pax_global_header00006660000000000000000000000064147002214350014510gustar00rootroot0000000000000052 comment=894ab95f971dea3bf1dc941f011a8c21b8664b06 libid3tag-0.16.3/000077500000000000000000000000001470022143500134415ustar00rootroot00000000000000libid3tag-0.16.3/.github/000077500000000000000000000000001470022143500150015ustar00rootroot00000000000000libid3tag-0.16.3/.github/workflows/000077500000000000000000000000001470022143500170365ustar00rootroot00000000000000libid3tag-0.16.3/.github/workflows/build.yml000066400000000000000000000037731470022143500206720ustar00rootroot00000000000000name: build on: push: pull_request: jobs: build: strategy: fail-fast: false matrix: include: - name: Ubuntu os: ubuntu-latest install_dir: ~/libid3tag cmake_extras: -DCMAKE_BUILD_TYPE=RelWithDebInfo - name: macOS os: macos-latest install_dir: ~/libid3tag cmake_extras: -DCMAKE_BUILD_TYPE=RelWithDebInfo - name: Windows os: windows-latest install_dir: C:\libid3tag cmake_config: --config RelWithDebInfo cmake_extras: >- -DCMAKE_TOOLCHAIN_FILE=C:\vcpkg\scripts\buildsystems\vcpkg.cmake vcpkg_tripet: x64-windows vcpkg_binary_cache: C:\Users\runneradmin\AppData\Local\vcpkg\archives name: ${{ matrix.name }} runs-on: ${{ matrix.os }} steps: - name: Check out Git repository uses: actions/checkout@v2 - name: Set up vcpkg cache uses: actions/cache@v2 if: runner.os == 'Windows' with: path: ${{ matrix.vcpkg_binary_cache }} key: vcpkg-${{ github.head_ref }}-${{ github.run_number }} restore-keys: | vcpkg-${{ github.head_ref }} vcpkg - name: Install dependencies if: startsWith(matrix.os, 'windows') run: vcpkg install zlib env: VCPKG_DEFAULT_TRIPLET: ${{ matrix.vcpkg_tripet }} - name: Configure run: >- cmake -D CMAKE_INSTALL_PREFIX=${{ matrix.install_dir }} -D VCPKG_TARGET_TRIPLET=${{ matrix.vcpkg_tripet }} ${{ matrix.cmake_extras }} -S . -B build - name: Build run: cmake --build build ${{ matrix.cmake_config }} env: CMAKE_BUILD_PARALLEL_LEVEL: 2 - name: Install run: cmake --install . ${{ matrix.cmake_config }} working-directory: build - name: Upload Build Artifact uses: actions/upload-artifact@v2 with: name: ${{ matrix.name }} libid3tag build path: ${{ matrix.install_dir }} libid3tag-0.16.3/.gitignore000066400000000000000000000000061470022143500154250ustar00rootroot00000000000000build libid3tag-0.16.3/CHANGES000066400000000000000000000062641470022143500144440ustar00rootroot00000000000000 libid3tag - ID3 tag manipulation library Copyright (C) 2000-2004 Underbit Technologies, Inc. $Id: CHANGES,v 1.11 2004/02/17 02:04:10 rob Exp $ =============================================================================== Version 0.16.3 * Fix backward compatibility with libid3tag 0.15.1b. Version 0.16.2 * Fix null pointer dereference in id3_ucs4_length (CVE-2017-11550) Version 0.16.1 * Fix exported CMake config file * Fix pkgconfig file name to match Linux distro packages (id3tag instead of libid3tag). Version 0.16.0 * Add CMake build system * Remove autotools * Apply patches from Debian, Fedora, Arch, and Gentoo Version 0.15.1 (beta) * Updated to autoconf 2.59, automake 1.8.2, libtool 1.5.2. * Fixed a potential problem in file.c when writing empty ID3v2 tags. * Added new id3_field_gettextencoding() API routine. Version 0.15.0 (beta) * Updated to autoconf 2.57, automake 1.7.5, libtool 1.4.3. * Added new id3_tag_version(), id3_tag_options(), id3_tag_setlength(), id3_frame_field(), id3_field_getlatin1(), id3_field_getfulllatin1(), id3_genre_index(), id3_genre_number(), id3_latin1_ucs4duplicate(), id3_utf16_ucs4duplicate(), and id3_utf8_ucs4duplicate() API routines. * Properly exposed the id3_frame_new(), id3_frame_delete(), and id3_field_type() API routines. * Fixed a possible segmentation fault rendering ID3v1 tags when a tag field exceeds the field length limit. * Fixed a problem whereby the file interface could try to seek and read data from a non-seekable stream, unrecoverably losing data from the stream. (N.B. the fix does not work under Win32.) * Fixed a problem reading ID3v2.2 frames which corrupted their frame IDs and caused them not to be re-rendered. * Improved rendering of the ID3v1 genre field from ID3v2 genre names/numbers. The genre "Other" is used in place of non-translatable genres. * Rendering an empty ID3v1 tag now properly returns 0 length even when a null buffer pointer is passed. * Changed the file implementation to maintain information about present but unparseable tags, instead of ignoring all tags and returning an error. * Added an external dependency on zlib (libz), which is no longer included. * Changed to build a shared library by default. * Changed to use native Cygwin build by default; give --host=mingw32 to `configure' to use MinGW (and avoid a dependency on the Cygwin DLL). Version 0.14.2 (beta) * Changed Cygwin builds to use MinGW; resulting Win32 executables no longer have a dependency on Cygwin DLLs. Version 0.14.1 (beta) * Updated config.guess and config.sub to latest upstream versions. * Enabled libtool versioning rather than release numbering. * Renamed `libid3' to `libid3tag' and enabled installation as a separate library. * Several other small fixes. Version 0.14.0 (beta) * Added a new ID3 tag manipulation library (libid3). The required zlib support is provided either by the host system or by the included static library implementation (libz). * Improved MSVC++ portability and added MSVC++ project files. =============================================================================== libid3tag-0.16.3/CMakeLists.txt000066400000000000000000000063051470022143500162050ustar00rootroot00000000000000cmake_minimum_required(VERSION 3.1.0) project(id3tag VERSION 0.16.3) option(BUILD_SHARED_LIBS "Build dynamic library" ON) # The new SOVERSION. This is 0.16.2 by default # The general policy is that minor versions of the library (e.g., 0.16.1, # 0.16.2) don't constitute an ABI breakage. Major versions (e.g., 0.17, 0.18) # do constitute an ABI breakage. set(LIBRARY_SOVERSION 0) include(GNUInstallDirs) # # Build # add_library(id3tag compat.c crc.c debug.c field.c file.c frame.c frametype.c genre.c latin1.c parse.c render.c tag.c ucs4.c utf16.c utf8.c util.c version.c ) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/id3tag.h.in ${CMAKE_CURRENT_BINARY_DIR}/id3tag.h @ONLY) target_include_directories(id3tag PUBLIC $ $ $ ) if(WIN32 AND BUILD_SHARED_LIBS) set_target_properties(id3tag PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON) endif() set_target_properties(id3tag PROPERTIES VERSION ${CMAKE_PROJECT_VERSION} SOVERSION ${LIBRARY_SOVERSION} ) include(CheckIncludeFile) check_include_file(sys/stat.h HAVE_SYS_STAT_H) if(HAVE_SYS_STAT_H) target_compile_definitions(id3tag PRIVATE HAVE_SYS_STAT_H) endif() check_include_file(unistd.h HAVE_UNISTD_H) if(HAVE_UNISTD_H) target_compile_definitions(id3tag PRIVATE HAVE_UNISTD_H) endif() check_include_file(assert.h HAVE_ASSERT_H) if(HAVE_ASSERT_H) target_compile_definitions(id3tag PRIVATE HAVE_ASSERT_H) endif() include(CheckFunctionExists) check_function_exists(ftruncate HAVE_FTRUNCATE) if(HAVE_FTRUNCATE) target_compile_definitions(id3tag PRIVATE HAVE_FTRUNCATE) endif() find_package(ZLIB REQUIRED) target_link_libraries(id3tag PUBLIC ZLIB::ZLIB) # # Installation # include(CMakePackageConfigHelpers) # Library files install(TARGETS id3tag EXPORT id3tagTargets ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" ) # Header files install( FILES "${CMAKE_CURRENT_BINARY_DIR}/id3tag.h" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" ) # pkgconfig configure_file(${CMAKE_CURRENT_SOURCE_DIR}/packaging/id3tag.pc.in ${CMAKE_CURRENT_BINARY_DIR}/packaging/id3tag.pc @ONLY) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/packaging/id3tag.pc DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") # CMake config set(ID3TAG_INSTALL_CMAKEDIR "${CMAKE_INSTALL_LIBDIR}/cmake/id3tag") install( EXPORT id3tagTargets FILE id3tagTargets.cmake NAMESPACE id3tag:: DESTINATION "${ID3TAG_INSTALL_CMAKEDIR}" ) configure_package_config_file(packaging/id3tagConfig.cmake.in "${CMAKE_CURRENT_BINARY_DIR}/packaging/id3tagConfig.cmake" INSTALL_DESTINATION "${ID3TAG_INSTALL_CMAKEDIR}" ) write_basic_package_version_file( "${CMAKE_CURRENT_BINARY_DIR}/packaging/id3tagConfigVersion.cmake" VERSION "${CMAKE_PROJECT_VERSION}" COMPATIBILITY SameMajorVersion ) install( FILES "${CMAKE_CURRENT_BINARY_DIR}/packaging/id3tagConfig.cmake" "${CMAKE_CURRENT_BINARY_DIR}/packaging/id3tagConfigVersion.cmake" DESTINATION "${ID3TAG_INSTALL_CMAKEDIR}" ) libid3tag-0.16.3/COPYING000066400000000000000000000431101470022143500144730ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 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. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, 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 software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, 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 redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's 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 give any other recipients of the Program a copy of this License along with the Program. 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 Program or any portion of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, 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 Program, 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 Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) 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; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, 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 executable. 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. If distribution of executable or 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 counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program 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. 5. 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 Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program 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. 7. 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 Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program 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 Program. 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. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program 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. 9. The Free Software Foundation may publish revised and/or new versions of the 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 Program 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 Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, 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 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "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 PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. 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 PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 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 Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. 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. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; 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. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. libid3tag-0.16.3/COPYRIGHT000066400000000000000000000016331470022143500147370ustar00rootroot00000000000000 libid3tag - ID3 tag manipulation library Copyright (C) 2000-2004 Underbit Technologies, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA If you would like to negotiate alternate licensing terms, you may do so by contacting: Underbit Technologies, Inc. libid3tag-0.16.3/CREDITS000066400000000000000000000013751470022143500144670ustar00rootroot00000000000000 libid3tag - ID3 tag manipulation library Copyright (C) 2000-2004 Underbit Technologies, Inc. $Id: CREDITS,v 1.2 2004/01/23 09:41:32 rob Exp $ =============================================================================== AUTHOR Except where otherwise noted, all code was authored by: Robert Leslie CONTRIBUTORS Significant contributions have been incorporated with thanks to: Mark Malson 2002/10/09: frame.c - Reported problem reading ID3v2.2 tag frames. Brett Paterson 2001/10/28: global.h - Reported missing et al. under MS Embedded Visual C. =============================================================================== libid3tag-0.16.3/README000066400000000000000000000023751470022143500143300ustar00rootroot00000000000000 libid3tag - ID3 tag manipulation library Copyright (C) 2000-2004 Underbit Technologies, Inc. $Id: README,v 1.5 2004/01/23 09:41:32 rob Exp $ =============================================================================== INTRODUCTION libid3tag is a library for reading and (eventually) writing ID3 tags, both ID3v1 and the various versions of ID3v2. See the file `id3tag.h' for the current library interface. =============================================================================== BUILDING AND INSTALLING libid3tag depends on zlib. It uses the CMake build system. To build it, run: cmake -DCMAKE_INSTALL_PREFIX=/where/you/want/to/install/to -S . -B build cmake --build build --parallel number-of-cpu-cores cmake --install build =============================================================================== COPYRIGHT Please read the `COPYRIGHT' file for copyright and warranty information. Also, the file `COPYING' contains the full text of the GNU GPL. Send inquiries, comments, bug reports, suggestions, patches, etc. to: https://codeberg.org/tenacityteam/libid3tag See also Tenacity's homepage on the Web: http://tenacityaudio.org =============================================================================== libid3tag-0.16.3/TODO000066400000000000000000000004261470022143500141330ustar00rootroot00000000000000 libid3tag - ID3 tag manipulation library Copyright (C) 2000-2004 Underbit Technologies, Inc. $Id: TODO,v 1.2 2004/01/23 09:41:32 rob Exp $ =============================================================================== libid3tag: - finish file API - fix API headers libid3tag-0.16.3/compat.c000066400000000000000000000374411470022143500151010ustar00rootroot00000000000000/* C code produced by gperf version 3.0.1 */ /* Command-line: gperf -tCcTonD -K id -N id3_compat_lookup -s -3 -k '*' compat.gperf */ #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) /* The character set is not based on ISO-646. */ error "gperf generated tables don't work with this execution character set. Please report a bug to ." #endif #line 1 "compat.gperf" /* * libid3tag - ID3 tag manipulation library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Id: compat.gperf,v 1.11 2004/01/23 09:41:32 rob Exp */ # include "global.h" # include # include # ifdef HAVE_ASSERT_H # include # endif # include "id3tag.h" # include "compat.h" # include "frame.h" # include "field.h" # include "parse.h" # include "ucs4.h" # define EQ(id) #id, 0 # define OBSOLETE 0, 0 # define TX(id) #id, translate_##id static id3_compat_func_t translate_TCON; #define TOTAL_KEYWORDS 73 #define MIN_WORD_LENGTH 3 #define MAX_WORD_LENGTH 4 #define MIN_HASH_VALUE 6 #define MAX_HASH_VALUE 127 /* maximum key range = 122, duplicates = 0 */ #ifdef __GNUC__ __inline #else #ifdef __cplusplus inline #endif #endif static unsigned int hash (str, len) register const char *str; register unsigned int len; { static const unsigned char asso_values[] = { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 64, 58, 20, 15, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 10, 18, 3, 6, 1, 47, 0, 128, 42, 62, 30, 31, 0, 19, 52, 10, 24, 8, 30, 5, 3, 30, 8, 25, 47, 3, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 }; register int hval = 0; switch (len) { default: hval += asso_values[(unsigned char)str[3]]; /*FALLTHROUGH*/ case 3: hval += asso_values[(unsigned char)str[2]]; /*FALLTHROUGH*/ case 2: hval += asso_values[(unsigned char)str[1]+1]; /*FALLTHROUGH*/ case 1: hval += asso_values[(unsigned char)str[0]]; break; } return hval; } #ifdef __GNUC__ __inline #endif const struct id3_compat * id3_compat_lookup (str, len) register const char *str; register size_t len; { static const struct id3_compat wordlist[] = { #line 97 "compat.gperf" {"TLE", EQ(TLEN) /* Length */}, #line 68 "compat.gperf" {"ETC", EQ(ETCO) /* Event timing codes */}, #line 126 "compat.gperf" {"ULT", EQ(USLT) /* Unsynchronised lyric/text transcription */}, #line 123 "compat.gperf" {"TYE", OBSOLETE /* Year [obsolete] */}, #line 92 "compat.gperf" {"TFT", EQ(TFLT) /* File type */}, #line 84 "compat.gperf" {"TCM", EQ(TCOM) /* Composer */}, #line 66 "compat.gperf" {"EQU", OBSOLETE /* Equalization [obsolete] */}, #line 63 "compat.gperf" {"COM", EQ(COMM) /* Comments */}, #line 130 "compat.gperf" {"WCM", EQ(WCOM) /* Commercial information */}, #line 96 "compat.gperf" {"TLA", EQ(TLAN) /* Language(s) */}, #line 88 "compat.gperf" {"TDA", OBSOLETE /* Date [obsolete] */}, #line 124 "compat.gperf" {"TYER", OBSOLETE /* Year [obsolete] */}, #line 83 "compat.gperf" {"TBP", EQ(TBPM) /* BPM (beats per minute) */}, #line 87 "compat.gperf" {"TCR", EQ(TCOP) /* Copyright message */}, #line 104 "compat.gperf" {"TOT", EQ(TOAL) /* Original album/movie/show title */}, #line 89 "compat.gperf" {"TDAT", OBSOLETE /* Date [obsolete] */}, #line 67 "compat.gperf" {"EQUA", OBSOLETE /* Equalization [obsolete] */}, #line 102 "compat.gperf" {"TOR", EQ(TDOR) /* Original release year [obsolete] */}, #line 131 "compat.gperf" {"WCP", EQ(WCOP) /* Copyright/legal information */}, #line 99 "compat.gperf" {"TOA", EQ(TOPE) /* Original artist(s)/performer(s) */}, #line 78 "compat.gperf" {"RVA", OBSOLETE /* Relative volume adjustment [obsolete] */}, #line 120 "compat.gperf" {"TT3", EQ(TIT3) /* Subtitle/description refinement */}, #line 98 "compat.gperf" {"TMT", EQ(TMED) /* Media type */}, #line 76 "compat.gperf" {"POP", EQ(POPM) /* Popularimeter */}, #line 74 "compat.gperf" {"MLL", EQ(MLLT) /* MPEG location lookup table */}, #line 79 "compat.gperf" {"RVAD", OBSOLETE /* Relative volume adjustment [obsolete] */}, #line 65 "compat.gperf" {"CRM", OBSOLETE /* Encrypted meta frame [obsolete] */}, #line 128 "compat.gperf" {"WAR", EQ(WOAR) /* Official artist/performer webpage */}, #line 80 "compat.gperf" {"SLT", EQ(SYLT) /* Synchronised lyric/text */}, #line 81 "compat.gperf" {"STC", EQ(SYTC) /* Synchronised tempo codes */}, #line 95 "compat.gperf" {"TKE", EQ(TKEY) /* Initial key */}, #line 111 "compat.gperf" {"TRC", EQ(TSRC) /* ISRC (international standard recording code) */}, #line 109 "compat.gperf" {"TPA", EQ(TPOS) /* Part of a set */}, #line 117 "compat.gperf" {"TSS", EQ(TSSE) /* Software/hardware and settings used for encoding */}, #line 112 "compat.gperf" {"TRD", OBSOLETE /* Recording dates [obsolete] */}, #line 64 "compat.gperf" {"CRA", EQ(AENC) /* Audio encryption */}, #line 108 "compat.gperf" {"TP4", EQ(TPE4) /* Interpreted, remixed, or otherwise modified by */}, #line 125 "compat.gperf" {"UFI", EQ(UFID) /* Unique file identifier */}, #line 101 "compat.gperf" {"TOL", EQ(TOLY) /* Original lyricist(s)/text writer(s) */}, #line 110 "compat.gperf" {"TPB", EQ(TPUB) /* Publisher */}, #line 73 "compat.gperf" {"MCI", EQ(MCDI) /* Music CD identifier */}, #line 107 "compat.gperf" {"TP3", EQ(TPE3) /* Conductor/performer refinement */}, #line 132 "compat.gperf" {"WPB", EQ(WPUB) /* Publishers official webpage */}, #line 113 "compat.gperf" {"TRDA", OBSOLETE /* Recording dates [obsolete] */}, #line 115 "compat.gperf" {"TSI", OBSOLETE /* Size [obsolete] */}, #line 90 "compat.gperf" {"TDY", EQ(TDLY) /* Playlist delay */}, #line 82 "compat.gperf" {"TAL", EQ(TALB) /* Album/movie/show title */}, #line 116 "compat.gperf" {"TSIZ", OBSOLETE /* Size [obsolete] */}, #line 129 "compat.gperf" {"WAS", EQ(WOAS) /* Official audio source webpage */}, #line 121 "compat.gperf" {"TXT", EQ(TEXT) /* Lyricist/text writer */}, #line 62 "compat.gperf" {"CNT", EQ(PCNT) /* Play counter */}, #line 100 "compat.gperf" {"TOF", EQ(TOFN) /* Original filename */}, #line 85 "compat.gperf" {"TCO", TX(TCON) /* Content type */}, #line 114 "compat.gperf" {"TRK", EQ(TRCK) /* Track number/position in set */}, #line 119 "compat.gperf" {"TT2", EQ(TIT2) /* Title/songname/content description */}, #line 93 "compat.gperf" {"TIM", OBSOLETE /* Time [obsolete] */}, #line 94 "compat.gperf" {"TIME", OBSOLETE /* Time [obsolete] */}, #line 103 "compat.gperf" {"TORY", EQ(TDOR) /* Original release year [obsolete] */}, #line 91 "compat.gperf" {"TEN", EQ(TENC) /* Encoded by */}, #line 118 "compat.gperf" {"TT1", EQ(TIT1) /* Content group description */}, #line 127 "compat.gperf" {"WAF", EQ(WOAF) /* Official audio file webpage */}, #line 75 "compat.gperf" {"PIC", EQ(APIC) /* Attached picture */}, #line 122 "compat.gperf" {"TXX", EQ(TXXX) /* User defined text information frame */}, #line 133 "compat.gperf" {"WXX", EQ(WXXX) /* User defined URL link frame */}, #line 86 "compat.gperf" {"TCON", TX(TCON) /* Content type */}, #line 77 "compat.gperf" {"REV", EQ(RVRB) /* Reverb */}, #line 106 "compat.gperf" {"TP2", EQ(TPE2) /* Band/orchestra/accompaniment */}, #line 105 "compat.gperf" {"TP1", EQ(TPE1) /* Lead performer(s)/soloist(s) */}, #line 61 "compat.gperf" {"BUF", EQ(RBUF) /* Recommended buffer size */}, #line 70 "compat.gperf" {"IPL", EQ(TIPL) /* Involved people list */}, #line 69 "compat.gperf" {"GEO", EQ(GEOB) /* General encapsulated object */}, #line 72 "compat.gperf" {"LNK", EQ(LINK) /* Linked information */}, #line 71 "compat.gperf" {"IPLS", EQ(TIPL) /* Involved people list */} }; static const short lookup[] = { -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, -1, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, -1, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, -1, -1, 50, -1, 51, 52, -1, 53, 54, 55, 56, -1, 57, 58, 59, 60, -1, 61, -1, 62, -1, -1, 63, -1, 64, -1, -1, 65, -1, 66, -1, -1, -1, -1, -1, 67, -1, 68, -1, 69, -1, 70, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 71, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 72 }; if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) { register int key = hash (str, len); if (key <= MAX_HASH_VALUE && key >= 0) { register int index = lookup[key]; if (index >= 0) { register const char *s = wordlist[index].id; if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0') return &wordlist[index]; } } } return 0; } #line 134 "compat.gperf" static int translate_TCON(struct id3_frame *frame, char const *oldid, id3_byte_t const *data, id3_length_t length) { id3_byte_t const *end; enum id3_field_textencoding encoding; id3_ucs4_t *string = 0, *ptr, *endptr; int result = 0; /* translate old TCON syntax into multiple strings */ assert(frame->nfields == 2); encoding = ID3_FIELD_TEXTENCODING_ISO_8859_1; end = data + length; if (id3_field_parse(&frame->fields[0], &data, end - data, &encoding) == -1) goto fail; string = id3_parse_string(&data, end - data, encoding, 0); if (string == 0) goto fail; ptr = string; while (*ptr == '(') { if (*++ptr == '(') break; endptr = ptr; while (*endptr && *endptr != ')') ++endptr; if (*endptr) *endptr++ = 0; if (id3_field_addstring(&frame->fields[1], ptr) == -1) goto fail; ptr = endptr; } if (*ptr && id3_field_addstring(&frame->fields[1], ptr) == -1) goto fail; if (0) { fail: result = -1; } if (string) free(string); return result; } /* * NAME: compat->fixup() * DESCRIPTION: finish compatibility translations */ int id3_compat_fixup(struct id3_tag *tag) { struct id3_frame *frame; unsigned int index; id3_ucs4_t timestamp[17] = { 0 }; int result = 0; /* create a TDRC frame from obsolete TYER/TDAT/TIME frames */ /* * TYE/TYER: YYYY * TDA/TDAT: DDMM * TIM/TIME: HHMM * * TDRC: yyyy-MM-ddTHH:mm */ index = 0; while ((frame = id3_tag_findframe(tag, ID3_FRAME_OBSOLETE, index++))) { char const *id; id3_byte_t const *data, *end; id3_length_t length; enum id3_field_textencoding encoding; id3_ucs4_t *string; id = id3_field_getframeid(&frame->fields[0]); assert(id); if (strcmp(id, "TYER") != 0 && strcmp(id, "YTYE") != 0 && strcmp(id, "TDAT") != 0 && strcmp(id, "YTDA") != 0 && strcmp(id, "TIME") != 0 && strcmp(id, "YTIM") != 0) continue; data = id3_field_getbinarydata(&frame->fields[1], &length); assert(data); if (length < 1) continue; end = data + length; encoding = id3_parse_uint(&data, 1); string = id3_parse_string(&data, end - data, encoding, 0); if (!string) continue; if (id3_ucs4_length(string) < 4) { free(string); continue; } if (strcmp(id, "TYER") == 0 || strcmp(id, "YTYE") == 0) { timestamp[0] = string[0]; timestamp[1] = string[1]; timestamp[2] = string[2]; timestamp[3] = string[3]; } else if (strcmp(id, "TDAT") == 0 || strcmp(id, "YTDA") == 0) { timestamp[4] = '-'; timestamp[5] = string[2]; timestamp[6] = string[3]; timestamp[7] = '-'; timestamp[8] = string[0]; timestamp[9] = string[1]; } else { /* TIME or YTIM */ timestamp[10] = 'T'; timestamp[11] = string[0]; timestamp[12] = string[1]; timestamp[13] = ':'; timestamp[14] = string[2]; timestamp[15] = string[3]; } free(string); } if (timestamp[0]) { id3_ucs4_t *strings; frame = id3_frame_new("TDRC"); if (frame == 0) goto fail; strings = timestamp; if (id3_field_settextencoding(&frame->fields[0], ID3_FIELD_TEXTENCODING_ISO_8859_1) == -1 || id3_field_setstrings(&frame->fields[1], 1, &strings) == -1 || id3_tag_attachframe(tag, frame) == -1) { id3_frame_delete(frame); goto fail; } } if (0) { fail: result = -1; } return result; } libid3tag-0.16.3/compat.gperf000066400000000000000000000204371470022143500157570ustar00rootroot00000000000000%{ /* * libid3tag - ID3 tag manipulation library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: compat.gperf,v 1.11 2004/01/23 09:41:32 rob Exp $ */ # include "global.h" # include # include # ifdef HAVE_ASSERT_H # include # endif # include "id3tag.h" # include "compat.h" # include "frame.h" # include "field.h" # include "parse.h" # include "ucs4.h" # define EQ(id) #id, 0 # define OBSOLETE 0, 0 # define TX(id) #id, translate_##id static id3_compat_func_t translate_TCON; %} struct id3_compat; %% # # ID3v2.2 and ID3v2.3 frames # # Only obsolete frames or frames with an equivalent ID3v2.4 frame ID are # listed here. If a frame ID is not listed, it is assumed that the same # frame ID is itself the equivalent ID3v2.4 frame ID. # # This list may also include frames with new content interpretations; the # translation function will rewrite the contents to comply with ID3v2.4. # BUF, EQ(RBUF) /* Recommended buffer size */ CNT, EQ(PCNT) /* Play counter */ COM, EQ(COMM) /* Comments */ CRA, EQ(AENC) /* Audio encryption */ CRM, OBSOLETE /* Encrypted meta frame [obsolete] */ EQU, OBSOLETE /* Equalization [obsolete] */ EQUA, OBSOLETE /* Equalization [obsolete] */ ETC, EQ(ETCO) /* Event timing codes */ GEO, EQ(GEOB) /* General encapsulated object */ IPL, EQ(TIPL) /* Involved people list */ IPLS, EQ(TIPL) /* Involved people list */ LNK, EQ(LINK) /* Linked information */ MCI, EQ(MCDI) /* Music CD identifier */ MLL, EQ(MLLT) /* MPEG location lookup table */ PIC, EQ(APIC) /* Attached picture */ POP, EQ(POPM) /* Popularimeter */ REV, EQ(RVRB) /* Reverb */ RVA, OBSOLETE /* Relative volume adjustment [obsolete] */ RVAD, OBSOLETE /* Relative volume adjustment [obsolete] */ SLT, EQ(SYLT) /* Synchronised lyric/text */ STC, EQ(SYTC) /* Synchronised tempo codes */ TAL, EQ(TALB) /* Album/movie/show title */ TBP, EQ(TBPM) /* BPM (beats per minute) */ TCM, EQ(TCOM) /* Composer */ TCO, TX(TCON) /* Content type */ TCON, TX(TCON) /* Content type */ TCR, EQ(TCOP) /* Copyright message */ TDA, OBSOLETE /* Date [obsolete] */ TDAT, OBSOLETE /* Date [obsolete] */ TDY, EQ(TDLY) /* Playlist delay */ TEN, EQ(TENC) /* Encoded by */ TFT, EQ(TFLT) /* File type */ TIM, OBSOLETE /* Time [obsolete] */ TIME, OBSOLETE /* Time [obsolete] */ TKE, EQ(TKEY) /* Initial key */ TLA, EQ(TLAN) /* Language(s) */ TLE, EQ(TLEN) /* Length */ TMT, EQ(TMED) /* Media type */ TOA, EQ(TOPE) /* Original artist(s)/performer(s) */ TOF, EQ(TOFN) /* Original filename */ TOL, EQ(TOLY) /* Original lyricist(s)/text writer(s) */ TOR, EQ(TDOR) /* Original release year [obsolete] */ TORY, EQ(TDOR) /* Original release year [obsolete] */ TOT, EQ(TOAL) /* Original album/movie/show title */ TP1, EQ(TPE1) /* Lead performer(s)/soloist(s) */ TP2, EQ(TPE2) /* Band/orchestra/accompaniment */ TP3, EQ(TPE3) /* Conductor/performer refinement */ TP4, EQ(TPE4) /* Interpreted, remixed, or otherwise modified by */ TPA, EQ(TPOS) /* Part of a set */ TPB, EQ(TPUB) /* Publisher */ TRC, EQ(TSRC) /* ISRC (international standard recording code) */ TRD, OBSOLETE /* Recording dates [obsolete] */ TRDA, OBSOLETE /* Recording dates [obsolete] */ TRK, EQ(TRCK) /* Track number/position in set */ TSI, OBSOLETE /* Size [obsolete] */ TSIZ, OBSOLETE /* Size [obsolete] */ TSS, EQ(TSSE) /* Software/hardware and settings used for encoding */ TT1, EQ(TIT1) /* Content group description */ TT2, EQ(TIT2) /* Title/songname/content description */ TT3, EQ(TIT3) /* Subtitle/description refinement */ TXT, EQ(TEXT) /* Lyricist/text writer */ TXX, EQ(TXXX) /* User defined text information frame */ TYE, OBSOLETE /* Year [obsolete] */ TYER, OBSOLETE /* Year [obsolete] */ UFI, EQ(UFID) /* Unique file identifier */ ULT, EQ(USLT) /* Unsynchronised lyric/text transcription */ WAF, EQ(WOAF) /* Official audio file webpage */ WAR, EQ(WOAR) /* Official artist/performer webpage */ WAS, EQ(WOAS) /* Official audio source webpage */ WCM, EQ(WCOM) /* Commercial information */ WCP, EQ(WCOP) /* Copyright/legal information */ WPB, EQ(WPUB) /* Publishers official webpage */ WXX, EQ(WXXX) /* User defined URL link frame */ %% static int translate_TCON(struct id3_frame *frame, char const *oldid, id3_byte_t const *data, id3_length_t length) { id3_byte_t const *end; enum id3_field_textencoding encoding; id3_ucs4_t *string = 0, *ptr, *endptr; int result = 0; /* translate old TCON syntax into multiple strings */ assert(frame->nfields == 2); encoding = ID3_FIELD_TEXTENCODING_ISO_8859_1; end = data + length; if (id3_field_parse(&frame->fields[0], &data, end - data, &encoding) == -1) goto fail; string = id3_parse_string(&data, end - data, encoding, 0); if (string == 0) goto fail; ptr = string; while (*ptr == '(') { if (*++ptr == '(') break; endptr = ptr; while (*endptr && *endptr != ')') ++endptr; if (*endptr) *endptr++ = 0; if (id3_field_addstring(&frame->fields[1], ptr) == -1) goto fail; ptr = endptr; } if (*ptr && id3_field_addstring(&frame->fields[1], ptr) == -1) goto fail; if (0) { fail: result = -1; } if (string) free(string); return result; } /* * NAME: compat->fixup() * DESCRIPTION: finish compatibility translations */ int id3_compat_fixup(struct id3_tag *tag) { struct id3_frame *frame; unsigned int index; id3_ucs4_t timestamp[17] = { 0 }; int result = 0; /* create a TDRC frame from obsolete TYER/TDAT/TIME frames */ /* * TYE/TYER: YYYY * TDA/TDAT: DDMM * TIM/TIME: HHMM * * TDRC: yyyy-MM-ddTHH:mm */ index = 0; while ((frame = id3_tag_findframe(tag, ID3_FRAME_OBSOLETE, index++))) { char const *id; id3_byte_t const *data, *end; id3_length_t length; enum id3_field_textencoding encoding; id3_ucs4_t *string; id = id3_field_getframeid(&frame->fields[0]); assert(id); if (strcmp(id, "TYER") != 0 && strcmp(id, "YTYE") != 0 && strcmp(id, "TDAT") != 0 && strcmp(id, "YTDA") != 0 && strcmp(id, "TIME") != 0 && strcmp(id, "YTIM") != 0) continue; data = id3_field_getbinarydata(&frame->fields[1], &length); assert(data); if (length < 1) continue; end = data + length; encoding = id3_parse_uint(&data, 1); string = id3_parse_string(&data, end - data, encoding, 0); if (!string) { continue; } if (id3_ucs4_length(string) < 4) { free(string); continue; } if (strcmp(id, "TYER") == 0 || strcmp(id, "YTYE") == 0) { timestamp[0] = string[0]; timestamp[1] = string[1]; timestamp[2] = string[2]; timestamp[3] = string[3]; } else if (strcmp(id, "TDAT") == 0 || strcmp(id, "YTDA") == 0) { timestamp[4] = '-'; timestamp[5] = string[2]; timestamp[6] = string[3]; timestamp[7] = '-'; timestamp[8] = string[0]; timestamp[9] = string[1]; } else { /* TIME or YTIM */ timestamp[10] = 'T'; timestamp[11] = string[0]; timestamp[12] = string[1]; timestamp[13] = ':'; timestamp[14] = string[2]; timestamp[15] = string[3]; } free(string); } if (timestamp[0]) { id3_ucs4_t *strings; frame = id3_frame_new("TDRC"); if (frame == 0) goto fail; strings = timestamp; if (id3_field_settextencoding(&frame->fields[0], ID3_FIELD_TEXTENCODING_ISO_8859_1) == -1 || id3_field_setstrings(&frame->fields[1], 1, &strings) == -1 || id3_tag_attachframe(tag, frame) == -1) { id3_frame_delete(frame); goto fail; } } if (0) { fail: result = -1; } return result; } libid3tag-0.16.3/compat.h000066400000000000000000000024301470022143500150740ustar00rootroot00000000000000/* * libid3tag - ID3 tag manipulation library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: compat.h,v 1.8 2004/01/23 09:41:32 rob Exp $ */ # ifndef LIBID3TAG_COMPAT_H # define LIBID3TAG_COMPAT_H # include "id3tag.h" typedef int id3_compat_func_t(struct id3_frame *, char const *, id3_byte_t const *, id3_length_t); struct id3_compat { char const *id; char const *equiv; id3_compat_func_t *translate; }; struct id3_compat const *id3_compat_lookup(register char const *, register size_t); int id3_compat_fixup(struct id3_tag *); # endif libid3tag-0.16.3/crc.c000066400000000000000000000130631470022143500143570ustar00rootroot00000000000000/* * libid3tag - ID3 tag manipulation library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: crc.c,v 1.11 2004/02/17 02:04:10 rob Exp $ */ # include "global.h" # include "id3tag.h" # include "crc.h" static unsigned long const crc_table[256] = { 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, 0x2d02ef8dL }; /* * NAME: crc->compute() * DESCRIPTION: calculate CRC-32 value (ISO 3309) */ unsigned long id3_crc_compute(id3_byte_t const *data, id3_length_t length) { register unsigned long crc; for (crc = 0xffffffffL; length >= 8; length -= 8) { crc = crc_table[(crc ^ *data++) & 0xff] ^ (crc >> 8); crc = crc_table[(crc ^ *data++) & 0xff] ^ (crc >> 8); crc = crc_table[(crc ^ *data++) & 0xff] ^ (crc >> 8); crc = crc_table[(crc ^ *data++) & 0xff] ^ (crc >> 8); crc = crc_table[(crc ^ *data++) & 0xff] ^ (crc >> 8); crc = crc_table[(crc ^ *data++) & 0xff] ^ (crc >> 8); crc = crc_table[(crc ^ *data++) & 0xff] ^ (crc >> 8); crc = crc_table[(crc ^ *data++) & 0xff] ^ (crc >> 8); } switch (length) { case 7: crc = crc_table[(crc ^ *data++) & 0xff] ^ (crc >> 8); case 6: crc = crc_table[(crc ^ *data++) & 0xff] ^ (crc >> 8); case 5: crc = crc_table[(crc ^ *data++) & 0xff] ^ (crc >> 8); case 4: crc = crc_table[(crc ^ *data++) & 0xff] ^ (crc >> 8); case 3: crc = crc_table[(crc ^ *data++) & 0xff] ^ (crc >> 8); case 2: crc = crc_table[(crc ^ *data++) & 0xff] ^ (crc >> 8); case 1: crc = crc_table[(crc ^ *data++) & 0xff] ^ (crc >> 8); case 0: break; } return crc ^ 0xffffffffL; } libid3tag-0.16.3/crc.h000066400000000000000000000017771470022143500143750ustar00rootroot00000000000000/* * libid3tag - ID3 tag manipulation library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: crc.h,v 1.8 2004/02/17 02:04:10 rob Exp $ */ # ifndef LIBID3TAG_CRC_H # define LIBID3TAG_CRC_H # include "id3tag.h" unsigned long id3_crc_compute(id3_byte_t const *, id3_length_t); # endif libid3tag-0.16.3/debug.c000066400000000000000000000104641470022143500147000ustar00rootroot00000000000000/* * libid3tag - ID3 tag manipulation library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: debug.c,v 1.8 2004/01/23 09:41:32 rob Exp $ */ # include "global.h" # undef malloc # undef calloc # undef realloc # undef free # include # include # include # include "debug.h" # if defined(DEBUG) # define DEBUG_MAGIC 0xdeadbeefL struct debug { char const *file; unsigned int line; size_t size; struct debug *next; struct debug *prev; long int magic; }; static struct debug *allocated; static int registered; static void check(void) { struct debug *debug; for (debug = allocated; debug; debug = debug->next) { if (debug->magic != DEBUG_MAGIC) { fprintf(stderr, "memory corruption\n"); break; } fprintf(stderr, "%s:%u: leaked %lu bytes\n", debug->file, debug->line, debug->size); } } void *id3_debug_malloc(size_t size, char const *file, unsigned int line) { struct debug *debug; if (!registered) { atexit(check); registered = 1; } if (size == 0) fprintf(stderr, "%s:%u: malloc(0)\n", file, line); debug = malloc(sizeof(*debug) + size); if (debug == 0) { fprintf(stderr, "%s:%u: malloc(%lu) failed\n", file, line, size); return 0; } debug->magic = DEBUG_MAGIC; debug->file = file; debug->line = line; debug->size = size; debug->next = allocated; debug->prev = 0; if (allocated) allocated->prev = debug; allocated = debug; return ++debug; } void *id3_debug_calloc(size_t nmemb, size_t size, char const *file, unsigned int line) { void *ptr; ptr = id3_debug_malloc(nmemb * size, file, line); if (ptr) memset(ptr, 0, nmemb * size); return ptr; } void *id3_debug_realloc(void *ptr, size_t size, char const *file, unsigned int line) { struct debug *debug, *new; if (size == 0) { id3_debug_free(ptr, file, line); return 0; } if (ptr == 0) return id3_debug_malloc(size, file, line); debug = ptr; --debug; if (debug->magic != DEBUG_MAGIC) { fprintf(stderr, "%s:%u: realloc(%p, %lu) memory not allocated\n", file, line, ptr, size); return 0; } new = realloc(debug, sizeof(*debug) + size); if (new == 0) { fprintf(stderr, "%s:%u: realloc(%p, %lu) failed\n", file, line, ptr, size); return 0; } if (allocated == debug) allocated = new; debug = new; debug->file = file; debug->line = line; debug->size = size; if (debug->next) debug->next->prev = debug; if (debug->prev) debug->prev->next = debug; return ++debug; } void id3_debug_free(void *ptr, char const *file, unsigned int line) { struct debug *debug; if (ptr == 0) { fprintf(stderr, "%s:%u: free(0)\n", file, line); return; } debug = ptr; --debug; if (debug->magic != DEBUG_MAGIC) { fprintf(stderr, "%s:%u: free(%p) memory not allocated\n", file, line, ptr); return; } debug->magic = 0; if (debug->next) debug->next->prev = debug->prev; if (debug->prev) debug->prev->next = debug->next; if (allocated == debug) allocated = debug->next; free(debug); } void *id3_debug_release(void *ptr, char const *file, unsigned int line) { struct debug *debug; if (ptr == 0) return 0; debug = ptr; --debug; if (debug->magic != DEBUG_MAGIC) { fprintf(stderr, "%s:%u: release(%p) memory not allocated\n", file, line, ptr); return ptr; } if (debug->next) debug->next->prev = debug->prev; if (debug->prev) debug->prev->next = debug->next; if (allocated == debug) allocated = debug->next; memmove(debug, debug + 1, debug->size); return debug; } # endif libid3tag-0.16.3/debug.h000066400000000000000000000024001470022143500146740ustar00rootroot00000000000000/* * libid3tag - ID3 tag manipulation library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: debug.h,v 1.8 2004/01/23 09:41:32 rob Exp $ */ # ifndef LIBID3TAG_DEBUG_H # define LIBID3TAG_DEBUG_H # include void *id3_debug_malloc(size_t, char const *, unsigned int); void *id3_debug_calloc(size_t, size_t, char const *, unsigned int); void *id3_debug_realloc(void *, size_t, char const *, unsigned int); void id3_debug_free(void *, char const *, unsigned int); void *id3_debug_release(void *, char const *, unsigned int); # endif libid3tag-0.16.3/field.c000066400000000000000000000443661470022143500147050ustar00rootroot00000000000000/* * libid3tag - ID3 tag manipulation library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: field.c,v 1.16 2004/01/23 09:41:32 rob Exp $ */ # include "global.h" # include # include # ifdef HAVE_ASSERT_H # include # endif # include "id3tag.h" # include "field.h" # include "frame.h" # include "render.h" # include "ucs4.h" # include "latin1.h" # include "parse.h" /* * NAME: field->init() * DESCRIPTION: initialize a field to a default value for the given type */ void id3_field_init(union id3_field *field, enum id3_field_type type) { assert(field); switch (field->type = type) { case ID3_FIELD_TYPE_TEXTENCODING: case ID3_FIELD_TYPE_INT8: case ID3_FIELD_TYPE_INT16: case ID3_FIELD_TYPE_INT24: case ID3_FIELD_TYPE_INT32: field->number.value = 0; break; case ID3_FIELD_TYPE_LATIN1: case ID3_FIELD_TYPE_LATIN1FULL: field->latin1.ptr = 0; break; case ID3_FIELD_TYPE_LATIN1LIST: field->latin1list.nstrings = 0; field->latin1list.strings = 0; case ID3_FIELD_TYPE_STRING: case ID3_FIELD_TYPE_STRINGFULL: field->string.ptr = 0; break; case ID3_FIELD_TYPE_STRINGLIST: field->stringlist.nstrings = 0; field->stringlist.strings = 0; break; case ID3_FIELD_TYPE_LANGUAGE: strcpy(field->immediate.value, "XXX"); break; case ID3_FIELD_TYPE_FRAMEID: strcpy(field->immediate.value, "XXXX"); break; case ID3_FIELD_TYPE_DATE: memset(field->immediate.value, 0, sizeof(field->immediate.value)); break; case ID3_FIELD_TYPE_INT32PLUS: case ID3_FIELD_TYPE_BINARYDATA: field->binary.data = 0; field->binary.length = 0; break; } } /* * NAME: field->finish() * DESCRIPTION: reset a field, deallocating memory if necessary */ void id3_field_finish(union id3_field *field) { unsigned int i; assert(field); switch (field->type) { case ID3_FIELD_TYPE_TEXTENCODING: case ID3_FIELD_TYPE_INT8: case ID3_FIELD_TYPE_INT16: case ID3_FIELD_TYPE_INT24: case ID3_FIELD_TYPE_INT32: case ID3_FIELD_TYPE_LANGUAGE: case ID3_FIELD_TYPE_FRAMEID: case ID3_FIELD_TYPE_DATE: break; case ID3_FIELD_TYPE_LATIN1: case ID3_FIELD_TYPE_LATIN1FULL: if (field->latin1.ptr) free(field->latin1.ptr); break; case ID3_FIELD_TYPE_LATIN1LIST: for (i = 0; i < field->latin1list.nstrings; ++i) free(field->latin1list.strings[i]); if (field->latin1list.strings) free(field->latin1list.strings); break; case ID3_FIELD_TYPE_STRING: case ID3_FIELD_TYPE_STRINGFULL: if (field->string.ptr) free(field->string.ptr); break; case ID3_FIELD_TYPE_STRINGLIST: for (i = 0; i < field->stringlist.nstrings; ++i) free(field->stringlist.strings[i]); if (field->stringlist.strings) free(field->stringlist.strings); break; case ID3_FIELD_TYPE_INT32PLUS: case ID3_FIELD_TYPE_BINARYDATA: if (field->binary.data) free(field->binary.data); break; } id3_field_init(field, field->type); } /* * NAME: field->type() * DESCRIPTION: return the value type of a field */ enum id3_field_type id3_field_type(union id3_field const *field) { assert(field); return field->type; } /* * NAME: field->parse() * DESCRIPTION: parse a field value */ int id3_field_parse(union id3_field *field, id3_byte_t const **ptr, id3_length_t length, enum id3_field_textencoding *encoding) { assert(field); id3_field_finish(field); switch (field->type) { case ID3_FIELD_TYPE_INT32: if (length < 4) goto fail; field->number.value = id3_parse_uint(ptr, 4); break; case ID3_FIELD_TYPE_INT24: if (length < 3) goto fail; field->number.value = id3_parse_uint(ptr, 3); break; case ID3_FIELD_TYPE_INT16: if (length < 2) goto fail; field->number.value = id3_parse_uint(ptr, 2); break; case ID3_FIELD_TYPE_INT8: case ID3_FIELD_TYPE_TEXTENCODING: if (length < 1) goto fail; field->number.value = id3_parse_uint(ptr, 1); if (field->type == ID3_FIELD_TYPE_TEXTENCODING) *encoding = field->number.value; break; case ID3_FIELD_TYPE_LANGUAGE: if (length < 3) goto fail; id3_parse_immediate(ptr, 3, field->immediate.value); break; case ID3_FIELD_TYPE_FRAMEID: if (length < 4) goto fail; id3_parse_immediate(ptr, 4, field->immediate.value); break; case ID3_FIELD_TYPE_DATE: if (length < 8) goto fail; id3_parse_immediate(ptr, 8, field->immediate.value); break; case ID3_FIELD_TYPE_LATIN1: case ID3_FIELD_TYPE_LATIN1FULL: { id3_latin1_t *latin1; latin1 = id3_parse_latin1(ptr, length, field->type == ID3_FIELD_TYPE_LATIN1FULL); if (latin1 == 0) goto fail; field->latin1.ptr = latin1; } break; case ID3_FIELD_TYPE_LATIN1LIST: { id3_byte_t const *end; id3_latin1_t *latin1, **strings; end = *ptr + length; while (end - *ptr > 0) { latin1 = id3_parse_latin1(ptr, end - *ptr, 0); if (latin1 == 0) goto fail; strings = realloc(field->latin1list.strings, (field->latin1list.nstrings + 1) * sizeof(*strings)); if (strings == 0) { free(latin1); goto fail; } field->latin1list.strings = strings; field->latin1list.strings[field->latin1list.nstrings++] = latin1; } } break; case ID3_FIELD_TYPE_STRING: case ID3_FIELD_TYPE_STRINGFULL: { id3_ucs4_t *ucs4; ucs4 = id3_parse_string(ptr, length, *encoding, field->type == ID3_FIELD_TYPE_STRINGFULL); if (ucs4 == 0) goto fail; field->string.ptr = ucs4; } break; case ID3_FIELD_TYPE_STRINGLIST: { id3_byte_t const *end; id3_ucs4_t *ucs4, **strings; end = *ptr + length; while (end - *ptr > 0 && **ptr != '\0') { ucs4 = id3_parse_string(ptr, end - *ptr, *encoding, 0); if (ucs4 == 0) goto fail; strings = realloc(field->stringlist.strings, (field->stringlist.nstrings + 1) * sizeof(*strings)); if (strings == 0) { free(ucs4); goto fail; } field->stringlist.strings = strings; field->stringlist.strings[field->stringlist.nstrings++] = ucs4; } } break; case ID3_FIELD_TYPE_INT32PLUS: case ID3_FIELD_TYPE_BINARYDATA: { id3_byte_t *data; data = id3_parse_binary(ptr, length); if (data == 0) goto fail; field->binary.data = data; field->binary.length = length; } break; } return 0; fail: return -1; } /* * NAME: field->render() * DESCRIPTION: render a field value */ id3_length_t id3_field_render(union id3_field const *field, id3_byte_t **ptr, enum id3_field_textencoding *encoding, int terminate) { id3_length_t size; unsigned int i; assert(field && encoding); switch (field->type) { case ID3_FIELD_TYPE_INT32: return id3_render_int(ptr, field->number.value, 4); case ID3_FIELD_TYPE_INT24: return id3_render_int(ptr, field->number.value, 3); case ID3_FIELD_TYPE_INT16: return id3_render_int(ptr, field->number.value, 2); case ID3_FIELD_TYPE_TEXTENCODING: *encoding = field->number.value; case ID3_FIELD_TYPE_INT8: return id3_render_int(ptr, field->number.value, 1); case ID3_FIELD_TYPE_LATIN1: case ID3_FIELD_TYPE_LATIN1FULL: return id3_render_latin1(ptr, field->latin1.ptr, terminate); case ID3_FIELD_TYPE_LATIN1LIST: size = 0; for (i = 0; i < field->latin1list.nstrings; ++i) { size += id3_render_latin1(ptr, field->latin1list.strings[i], (i < field->latin1list.nstrings - 1) || terminate); } return size; case ID3_FIELD_TYPE_STRING: case ID3_FIELD_TYPE_STRINGFULL: return id3_render_string(ptr, field->string.ptr, *encoding, terminate); case ID3_FIELD_TYPE_STRINGLIST: size = 0; for (i = 0; i < field->stringlist.nstrings; ++i) { size += id3_render_string(ptr, field->stringlist.strings[i], *encoding, (i < field->stringlist.nstrings - 1) || terminate); } return size; case ID3_FIELD_TYPE_LANGUAGE: return id3_render_immediate(ptr, field->immediate.value, 3); case ID3_FIELD_TYPE_FRAMEID: return id3_render_immediate(ptr, field->immediate.value, 4); case ID3_FIELD_TYPE_DATE: return id3_render_immediate(ptr, field->immediate.value, 8); case ID3_FIELD_TYPE_INT32PLUS: case ID3_FIELD_TYPE_BINARYDATA: return id3_render_binary(ptr, field->binary.data, field->binary.length); } return 0; } /* * NAME: field->setint() * DESCRIPTION: set the value of an int field */ int id3_field_setint(union id3_field *field, signed long number) { assert(field); switch (field->type) { case ID3_FIELD_TYPE_INT8: if (number > 0x7f || number < -0x80) return -1; break; case ID3_FIELD_TYPE_INT16: if (number > 0x7fff || number < -0x8000) return -1; break; case ID3_FIELD_TYPE_INT24: if (number > 0x7fffffL || number < -0x800000L) return -1; break; case ID3_FIELD_TYPE_INT32: if (number > 0x7fffffffL || number < -0x80000000L) return -1; break; default: return -1; } id3_field_finish(field); field->number.value = number; return 0; } /* * NAME: field->settextencoding() * DESCRIPTION: set the value of a textencoding field */ int id3_field_settextencoding(union id3_field *field, enum id3_field_textencoding encoding) { assert(field); if (field->type != ID3_FIELD_TYPE_TEXTENCODING) return -1; id3_field_finish(field); field->number.value = encoding; return 0; } static int set_latin1(union id3_field *field, id3_latin1_t const *latin1) { id3_latin1_t *data; if (latin1 == 0 || *latin1 == 0) data = 0; else { data = id3_latin1_duplicate(latin1); if (data == 0) return -1; } field->latin1.ptr = data; return 0; } /* * NAME: field->setlatin1() * DESCRIPTION: set the value of a latin1 field */ int id3_field_setlatin1(union id3_field *field, id3_latin1_t const *latin1) { assert(field); if (field->type != ID3_FIELD_TYPE_LATIN1) return -1; id3_field_finish(field); if (latin1) { id3_latin1_t const *ptr; for (ptr = latin1; *ptr; ++ptr) { if (*ptr == '\n') return -1; } } return set_latin1(field, latin1); } /* * NAME: field->setfulllatin1() * DESCRIPTION: set the value of a full latin1 field */ int id3_field_setfulllatin1(union id3_field *field, id3_latin1_t const *latin1) { assert(field); if (field->type != ID3_FIELD_TYPE_LATIN1FULL) return -1; id3_field_finish(field); return set_latin1(field, latin1); } static int set_string(union id3_field *field, id3_ucs4_t const *string) { id3_ucs4_t *data; if (string == 0 || *string == 0) data = 0; else { data = id3_ucs4_duplicate(string); if (data == 0) return -1; } field->string.ptr = data; return 0; } /* * NAME: field->setstring() * DESCRIPTION: set the value of a string field */ int id3_field_setstring(union id3_field *field, id3_ucs4_t const *string) { assert(field); if (field->type != ID3_FIELD_TYPE_STRING) return -1; id3_field_finish(field); if (string) { id3_ucs4_t const *ptr; for (ptr = string; *ptr; ++ptr) { if (*ptr == '\n') return -1; } } return set_string(field, string); } /* * NAME: field->setfullstring() * DESCRIPTION: set the value of a full string field */ int id3_field_setfullstring(union id3_field *field, id3_ucs4_t const *string) { assert(field); if (field->type != ID3_FIELD_TYPE_STRINGFULL) return -1; id3_field_finish(field); return set_string(field, string); } /* * NAME: field->setstrings() * DESCRIPTION: set the value of a stringlist field */ int id3_field_setstrings(union id3_field *field, unsigned int length, id3_ucs4_t **ptrs) { id3_ucs4_t **strings; unsigned int i; assert(field); if (field->type != ID3_FIELD_TYPE_STRINGLIST) return -1; id3_field_finish(field); if (length == 0) return 0; strings = malloc(length * sizeof(*strings)); if (strings == 0) return -1; for (i = 0; i < length; ++i) { strings[i] = id3_ucs4_duplicate(ptrs[i]); if (strings[i] == 0) { while (i--) free(strings[i]); free(strings); return -1; } } field->stringlist.strings = strings; field->stringlist.nstrings = length; return 0; } /* * NAME: field->addstring() * DESCRIPTION: add a string to a stringlist field */ int id3_field_addstring(union id3_field *field, id3_ucs4_t const *string) { id3_ucs4_t *new, **strings; assert(field); if (field->type != ID3_FIELD_TYPE_STRINGLIST) return -1; if (string == 0) string = id3_ucs4_empty; new = id3_ucs4_duplicate(string); if (new == 0) return -1; strings = realloc(field->stringlist.strings, (field->stringlist.nstrings + 1) * sizeof(*strings)); if (strings == 0) { free(new); return -1; } field->stringlist.strings = strings; field->stringlist.strings[field->stringlist.nstrings++] = new; return 0; } /* * NAME: field->setlanguage() * DESCRIPTION: set the value of a language field */ int id3_field_setlanguage(union id3_field *field, char const *language) { assert(field); if (field->type != ID3_FIELD_TYPE_LANGUAGE) return -1; id3_field_finish(field); if (language) { if (strlen(language) != 3) return -1; strcpy(field->immediate.value, language); } return 0; } /* * NAME: field->setframeid() * DESCRIPTION: set the value of a frameid field */ int id3_field_setframeid(union id3_field *field, char const *id) { assert(field); if (field->type != ID3_FIELD_TYPE_FRAMEID || !id3_frame_validid(id)) return -1; id3_field_finish(field); field->immediate.value[0] = id[0]; field->immediate.value[1] = id[1]; field->immediate.value[2] = id[2]; field->immediate.value[3] = id[3]; field->immediate.value[4] = 0; return 0; } /* * NAME: field->setbinarydata() * DESCRIPTION: set the value of a binarydata field */ int id3_field_setbinarydata(union id3_field *field, id3_byte_t const *data, id3_length_t length) { id3_byte_t *mem; assert(field); if (field->type != ID3_FIELD_TYPE_BINARYDATA) return -1; id3_field_finish(field); if (length == 0) mem = 0; else { mem = malloc(length); if (mem == 0) return -1; assert(data); memcpy(mem, data, length); } field->binary.data = mem; field->binary.length = length; return 0; } /* * NAME: field->getint() * DESCRIPTION: return the value of an integer field */ signed long id3_field_getint(union id3_field const *field) { assert(field); if (field->type != ID3_FIELD_TYPE_INT8 && field->type != ID3_FIELD_TYPE_INT16 && field->type != ID3_FIELD_TYPE_INT24 && field->type != ID3_FIELD_TYPE_INT32) return -1; return field->number.value; } /* * NAME: field->gettextencoding() * DESCRIPTION: return the value of a text encoding field */ enum id3_field_textencoding id3_field_gettextencoding(union id3_field const *field) { assert(field); if (field->type != ID3_FIELD_TYPE_TEXTENCODING) return -1; return field->number.value; } /* * NAME: field->getlatin1() * DESCRIPTION: return the value of a latin1 field */ id3_latin1_t const *id3_field_getlatin1(union id3_field const *field) { assert(field); if (field->type != ID3_FIELD_TYPE_LATIN1) return 0; return field->latin1.ptr ? field->latin1.ptr : (id3_latin1_t const *) ""; } /* * NAME: field->getfulllatin1() * DESCRIPTION: return the value of a full latin1 field */ id3_latin1_t const *id3_field_getfulllatin1(union id3_field const *field) { assert(field); if (field->type != ID3_FIELD_TYPE_LATIN1FULL) return 0; return field->latin1.ptr ? field->latin1.ptr : (id3_latin1_t const *) ""; } /* * NAME: field->getstring() * DESCRIPTION: return the value of a string field */ id3_ucs4_t const *id3_field_getstring(union id3_field const *field) { assert(field); if (field->type != ID3_FIELD_TYPE_STRING) return 0; return field->string.ptr ? field->string.ptr : id3_ucs4_empty; } /* * NAME: field->getfullstring() * DESCRIPTION: return the value of a fullstring field */ id3_ucs4_t const *id3_field_getfullstring(union id3_field const *field) { assert(field); if (field->type != ID3_FIELD_TYPE_STRINGFULL) return 0; return field->string.ptr ? field->string.ptr : id3_ucs4_empty; } /* * NAME: field->getnstrings() * DESCRIPTION: return the number of strings in a stringlist field */ unsigned int id3_field_getnstrings(union id3_field const *field) { assert(field); if (field->type != ID3_FIELD_TYPE_STRINGLIST) return 0; return field->stringlist.nstrings; } /* * NAME: field->getstrings() * DESCRIPTION: return one value of a stringlist field */ id3_ucs4_t const *id3_field_getstrings(union id3_field const *field, unsigned int index) { id3_ucs4_t const *string; assert(field); if (field->type != ID3_FIELD_TYPE_STRINGLIST || index >= field->stringlist.nstrings) return 0; string = field->stringlist.strings[index]; return string ? string : id3_ucs4_empty; } /* * NAME: field->getframeid() * DESCRIPTION: return the value of a frameid field */ char const *id3_field_getframeid(union id3_field const *field) { assert(field); if (field->type != ID3_FIELD_TYPE_FRAMEID) return 0; return field->immediate.value; } /* * NAME: field->getbinarydata() * DESCRIPTION: return the value of a binarydata field */ id3_byte_t const *id3_field_getbinarydata(union id3_field const *field, id3_length_t *length) { static id3_byte_t const empty; assert(field && length); if (field->type != ID3_FIELD_TYPE_BINARYDATA) return 0; assert(field->binary.length == 0 || field->binary.data); *length = field->binary.length; return field->binary.data ? field->binary.data : ∅ } libid3tag-0.16.3/field.h000066400000000000000000000024211470022143500146740ustar00rootroot00000000000000/* * libid3tag - ID3 tag manipulation library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: field.h,v 1.9 2004/01/23 09:41:32 rob Exp $ */ # ifndef LIBID3TAG_FIELD_H # define LIBID3TAG_FIELD_H # include "id3tag.h" void id3_field_init(union id3_field *, enum id3_field_type); void id3_field_finish(union id3_field *); int id3_field_parse(union id3_field *, id3_byte_t const **, id3_length_t, enum id3_field_textencoding *); id3_length_t id3_field_render(union id3_field const *, id3_byte_t **, enum id3_field_textencoding *, int); # endif libid3tag-0.16.3/file.c000066400000000000000000000336131470022143500145320ustar00rootroot00000000000000/* * libid3tag - ID3 tag manipulation library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: file.c,v 1.21 2004/01/23 09:41:32 rob Exp $ */ # include "global.h" # include # include # include # ifdef HAVE_UNISTD_H # include # endif # ifdef HAVE_ASSERT_H # include # endif # ifdef HAVE_SYS_STAT_H # include # endif # include "id3tag.h" # include "file.h" # include "tag.h" # include "field.h" struct filetag { struct id3_tag *tag; unsigned long location; id3_length_t length; }; struct id3_file { FILE *iofile; enum id3_file_mode mode; char *path; int flags; struct id3_tag *primary; unsigned int ntags; struct filetag *tags; }; enum { ID3_FILE_FLAG_ID3V1 = 0x0001 }; /* * NAME: query_tag() * DESCRIPTION: check for a tag at a file's current position */ static signed long query_tag(FILE *iofile) { fpos_t save_position; id3_byte_t query[ID3_TAG_QUERYSIZE]; signed long size; if (fgetpos(iofile, &save_position) == -1) return 0; size = id3_tag_query(query, fread(query, 1, sizeof(query), iofile)); if (fsetpos(iofile, &save_position) == -1) return 0; return size; } /* * NAME: read_tag() * DESCRIPTION: read and parse a tag at a file's current position */ static struct id3_tag *read_tag(FILE *iofile, id3_length_t size) { id3_byte_t *data; struct id3_tag *tag = 0; data = malloc(size); if (data) { if (fread(data, size, 1, iofile) == 1) tag = id3_tag_parse(data, size); free(data); } return tag; } /* * NAME: update_primary() * DESCRIPTION: update the primary tag with data from a new tag */ static int update_primary(struct id3_tag *tag, struct id3_tag const *new) { unsigned int i; struct id3_frame *frame; if (new) { if (!(new->extendedflags & ID3_TAG_EXTENDEDFLAG_TAGISANUPDATE)) id3_tag_clearframes(tag); i = 0; while ((frame = id3_tag_findframe(new, 0, i++))) { if (id3_tag_attachframe(tag, frame) == -1) return -1; } } return 0; } /* * NAME: tag_compare() * DESCRIPTION: tag sort function for qsort() */ static int tag_compare(const void *a, const void *b) { struct filetag const *tag1 = a, *tag2 = b; if (tag1->location < tag2->location) return -1; else if (tag1->location > tag2->location) return +1; return 0; } /* * NAME: add_filetag() * DESCRIPTION: add a new file tag entry */ static int add_filetag(struct id3_file *file, struct filetag const *filetag) { struct filetag *tags; tags = realloc(file->tags, (file->ntags + 1) * sizeof(*tags)); if (tags == 0) return -1; file->tags = tags; file->tags[file->ntags++] = *filetag; /* sort tags by location */ if (file->ntags > 1) qsort(file->tags, file->ntags, sizeof(file->tags[0]), tag_compare); return 0; } /* * NAME: del_filetag() * DESCRIPTION: delete a file tag entry */ static void del_filetag(struct id3_file *file, unsigned int index) { assert(index < file->ntags); while (index < file->ntags - 1) { file->tags[index] = file->tags[index + 1]; ++index; } --file->ntags; } /* * NAME: add_tag() * DESCRIPTION: read, parse, and add a tag to a file structure */ static struct id3_tag *add_tag(struct id3_file *file, id3_length_t length) { long location; unsigned int i; struct filetag filetag; struct id3_tag *tag; location = ftell(file->iofile); if (location == -1) return 0; /* check for duplication/overlap */ { unsigned long begin1, end1, begin2, end2; begin1 = location; end1 = begin1 + length; for (i = 0; i < file->ntags; ++i) { begin2 = file->tags[i].location; end2 = begin2 + file->tags[i].length; if (begin1 == begin2 && end1 == end2) return file->tags[i].tag; /* duplicate */ if (begin1 < end2 && end1 > begin2) return 0; /* overlap */ } } tag = read_tag(file->iofile, length); filetag.tag = tag; filetag.location = location; filetag.length = length; if (add_filetag(file, &filetag) == -1 || update_primary(file->primary, tag) == -1) { if (tag) id3_tag_delete(tag); return 0; } if (tag) id3_tag_addref(tag); return tag; } /* * NAME: search_tags() * DESCRIPTION: search for tags in a file */ static int search_tags(struct id3_file *file) { fpos_t save_position; signed long size; /* * save the current seek position * * We also verify the stream is seekable by calling fsetpos(), since * fgetpos() alone is not reliable enough for this purpose. * * [Apparently not even fsetpos() is sufficient under Win32.] */ if (fgetpos(file->iofile, &save_position) == -1 || fsetpos(file->iofile, &save_position) == -1) return -1; /* look for an ID3v1 tag */ if (fseek(file->iofile, -128, SEEK_END) == 0) { size = query_tag(file->iofile); if (size > 0) { struct id3_tag const *tag; tag = add_tag(file, size); /* if this is indeed an ID3v1 tag, mark the file so */ if (tag && (ID3_TAG_VERSION_MAJOR(id3_tag_version(tag)) == 1)) file->flags |= ID3_FILE_FLAG_ID3V1; } } /* look for a tag at the beginning of the file */ rewind(file->iofile); size = query_tag(file->iofile); if (size > 0) { struct id3_tag const *tag; struct id3_frame const *frame; tag = add_tag(file, size); /* locate tags indicated by SEEK frames */ while (tag && (frame = id3_tag_findframe(tag, "SEEK", 0))) { long seek; seek = id3_field_getint(id3_frame_field(frame, 0)); if (seek < 0 || fseek(file->iofile, seek, SEEK_CUR) == -1) break; size = query_tag(file->iofile); tag = (size > 0) ? add_tag(file, size) : 0; } } /* look for a tag at the end of the file (before any ID3v1 tag) */ if (fseek(file->iofile, ((file->flags & ID3_FILE_FLAG_ID3V1) ? -128 : 0) + -10, SEEK_END) == 0) { size = query_tag(file->iofile); if (size < 0 && fseek(file->iofile, size, SEEK_CUR) == 0) { size = query_tag(file->iofile); if (size > 0) add_tag(file, size); } } clearerr(file->iofile); /* restore seek position */ if (fsetpos(file->iofile, &save_position) == -1) return -1; /* set primary tag options and target padded length for convenience */ if ((file->ntags > 0 && !(file->flags & ID3_FILE_FLAG_ID3V1)) || (file->ntags > 1 && (file->flags & ID3_FILE_FLAG_ID3V1))) { if (file->tags[0].location == 0) id3_tag_setlength(file->primary, file->tags[0].length); else id3_tag_options(file->primary, ID3_TAG_OPTION_APPENDEDTAG, ~0); } return 0; } /* * NAME: finish_file() * DESCRIPTION: release memory associated with a file */ static void finish_file(struct id3_file *file) { unsigned int i; if (file->path) free(file->path); if (file->primary) { id3_tag_delref(file->primary); id3_tag_delete(file->primary); } for (i = 0; i < file->ntags; ++i) { struct id3_tag *tag; tag = file->tags[i].tag; if (tag) { id3_tag_delref(tag); id3_tag_delete(tag); } } if (file->tags) free(file->tags); free(file); } /* * NAME: new_file() * DESCRIPTION: create a new file structure and load tags */ static struct id3_file *new_file(FILE *iofile, enum id3_file_mode mode, char const *path) { struct id3_file *file; file = malloc(sizeof(*file)); if (file == 0) goto fail; file->iofile = iofile; file->mode = mode; file->path = path ? strdup(path) : 0; file->flags = 0; file->ntags = 0; file->tags = 0; file->primary = id3_tag_new(); if (file->primary == 0) goto fail; id3_tag_addref(file->primary); /* load tags from the file */ if (search_tags(file) == -1) goto fail; id3_tag_options(file->primary, ID3_TAG_OPTION_ID3V1, (file->flags & ID3_FILE_FLAG_ID3V1) ? ~0 : 0); if (0) { fail: if (file) { finish_file(file); file = 0; } } return file; } /* * NAME: file->open() * DESCRIPTION: open a file given its pathname */ struct id3_file *id3_file_open(char const *path, enum id3_file_mode mode) { FILE *iofile; struct id3_file *file; assert(path); iofile = fopen(path, (mode == ID3_FILE_MODE_READWRITE) ? "r+b" : "rb"); if (iofile == 0) return 0; file = new_file(iofile, mode, path); if (file == 0) fclose(iofile); return file; } /* * NAME: file->fdopen() * DESCRIPTION: open a file using an existing file descriptor */ struct id3_file *id3_file_fdopen(int fd, enum id3_file_mode mode) { # if 1 || defined(HAVE_UNISTD_H) FILE *iofile; struct id3_file *file; iofile = fdopen(fd, (mode == ID3_FILE_MODE_READWRITE) ? "r+b" : "rb"); if (iofile == 0) return 0; file = new_file(iofile, mode, 0); if (file == 0) { int save_fd; /* close iofile without closing fd */ save_fd = dup(fd); fclose(iofile); dup2(save_fd, fd); close(save_fd); } return file; # else return 0; # endif } /* * NAME: file->close() * DESCRIPTION: close a file and delete its associated tags */ int id3_file_close(struct id3_file *file) { int result = 0; assert(file); if (fclose(file->iofile) == EOF) result = -1; finish_file(file); return result; } /* * NAME: file->tag() * DESCRIPTION: return the primary tag structure for a file */ struct id3_tag *id3_file_tag(struct id3_file const *file) { assert(file); return file->primary; } /* * NAME: v1_write() * DESCRIPTION: write ID3v1 tag modifications to a file */ static int v1_write(struct id3_file *file, id3_byte_t const *data, id3_length_t length) { assert(!data || length == 128); if (data) { long location; if (fseek(file->iofile, (file->flags & ID3_FILE_FLAG_ID3V1) ? -128 : 0, SEEK_END) == -1 || (location = ftell(file->iofile)) == -1 || fwrite(data, 128, 1, file->iofile) != 1 || fflush(file->iofile) == EOF) return -1; /* add file tag reference */ if (!(file->flags & ID3_FILE_FLAG_ID3V1)) { struct filetag filetag; filetag.tag = 0; filetag.location = location; filetag.length = 128; if (add_filetag(file, &filetag) == -1) return -1; file->flags |= ID3_FILE_FLAG_ID3V1; } } # if defined(HAVE_FTRUNCATE) else if (file->flags & ID3_FILE_FLAG_ID3V1) { long length; if (fseek(file->iofile, 0, SEEK_END) == -1) return -1; length = ftell(file->iofile); if (length == -1 || (length >= 0 && length < 128)) return -1; if (ftruncate(fileno(file->iofile), length - 128) == -1) return -1; /* delete file tag reference */ del_filetag(file, file->ntags - 1); file->flags &= ~ID3_FILE_FLAG_ID3V1; } # endif return 0; } /* * NAME: v2_write() * DESCRIPTION: write ID3v2 tag modifications to a file */ static int v2_write(struct id3_file *file, id3_byte_t const *data, id3_length_t length) { struct stat st; char *buffer; id3_length_t datalen, offset; assert(!data || length > 0); if (data && ((file->ntags == 1 && !(file->flags & ID3_FILE_FLAG_ID3V1)) || (file->ntags == 2 && (file->flags & ID3_FILE_FLAG_ID3V1))) && file->tags[0].length == length) { /* easy special case: rewrite existing tag in-place */ if (fseek(file->iofile, file->tags[0].location, SEEK_SET) == -1 || fwrite(data, length, 1, file->iofile) != 1 || fflush(file->iofile) == EOF) return -1; goto done; } /* hard general case: rewrite entire file */ if (stat(file->path, &st) == -1) return -1; offset = file->tags ? file->tags[0].length : 0; datalen = st.st_size - offset; if ((buffer = (char *) malloc(datalen)) == NULL) return -1; if (fseek(file->iofile, offset, SEEK_SET) == -1 || fread(buffer, datalen, 1, file->iofile) != 1 || fseek(file->iofile, 0, SEEK_SET) == -1 || fwrite(data, length, 1, file->iofile) != 1 || fwrite(buffer, datalen, 1, file->iofile) != 1 || fflush(file->iofile) == EOF) { free(buffer); return -1; } free(buffer); done: return 0; } /* * NAME: file->update() * DESCRIPTION: rewrite tag(s) to a file */ int id3_file_update(struct id3_file *file) { int options, result = 0; id3_length_t v1size = 0, v2size = 0; id3_byte_t id3v1_data[128], *id3v1 = 0, *id3v2 = 0; assert(file); if (file->mode != ID3_FILE_MODE_READWRITE) return -1; options = id3_tag_options(file->primary, 0, 0); /* render ID3v1 */ if (options & ID3_TAG_OPTION_ID3V1) { v1size = id3_tag_render(file->primary, 0); if (v1size) { assert(v1size == sizeof(id3v1_data)); v1size = id3_tag_render(file->primary, id3v1_data); if (v1size) { assert(v1size == sizeof(id3v1_data)); id3v1 = id3v1_data; } } } /* render ID3v2 */ id3_tag_options(file->primary, ID3_TAG_OPTION_ID3V1, 0); v2size = id3_tag_render(file->primary, 0); if (v2size) { id3v2 = malloc(v2size); if (id3v2 == 0) goto fail; v2size = id3_tag_render(file->primary, id3v2); if (v2size == 0) { free(id3v2); id3v2 = 0; } } /* write tags */ if (v2_write(file, id3v2, v2size) == -1 || v1_write(file, id3v1, v1size) == -1) goto fail; rewind(file->iofile); /* update file tags array? ... */ if (0) { fail: result = -1; } /* clean up; restore tag options */ if (id3v2) free(id3v2); id3_tag_options(file->primary, ~0, options); return result; } libid3tag-0.16.3/file.h000066400000000000000000000016521470022143500145350ustar00rootroot00000000000000/* * libid3tag - ID3 tag manipulation library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: file.h,v 1.8 2004/01/23 09:41:32 rob Exp $ */ # ifndef LIBID3TAG_FILE_H # define LIBID3TAG_FILE_H # endif libid3tag-0.16.3/frame.c000066400000000000000000000325231470022143500147040ustar00rootroot00000000000000/* * libid3tag - ID3 tag manipulation library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: frame.c,v 1.15 2004/01/23 09:41:32 rob Exp $ */ # include "global.h" # include # include # ifdef HAVE_ASSERT_H # include # endif # include "id3tag.h" # include "frame.h" # include "frametype.h" # include "compat.h" # include "field.h" # include "render.h" # include "parse.h" # include "util.h" static int valid_idchar(char c) { return (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9'); } /* * NAME: frame->validid() * DESCRIPTION: return true if the parameter string is a legal frame ID */ int id3_frame_validid(char const *id) { return id && valid_idchar(id[0]) && valid_idchar(id[1]) && valid_idchar(id[2]) && valid_idchar(id[3]); } /* * NAME: frame->new() * DESCRIPTION: allocate and return a new frame */ struct id3_frame *id3_frame_new(char const *id) { struct id3_frametype const *frametype; struct id3_frame *frame; unsigned int i; if (!id3_frame_validid(id)) return 0; frametype = id3_frametype_lookup(id, 4); if (frametype == 0) { switch (id[0]) { case 'T': frametype = &id3_frametype_text; break; case 'W': frametype = &id3_frametype_url; break; case 'X': case 'Y': case 'Z': frametype = &id3_frametype_experimental; break; default: frametype = &id3_frametype_unknown; if (id3_compat_lookup(id, 4)) frametype = &id3_frametype_obsolete; break; } } frame = malloc(sizeof(*frame) + frametype->nfields * sizeof(*frame->fields)); if (frame) { frame->id[0] = id[0]; frame->id[1] = id[1]; frame->id[2] = id[2]; frame->id[3] = id[3]; frame->id[4] = 0; frame->description = frametype->description; frame->refcount = 0; frame->flags = frametype->defaultflags; frame->group_id = 0; frame->encryption_method = 0; frame->encoded = 0; frame->encoded_length = 0; frame->decoded_length = 0; frame->nfields = frametype->nfields; frame->fields = (union id3_field *) &frame[1]; for (i = 0; i < frame->nfields; ++i) id3_field_init(&frame->fields[i], frametype->fields[i]); } return frame; } void id3_frame_delete(struct id3_frame *frame) { assert(frame); if (frame->refcount == 0) { unsigned int i; for (i = 0; i < frame->nfields; ++i) id3_field_finish(&frame->fields[i]); if (frame->encoded) free(frame->encoded); free(frame); } } /* * NAME: frame->addref() * DESCRIPTION: add an external reference to a frame */ void id3_frame_addref(struct id3_frame *frame) { assert(frame); ++frame->refcount; } /* * NAME: frame->delref() * DESCRIPTION: remove an external reference to a frame */ void id3_frame_delref(struct id3_frame *frame) { assert(frame && frame->refcount > 0); --frame->refcount; } /* * NAME: frame->field() * DESCRIPTION: return a pointer to a field in a frame */ union id3_field *id3_frame_field(struct id3_frame const *frame, unsigned int index) { assert(frame); return (index < frame->nfields) ? &frame->fields[index] : 0; } static struct id3_frame *obsolete(char const *id, id3_byte_t const *data, id3_length_t length) { struct id3_frame *frame; frame = id3_frame_new(ID3_FRAME_OBSOLETE); if (frame) { if (id3_field_setframeid(&frame->fields[0], id) == -1 || id3_field_setbinarydata(&frame->fields[1], data, length) == -1) goto fail; } if (0) { fail: if (frame) { id3_frame_delete(frame); frame = 0; } } return frame; } static struct id3_frame *unparseable(char const *id, id3_byte_t const **ptr, id3_length_t length, int flags, int group_id, int encryption_method, id3_length_t decoded_length) { struct id3_frame *frame = 0; id3_byte_t *mem; mem = malloc(length ? length : 1); if (mem == 0) goto fail; frame = id3_frame_new(id); if (frame == 0) free(mem); else { memcpy(mem, *ptr, length); frame->flags = flags; frame->group_id = group_id; frame->encryption_method = encryption_method; frame->encoded = mem; frame->encoded_length = length; frame->decoded_length = decoded_length; } if (0) { fail: ; } *ptr += length; return frame; } static int parse_data(struct id3_frame *frame, id3_byte_t const *data, id3_length_t length) { enum id3_field_textencoding encoding; id3_byte_t const *end; unsigned int i; encoding = ID3_FIELD_TEXTENCODING_ISO_8859_1; end = data + length; for (i = 0; i < frame->nfields; ++i) { if (id3_field_parse(&frame->fields[i], &data, end - data, &encoding) == -1) return -1; } return 0; } /* * NAME: frame->parse() * DESCRIPTION: parse raw frame data according to the specified ID3 tag version */ struct id3_frame *id3_frame_parse(id3_byte_t const **ptr, id3_length_t length, unsigned int version) { struct id3_frame *frame = 0; id3_byte_t const *id, *end, *data; id3_length_t size, decoded_length = 0; int flags = 0, group_id = 0, encryption_method = 0; struct id3_compat const *compat = 0; id3_byte_t *mem = 0; char xid[4]; id = *ptr; end = *ptr + length; if (ID3_TAG_VERSION_MAJOR(version) < 4) { switch (ID3_TAG_VERSION_MAJOR(version)) { case 2: if (length < 6) goto fail; compat = id3_compat_lookup(id, 3); *ptr += 3; size = id3_parse_uint(ptr, 3); if (size > end - *ptr) goto fail; end = *ptr + size; break; case 3: if (length < 10) goto fail; compat = id3_compat_lookup(id, 4); *ptr += 4; size = id3_parse_uint(ptr, 4); flags = id3_parse_uint(ptr, 2); if (size > end - *ptr) goto fail; end = *ptr + size; if (flags & (ID3_FRAME_FLAG_FORMATFLAGS & ~0x00e0)) { frame = unparseable(id, ptr, end - *ptr, 0, 0, 0, 0); goto done; } flags = ((flags >> 1) & ID3_FRAME_FLAG_STATUSFLAGS) | ((flags >> 4) & (ID3_FRAME_FLAG_COMPRESSION | ID3_FRAME_FLAG_ENCRYPTION)) | ((flags << 1) & ID3_FRAME_FLAG_GROUPINGIDENTITY); if (flags & ID3_FRAME_FLAG_COMPRESSION) { if (end - *ptr < 4) goto fail; decoded_length = id3_parse_uint(ptr, 4); } if (flags & ID3_FRAME_FLAG_ENCRYPTION) { if (end - *ptr < 1) goto fail; encryption_method = id3_parse_uint(ptr, 1); } if (flags & ID3_FRAME_FLAG_GROUPINGIDENTITY) { if (end - *ptr < 1) goto fail; group_id = id3_parse_uint(ptr, 1); } break; default: goto fail; } /* canonicalize frame ID for ID3v2.4 */ if (compat && compat->equiv) id = compat->equiv; else if (ID3_TAG_VERSION_MAJOR(version) == 2) { xid[0] = 'Y'; xid[1] = id[0]; xid[2] = id[1]; xid[3] = id[2]; id = xid; flags |= ID3_FRAME_FLAG_TAGALTERPRESERVATION | ID3_FRAME_FLAG_FILEALTERPRESERVATION; } } else { /* ID3v2.4 */ if (length < 10) goto fail; *ptr += 4; size = id3_parse_syncsafe(ptr, 4); flags = id3_parse_uint(ptr, 2); if (size > end - *ptr) goto fail; end = *ptr + size; if (flags & (ID3_FRAME_FLAG_FORMATFLAGS & ~ID3_FRAME_FLAG_KNOWNFLAGS)) { frame = unparseable(id, ptr, end - *ptr, flags, 0, 0, 0); goto done; } if (flags & ID3_FRAME_FLAG_GROUPINGIDENTITY) { if (end - *ptr < 1) goto fail; group_id = id3_parse_uint(ptr, 1); } if ((flags & ID3_FRAME_FLAG_COMPRESSION) && !(flags & ID3_FRAME_FLAG_DATALENGTHINDICATOR)) goto fail; if (flags & ID3_FRAME_FLAG_ENCRYPTION) { if (end - *ptr < 1) goto fail; encryption_method = id3_parse_uint(ptr, 1); } if (flags & ID3_FRAME_FLAG_DATALENGTHINDICATOR) { if (end - *ptr < 4) goto fail; decoded_length = id3_parse_syncsafe(ptr, 4); } } data = *ptr; *ptr = end; /* undo frame encodings */ if ((flags & ID3_FRAME_FLAG_UNSYNCHRONISATION) && end - data > 0) { mem = malloc(end - data); if (mem == 0) goto fail; memcpy(mem, data, end - data); end = mem + id3_util_deunsynchronise(mem, end - data); data = mem; } if (flags & ID3_FRAME_FLAG_ENCRYPTION) { frame = unparseable(id, &data, end - data, flags, group_id, encryption_method, decoded_length); goto done; } if (flags & ID3_FRAME_FLAG_COMPRESSION) { id3_byte_t *decomp; decomp = id3_util_decompress(data, end - data, decoded_length); if (decomp == 0) goto fail; if (mem) free(mem); data = mem = decomp; end = data + decoded_length; } /* check for obsolescence */ if (compat && !compat->equiv) { frame = obsolete(id, data, end - data); goto done; } /* generate the internal frame structure */ frame = id3_frame_new(id); if (frame) { frame->flags = flags; frame->group_id = group_id; if (compat && compat->translate) { if (compat->translate(frame, compat->id, data, end - data) == -1) goto fail; } else { if (parse_data(frame, data, end - data) == -1) goto fail; } } if (0) { fail: if (frame) { id3_frame_delete(frame); frame = 0; } } done: if (mem) free(mem); return frame; } static id3_length_t render_data(id3_byte_t **ptr, union id3_field *fields, unsigned int length) { id3_length_t size = 0; enum id3_field_textencoding encoding; unsigned int i; encoding = ID3_FIELD_TEXTENCODING_ISO_8859_1; for (i = 0; i < length; ++i) size += id3_field_render(&fields[i], ptr, &encoding, i < length - 1); return size; } /* * NAME: frame->render() * DESCRIPTION: render a single, complete frame */ id3_length_t id3_frame_render(struct id3_frame const *frame, id3_byte_t **ptr, int options) { id3_length_t size = 0, decoded_length, datalen; id3_byte_t *size_ptr = 0, *flags_ptr = 0, *data = 0; int flags; assert(frame); if ((frame->flags & ID3_FRAME_FLAG_TAGALTERPRESERVATION) || ((options & ID3_TAG_OPTION_FILEALTERED) && (frame->flags & ID3_FRAME_FLAG_FILEALTERPRESERVATION))) return 0; /* a frame must be at least 1 byte big, excluding the header */ decoded_length = render_data(0, frame->fields, frame->nfields); if (decoded_length == 0 && frame->encoded == 0) return 0; /* header */ size += id3_render_immediate(ptr, frame->id, 4); if (ptr) size_ptr = *ptr; size += id3_render_syncsafe(ptr, 0, 4); if (ptr) flags_ptr = *ptr; flags = frame->flags; size += id3_render_int(ptr, flags, 2); if (flags & (ID3_FRAME_FLAG_FORMATFLAGS & ~ID3_FRAME_FLAG_KNOWNFLAGS)) { size += id3_render_binary(ptr, frame->encoded, frame->encoded_length); if (size_ptr) id3_render_syncsafe(&size_ptr, size - 10, 4); return size; } flags &= ID3_FRAME_FLAG_KNOWNFLAGS; flags &= ~ID3_FRAME_FLAG_UNSYNCHRONISATION; if (options & ID3_TAG_OPTION_UNSYNCHRONISATION) flags |= ID3_FRAME_FLAG_UNSYNCHRONISATION; if (!(flags & ID3_FRAME_FLAG_ENCRYPTION)) { flags &= ~ID3_FRAME_FLAG_COMPRESSION; if (options & ID3_TAG_OPTION_COMPRESSION) flags |= ID3_FRAME_FLAG_COMPRESSION | ID3_FRAME_FLAG_DATALENGTHINDICATOR; } if (flags & ID3_FRAME_FLAG_GROUPINGIDENTITY) size += id3_render_int(ptr, frame->group_id, 1); if (flags & ID3_FRAME_FLAG_ENCRYPTION) size += id3_render_int(ptr, frame->encryption_method, 1); if (flags & ID3_FRAME_FLAG_DATALENGTHINDICATOR) { if (flags & ID3_FRAME_FLAG_ENCRYPTION) decoded_length = frame->decoded_length; size += id3_render_syncsafe(ptr, decoded_length, 4); } if (ptr) data = *ptr; if (flags & ID3_FRAME_FLAG_ENCRYPTION) datalen = id3_render_binary(ptr, frame->encoded, frame->encoded_length); else { if (ptr == 0) datalen = decoded_length; else { datalen = render_data(ptr, frame->fields, frame->nfields); if (flags & ID3_FRAME_FLAG_COMPRESSION) { id3_byte_t *comp; id3_length_t complen; comp = id3_util_compress(data, datalen, &complen); if (comp == 0) flags &= ~ID3_FRAME_FLAG_COMPRESSION; else { *ptr = data; datalen = id3_render_binary(ptr, comp, complen); free(comp); } } } } /* unsynchronisation */ if (flags & ID3_FRAME_FLAG_UNSYNCHRONISATION) { if (data == 0) datalen *= 2; else { id3_length_t newlen; newlen = id3_util_unsynchronise(data, datalen); if (newlen == datalen) flags &= ~ID3_FRAME_FLAG_UNSYNCHRONISATION; else { *ptr += newlen - datalen; datalen = newlen; } } } size += datalen; /* patch size and flags */ if (size_ptr) id3_render_syncsafe(&size_ptr, size - 10, 4); if (flags_ptr) id3_render_int(&flags_ptr, flags, 2); return size; } libid3tag-0.16.3/frame.h000066400000000000000000000023501470022143500147040ustar00rootroot00000000000000/* * libid3tag - ID3 tag manipulation library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: frame.h,v 1.8 2004/01/23 09:41:32 rob Exp $ */ # ifndef LIBID3TAG_FRAME_H # define LIBID3TAG_FRAME_H # include "id3tag.h" int id3_frame_validid(char const *); void id3_frame_addref(struct id3_frame *); void id3_frame_delref(struct id3_frame *); struct id3_frame *id3_frame_parse(id3_byte_t const **, id3_length_t, unsigned int); id3_length_t id3_frame_render(struct id3_frame const *, id3_byte_t **, int); # endif libid3tag-0.16.3/frametype.c000066400000000000000000000441111470022143500156020ustar00rootroot00000000000000/* C code produced by gperf version 3.0.1 */ /* Command-line: gperf -tCcTonD -K id -N id3_frametype_lookup -s -3 -k '*' frametype.gperf */ #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) /* The character set is not based on ISO-646. */ error "gperf generated tables don't work with this execution character set. Please report a bug to ." #endif #line 1 "frametype.gperf" /* * libid3tag - ID3 tag manipulation library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Id: frametype.gperf,v 1.7 2004/01/23 09:41:32 rob Exp */ # include "global.h" # include # include "id3tag.h" # include "frametype.h" # define FIELDS(id) static enum id3_field_type const fields_##id[] /* frame field descriptions */ FIELDS(UFID) = { ID3_FIELD_TYPE_LATIN1, ID3_FIELD_TYPE_BINARYDATA }; FIELDS(TXXX) = { ID3_FIELD_TYPE_TEXTENCODING, ID3_FIELD_TYPE_STRING, ID3_FIELD_TYPE_STRING }; FIELDS(WXXX) = { ID3_FIELD_TYPE_TEXTENCODING, ID3_FIELD_TYPE_STRING, ID3_FIELD_TYPE_LATIN1 }; FIELDS(MCDI) = { ID3_FIELD_TYPE_BINARYDATA }; FIELDS(ETCO) = { ID3_FIELD_TYPE_INT8, ID3_FIELD_TYPE_BINARYDATA }; FIELDS(MLLT) = { ID3_FIELD_TYPE_INT16, ID3_FIELD_TYPE_INT24, ID3_FIELD_TYPE_INT24, ID3_FIELD_TYPE_INT8, ID3_FIELD_TYPE_INT8, ID3_FIELD_TYPE_BINARYDATA }; FIELDS(SYTC) = { ID3_FIELD_TYPE_INT8, ID3_FIELD_TYPE_BINARYDATA }; FIELDS(USLT) = { ID3_FIELD_TYPE_TEXTENCODING, ID3_FIELD_TYPE_LANGUAGE, ID3_FIELD_TYPE_STRING, ID3_FIELD_TYPE_STRINGFULL }; FIELDS(SYLT) = { ID3_FIELD_TYPE_TEXTENCODING, ID3_FIELD_TYPE_LANGUAGE, ID3_FIELD_TYPE_INT8, ID3_FIELD_TYPE_INT8, ID3_FIELD_TYPE_STRING, ID3_FIELD_TYPE_BINARYDATA }; FIELDS(COMM) = { ID3_FIELD_TYPE_TEXTENCODING, ID3_FIELD_TYPE_LANGUAGE, ID3_FIELD_TYPE_STRING, ID3_FIELD_TYPE_STRINGFULL }; FIELDS(RVA2) = { ID3_FIELD_TYPE_LATIN1, ID3_FIELD_TYPE_BINARYDATA }; FIELDS(EQU2) = { ID3_FIELD_TYPE_INT8, ID3_FIELD_TYPE_LATIN1, ID3_FIELD_TYPE_BINARYDATA }; FIELDS(RVRB) = { ID3_FIELD_TYPE_INT16, ID3_FIELD_TYPE_INT16, ID3_FIELD_TYPE_INT8, ID3_FIELD_TYPE_INT8, ID3_FIELD_TYPE_INT8, ID3_FIELD_TYPE_INT8, ID3_FIELD_TYPE_INT8, ID3_FIELD_TYPE_INT8, ID3_FIELD_TYPE_INT8, ID3_FIELD_TYPE_INT8 }; FIELDS(APIC) = { ID3_FIELD_TYPE_TEXTENCODING, ID3_FIELD_TYPE_LATIN1, ID3_FIELD_TYPE_INT8, ID3_FIELD_TYPE_STRING, ID3_FIELD_TYPE_BINARYDATA }; FIELDS(GEOB) = { ID3_FIELD_TYPE_TEXTENCODING, ID3_FIELD_TYPE_LATIN1, ID3_FIELD_TYPE_STRING, ID3_FIELD_TYPE_STRING, ID3_FIELD_TYPE_BINARYDATA }; FIELDS(PCNT) = { ID3_FIELD_TYPE_INT32PLUS }; FIELDS(POPM) = { ID3_FIELD_TYPE_LATIN1, ID3_FIELD_TYPE_INT8, ID3_FIELD_TYPE_INT32PLUS }; FIELDS(RBUF) = { ID3_FIELD_TYPE_INT24, ID3_FIELD_TYPE_INT8, ID3_FIELD_TYPE_INT32 }; FIELDS(AENC) = { ID3_FIELD_TYPE_LATIN1, ID3_FIELD_TYPE_INT16, ID3_FIELD_TYPE_INT16, ID3_FIELD_TYPE_BINARYDATA }; FIELDS(LINK) = { ID3_FIELD_TYPE_FRAMEID, ID3_FIELD_TYPE_LATIN1, ID3_FIELD_TYPE_LATIN1LIST }; FIELDS(POSS) = { ID3_FIELD_TYPE_INT8, ID3_FIELD_TYPE_BINARYDATA }; FIELDS(USER) = { ID3_FIELD_TYPE_TEXTENCODING, ID3_FIELD_TYPE_LANGUAGE, ID3_FIELD_TYPE_STRING }; FIELDS(OWNE) = { ID3_FIELD_TYPE_TEXTENCODING, ID3_FIELD_TYPE_LATIN1, ID3_FIELD_TYPE_DATE, ID3_FIELD_TYPE_STRING }; FIELDS(COMR) = { ID3_FIELD_TYPE_TEXTENCODING, ID3_FIELD_TYPE_LATIN1, ID3_FIELD_TYPE_DATE, ID3_FIELD_TYPE_LATIN1, ID3_FIELD_TYPE_INT8, ID3_FIELD_TYPE_STRING, ID3_FIELD_TYPE_STRING, ID3_FIELD_TYPE_LATIN1, ID3_FIELD_TYPE_BINARYDATA }; FIELDS(ENCR) = { ID3_FIELD_TYPE_LATIN1, ID3_FIELD_TYPE_INT8, ID3_FIELD_TYPE_BINARYDATA }; FIELDS(GRID) = { ID3_FIELD_TYPE_LATIN1, ID3_FIELD_TYPE_INT8, ID3_FIELD_TYPE_BINARYDATA }; FIELDS(PRIV) = { ID3_FIELD_TYPE_LATIN1, ID3_FIELD_TYPE_BINARYDATA }; FIELDS(SIGN) = { ID3_FIELD_TYPE_INT8, ID3_FIELD_TYPE_BINARYDATA }; FIELDS(SEEK) = { ID3_FIELD_TYPE_INT32 }; FIELDS(ASPI) = { ID3_FIELD_TYPE_INT32, ID3_FIELD_TYPE_INT32, ID3_FIELD_TYPE_INT16, ID3_FIELD_TYPE_INT8, ID3_FIELD_TYPE_BINARYDATA }; FIELDS(text) = { ID3_FIELD_TYPE_TEXTENCODING, ID3_FIELD_TYPE_STRINGLIST }; FIELDS(url) = { ID3_FIELD_TYPE_LATIN1 }; FIELDS(unknown) = { ID3_FIELD_TYPE_BINARYDATA }; FIELDS(ZOBS) = { ID3_FIELD_TYPE_FRAMEID, ID3_FIELD_TYPE_BINARYDATA }; # define FRAME(id) \ sizeof(fields_##id) / sizeof(fields_##id[0]), fields_##id # define PRESERVE 0 # define DISCARD ID3_FRAME_FLAG_FILEALTERPRESERVATION # define OBSOLETE (DISCARD | ID3_FRAME_FLAG_TAGALTERPRESERVATION) # define FRAMETYPE(type, id, flags, desc) \ struct id3_frametype const id3_frametype_##type = { \ 0, FRAME(id), flags, desc \ } /* static frame types */ FRAMETYPE(text, text, PRESERVE, "Unknown text information frame"); FRAMETYPE(url, url, PRESERVE, "Unknown URL link frame"); FRAMETYPE(experimental, unknown, PRESERVE, "Experimental frame"); FRAMETYPE(unknown, unknown, PRESERVE, "Unknown frame"); FRAMETYPE(obsolete, unknown, OBSOLETE, "Obsolete frame"); #define TOTAL_KEYWORDS 84 #define MIN_WORD_LENGTH 4 #define MAX_WORD_LENGTH 4 #define MIN_HASH_VALUE 7 #define MAX_HASH_VALUE 155 /* maximum key range = 149, duplicates = 0 */ #ifdef __GNUC__ __inline #else #ifdef __cplusplus inline #endif #endif static unsigned int hash (str, len) register const char *str; register unsigned int len; { static const unsigned char asso_values[] = { 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 43, 4, 47, 49, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 31, 53, 3, 15, 3, 24, 25, 10, 52, 69, 34, 23, 30, 1, 5, 10, 62, 20, 0, 28, 28, 22, 19, 47, 3, 10, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156 }; return asso_values[(unsigned char)str[3]+1] + asso_values[(unsigned char)str[2]] + asso_values[(unsigned char)str[1]] + asso_values[(unsigned char)str[0]]; } #ifdef __GNUC__ __inline #endif const struct id3_frametype * id3_frametype_lookup (str, len) register const char *str; register size_t len; { static const struct id3_frametype wordlist[] = { #line 282 "frametype.gperf" {"ENCR", FRAME(ENCR), PRESERVE, "Encryption method registration"}, #line 292 "frametype.gperf" {"POPM", FRAME(POPM), PRESERVE, "Popularimeter"}, #line 351 "frametype.gperf" {"WCOM", FRAME(url), PRESERVE, "Commercial information"}, #line 298 "frametype.gperf" {"SEEK", FRAME(SEEK), DISCARD, "Seek frame"}, #line 349 "frametype.gperf" {"USER", FRAME(USER), PRESERVE, "Terms of use"}, #line 285 "frametype.gperf" {"GEOB", FRAME(GEOB), PRESERVE, "General encapsulated object"}, #line 304 "frametype.gperf" {"TCOM", FRAME(text), PRESERVE, "Composer"}, #line 281 "frametype.gperf" {"COMR", FRAME(COMR), PRESERVE, "Commercial frame"}, #line 280 "frametype.gperf" {"COMM", FRAME(COMM), PRESERVE, "Comments"}, #line 305 "frametype.gperf" {"TCON", FRAME(text), PRESERVE, "Content type"}, #line 291 "frametype.gperf" {"PCNT", FRAME(PCNT), PRESERVE, "Play counter"}, #line 293 "frametype.gperf" {"POSS", FRAME(POSS), DISCARD, "Position synchronisation frame"}, #line 284 "frametype.gperf" {"ETCO", FRAME(ETCO), DISCARD, "Event timing codes"}, #line 332 "frametype.gperf" {"TPE2", FRAME(text), PRESERVE, "Band/orchestra/accompaniment"}, #line 301 "frametype.gperf" {"SYTC", FRAME(SYTC), DISCARD, "Synchronised tempo codes"}, #line 313 "frametype.gperf" {"TENC", FRAME(text), DISCARD, "Encoded by"}, #line 309 "frametype.gperf" {"TDOR", FRAME(text), PRESERVE, "Original release time"}, #line 290 "frametype.gperf" {"OWNE", FRAME(OWNE), PRESERVE, "Ownership frame"}, #line 277 "frametype.gperf" {"AENC", FRAME(AENC), DISCARD, "Audio encryption"}, #line 307 "frametype.gperf" {"TDEN", FRAME(text), PRESERVE, "Encoding time"}, #line 345 "frametype.gperf" {"TSSE", FRAME(text), PRESERVE, "Software/hardware and settings used for encoding"}, #line 339 "frametype.gperf" {"TRSN", FRAME(text), PRESERVE, "Internet radio station name"}, #line 300 "frametype.gperf" {"SYLT", FRAME(SYLT), DISCARD, "Synchronised lyric/text"}, #line 354 "frametype.gperf" {"WOAR", FRAME(url), PRESERVE, "Official artist/performer webpage"}, #line 346 "frametype.gperf" {"TSST", FRAME(text), PRESERVE, "Set subtitle"}, #line 330 "frametype.gperf" {"TOWN", FRAME(text), PRESERVE, "File owner/licensee"}, #line 340 "frametype.gperf" {"TRSO", FRAME(text), PRESERVE, "Internet radio station owner"}, #line 322 "frametype.gperf" {"TLEN", FRAME(text), DISCARD, "Length"}, #line 358 "frametype.gperf" {"WPUB", FRAME(url), PRESERVE, "Publishers official webpage"}, #line 343 "frametype.gperf" {"TSOT", FRAME(text), PRESERVE, "Title sort order"}, #line 327 "frametype.gperf" {"TOFN", FRAME(text), PRESERVE, "Original filename"}, #line 344 "frametype.gperf" {"TSRC", FRAME(text), PRESERVE, "ISRC (international standard recording code)"}, #line 324 "frametype.gperf" {"TMED", FRAME(text), PRESERVE, "Media type"}, #line 297 "frametype.gperf" {"RVRB", FRAME(RVRB), PRESERVE, "Reverb"}, #line 328 "frametype.gperf" {"TOLY", FRAME(text), PRESERVE, "Original lyricist(s)/text writer(s)"}, #line 329 "frametype.gperf" {"TOPE", FRAME(text), PRESERVE, "Original artist(s)/performer(s)"}, #line 336 "frametype.gperf" {"TPRO", FRAME(text), PRESERVE, "Produced notice"}, #line 337 "frametype.gperf" {"TPUB", FRAME(text), PRESERVE, "Publisher"}, #line 357 "frametype.gperf" {"WPAY", FRAME(url), PRESERVE, "Payment"}, #line 335 "frametype.gperf" {"TPOS", FRAME(text), PRESERVE, "Part of a set"}, #line 356 "frametype.gperf" {"WORS", FRAME(url), PRESERVE, "Official Internet radio station homepage"}, #line 325 "frametype.gperf" {"TMOO", FRAME(text), PRESERVE, "Mood"}, #line 338 "frametype.gperf" {"TRCK", FRAME(text), PRESERVE, "Track number/position in set"}, #line 320 "frametype.gperf" {"TKEY", FRAME(text), PRESERVE, "Initial key"}, #line 308 "frametype.gperf" {"TDLY", FRAME(text), PRESERVE, "Playlist delay"}, #line 296 "frametype.gperf" {"RVA2", FRAME(RVA2), DISCARD, "Relative volume adjustment (2)"}, #line 310 "frametype.gperf" {"TDRC", FRAME(text), PRESERVE, "Recording time"}, #line 350 "frametype.gperf" {"USLT", FRAME(USLT), PRESERVE, "Unsynchronised lyric/text transcription"}, #line 353 "frametype.gperf" {"WOAF", FRAME(url), PRESERVE, "Official audio file webpage"}, #line 312 "frametype.gperf" {"TDTG", FRAME(text), PRESERVE, "Tagging time"}, #line 299 "frametype.gperf" {"SIGN", FRAME(SIGN), PRESERVE, "Signature frame"}, #line 355 "frametype.gperf" {"WOAS", FRAME(url), PRESERVE, "Official audio source webpage"}, #line 331 "frametype.gperf" {"TPE1", FRAME(text), PRESERVE, "Lead performer(s)/soloist(s)"}, #line 302 "frametype.gperf" {"TALB", FRAME(text), PRESERVE, "Album/movie/show title"}, #line 341 "frametype.gperf" {"TSOA", FRAME(text), PRESERVE, "Album sort order"}, #line 321 "frametype.gperf" {"TLAN", FRAME(text), PRESERVE, "Language(s)"}, #line 333 "frametype.gperf" {"TPE3", FRAME(text), PRESERVE, "Conductor/performer refinement"}, #line 352 "frametype.gperf" {"WCOP", FRAME(url), PRESERVE, "Copyright/legal information"}, #line 334 "frametype.gperf" {"TPE4", FRAME(text), PRESERVE, "Interpreted, remixed, or otherwise modified by"}, #line 323 "frametype.gperf" {"TMCL", FRAME(text), PRESERVE, "Musician credits list"}, #line 303 "frametype.gperf" {"TBPM", FRAME(text), PRESERVE, "BPM (beats per minute)"}, #line 311 "frametype.gperf" {"TDRL", FRAME(text), PRESERVE, "Release time"}, #line 326 "frametype.gperf" {"TOAL", FRAME(text), PRESERVE, "Original album/movie/show title"}, #line 342 "frametype.gperf" {"TSOP", FRAME(text), PRESERVE, "Performer sort order"}, #line 363 "frametype.gperf" {"ZOBS", FRAME(ZOBS), OBSOLETE, "Obsolete frame"}, #line 283 "frametype.gperf" {"EQU2", FRAME(EQU2), DISCARD, "Equalisation (2)"}, #line 306 "frametype.gperf" {"TCOP", FRAME(text), PRESERVE, "Copyright message"}, #line 287 "frametype.gperf" {"LINK", FRAME(LINK), PRESERVE, "Linked information"}, #line 286 "frametype.gperf" {"GRID", FRAME(GRID), PRESERVE, "Group identification registration"}, #line 294 "frametype.gperf" {"PRIV", FRAME(PRIV), PRESERVE, "Private frame"}, #line 315 "frametype.gperf" {"TFLT", FRAME(text), PRESERVE, "File type"}, #line 289 "frametype.gperf" {"MLLT", FRAME(MLLT), DISCARD, "MPEG location lookup table"}, #line 314 "frametype.gperf" {"TEXT", FRAME(text), PRESERVE, "Lyricist/text writer"}, #line 348 "frametype.gperf" {"UFID", FRAME(UFID), PRESERVE, "Unique file identifier"}, #line 278 "frametype.gperf" {"APIC", FRAME(APIC), PRESERVE, "Attached picture"}, #line 279 "frametype.gperf" {"ASPI", FRAME(ASPI), DISCARD, "Audio seek point index"}, #line 318 "frametype.gperf" {"TIT2", FRAME(text), PRESERVE, "Title/songname/content description"}, #line 359 "frametype.gperf" {"WXXX", FRAME(WXXX), PRESERVE, "User defined URL link frame"}, #line 288 "frametype.gperf" {"MCDI", FRAME(MCDI), PRESERVE, "Music CD identifier"}, #line 316 "frametype.gperf" {"TIPL", FRAME(text), PRESERVE, "Involved people list"}, #line 347 "frametype.gperf" {"TXXX", FRAME(TXXX), PRESERVE, "User defined text information frame"}, #line 295 "frametype.gperf" {"RBUF", FRAME(RBUF), PRESERVE, "Recommended buffer size"}, #line 317 "frametype.gperf" {"TIT1", FRAME(text), PRESERVE, "Content group description"}, #line 319 "frametype.gperf" {"TIT3", FRAME(text), PRESERVE, "Subtitle/description refinement"} }; static const short lookup[] = { -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 2, 3, -1, 4, -1, -1, -1, -1, 5, 6, 7, 8, -1, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, -1, 70, 71, -1, 72, 73, 74, -1, 75, -1, 76, -1, -1, -1, 77, 78, -1, -1, 79, -1, -1, -1, -1, 80, 81, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 82, -1, -1, -1, 83 }; if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) { register int key = hash (str, len); if (key <= MAX_HASH_VALUE && key >= 0) { register int index = lookup[key]; if (index >= 0) { register const char *s = wordlist[index].id; if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0') return &wordlist[index]; } } } return 0; } libid3tag-0.16.3/frametype.gperf000066400000000000000000000233041470022143500164640ustar00rootroot00000000000000%{ /* * libid3tag - ID3 tag manipulation library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: frametype.gperf,v 1.7 2004/01/23 09:41:32 rob Exp $ */ # include "global.h" # include # include "id3tag.h" # include "frametype.h" # define FIELDS(id) static enum id3_field_type const fields_##id[] /* frame field descriptions */ FIELDS(UFID) = { ID3_FIELD_TYPE_LATIN1, ID3_FIELD_TYPE_BINARYDATA }; FIELDS(TXXX) = { ID3_FIELD_TYPE_TEXTENCODING, ID3_FIELD_TYPE_STRING, ID3_FIELD_TYPE_STRING }; FIELDS(WXXX) = { ID3_FIELD_TYPE_TEXTENCODING, ID3_FIELD_TYPE_STRING, ID3_FIELD_TYPE_LATIN1 }; FIELDS(MCDI) = { ID3_FIELD_TYPE_BINARYDATA }; FIELDS(ETCO) = { ID3_FIELD_TYPE_INT8, ID3_FIELD_TYPE_BINARYDATA }; FIELDS(MLLT) = { ID3_FIELD_TYPE_INT16, ID3_FIELD_TYPE_INT24, ID3_FIELD_TYPE_INT24, ID3_FIELD_TYPE_INT8, ID3_FIELD_TYPE_INT8, ID3_FIELD_TYPE_BINARYDATA }; FIELDS(SYTC) = { ID3_FIELD_TYPE_INT8, ID3_FIELD_TYPE_BINARYDATA }; FIELDS(USLT) = { ID3_FIELD_TYPE_TEXTENCODING, ID3_FIELD_TYPE_LANGUAGE, ID3_FIELD_TYPE_STRING, ID3_FIELD_TYPE_STRINGFULL }; FIELDS(SYLT) = { ID3_FIELD_TYPE_TEXTENCODING, ID3_FIELD_TYPE_LANGUAGE, ID3_FIELD_TYPE_INT8, ID3_FIELD_TYPE_INT8, ID3_FIELD_TYPE_STRING, ID3_FIELD_TYPE_BINARYDATA }; FIELDS(COMM) = { ID3_FIELD_TYPE_TEXTENCODING, ID3_FIELD_TYPE_LANGUAGE, ID3_FIELD_TYPE_STRING, ID3_FIELD_TYPE_STRINGFULL }; FIELDS(RVA2) = { ID3_FIELD_TYPE_LATIN1, ID3_FIELD_TYPE_BINARYDATA }; FIELDS(EQU2) = { ID3_FIELD_TYPE_INT8, ID3_FIELD_TYPE_LATIN1, ID3_FIELD_TYPE_BINARYDATA }; FIELDS(RVRB) = { ID3_FIELD_TYPE_INT16, ID3_FIELD_TYPE_INT16, ID3_FIELD_TYPE_INT8, ID3_FIELD_TYPE_INT8, ID3_FIELD_TYPE_INT8, ID3_FIELD_TYPE_INT8, ID3_FIELD_TYPE_INT8, ID3_FIELD_TYPE_INT8, ID3_FIELD_TYPE_INT8, ID3_FIELD_TYPE_INT8 }; FIELDS(APIC) = { ID3_FIELD_TYPE_TEXTENCODING, ID3_FIELD_TYPE_LATIN1, ID3_FIELD_TYPE_INT8, ID3_FIELD_TYPE_STRING, ID3_FIELD_TYPE_BINARYDATA }; FIELDS(GEOB) = { ID3_FIELD_TYPE_TEXTENCODING, ID3_FIELD_TYPE_LATIN1, ID3_FIELD_TYPE_STRING, ID3_FIELD_TYPE_STRING, ID3_FIELD_TYPE_BINARYDATA }; FIELDS(PCNT) = { ID3_FIELD_TYPE_INT32PLUS }; FIELDS(POPM) = { ID3_FIELD_TYPE_LATIN1, ID3_FIELD_TYPE_INT8, ID3_FIELD_TYPE_INT32PLUS }; FIELDS(RBUF) = { ID3_FIELD_TYPE_INT24, ID3_FIELD_TYPE_INT8, ID3_FIELD_TYPE_INT32 }; FIELDS(AENC) = { ID3_FIELD_TYPE_LATIN1, ID3_FIELD_TYPE_INT16, ID3_FIELD_TYPE_INT16, ID3_FIELD_TYPE_BINARYDATA }; FIELDS(LINK) = { ID3_FIELD_TYPE_FRAMEID, ID3_FIELD_TYPE_LATIN1, ID3_FIELD_TYPE_LATIN1LIST }; FIELDS(POSS) = { ID3_FIELD_TYPE_INT8, ID3_FIELD_TYPE_BINARYDATA }; FIELDS(USER) = { ID3_FIELD_TYPE_TEXTENCODING, ID3_FIELD_TYPE_LANGUAGE, ID3_FIELD_TYPE_STRING }; FIELDS(OWNE) = { ID3_FIELD_TYPE_TEXTENCODING, ID3_FIELD_TYPE_LATIN1, ID3_FIELD_TYPE_DATE, ID3_FIELD_TYPE_STRING }; FIELDS(COMR) = { ID3_FIELD_TYPE_TEXTENCODING, ID3_FIELD_TYPE_LATIN1, ID3_FIELD_TYPE_DATE, ID3_FIELD_TYPE_LATIN1, ID3_FIELD_TYPE_INT8, ID3_FIELD_TYPE_STRING, ID3_FIELD_TYPE_STRING, ID3_FIELD_TYPE_LATIN1, ID3_FIELD_TYPE_BINARYDATA }; FIELDS(ENCR) = { ID3_FIELD_TYPE_LATIN1, ID3_FIELD_TYPE_INT8, ID3_FIELD_TYPE_BINARYDATA }; FIELDS(GRID) = { ID3_FIELD_TYPE_LATIN1, ID3_FIELD_TYPE_INT8, ID3_FIELD_TYPE_BINARYDATA }; FIELDS(PRIV) = { ID3_FIELD_TYPE_LATIN1, ID3_FIELD_TYPE_BINARYDATA }; FIELDS(SIGN) = { ID3_FIELD_TYPE_INT8, ID3_FIELD_TYPE_BINARYDATA }; FIELDS(SEEK) = { ID3_FIELD_TYPE_INT32 }; FIELDS(ASPI) = { ID3_FIELD_TYPE_INT32, ID3_FIELD_TYPE_INT32, ID3_FIELD_TYPE_INT16, ID3_FIELD_TYPE_INT8, ID3_FIELD_TYPE_BINARYDATA }; FIELDS(text) = { ID3_FIELD_TYPE_TEXTENCODING, ID3_FIELD_TYPE_STRINGLIST }; FIELDS(url) = { ID3_FIELD_TYPE_LATIN1 }; FIELDS(unknown) = { ID3_FIELD_TYPE_BINARYDATA }; FIELDS(ZOBS) = { ID3_FIELD_TYPE_FRAMEID, ID3_FIELD_TYPE_BINARYDATA }; # define FRAME(id) \ sizeof(fields_##id) / sizeof(fields_##id[0]), fields_##id # define PRESERVE 0 # define DISCARD ID3_FRAME_FLAG_FILEALTERPRESERVATION # define OBSOLETE (DISCARD | ID3_FRAME_FLAG_TAGALTERPRESERVATION) # define FRAMETYPE(type, id, flags, desc) \ struct id3_frametype const id3_frametype_##type = { \ 0, FRAME(id), flags, desc \ } /* static frame types */ FRAMETYPE(text, text, PRESERVE, "Unknown text information frame"); FRAMETYPE(url, url, PRESERVE, "Unknown URL link frame"); FRAMETYPE(experimental, unknown, PRESERVE, "Experimental frame"); FRAMETYPE(unknown, unknown, PRESERVE, "Unknown frame"); FRAMETYPE(obsolete, unknown, OBSOLETE, "Obsolete frame"); %} struct id3_frametype; %% # # ID3v2.4 frames # AENC, FRAME(AENC), DISCARD, "Audio encryption" APIC, FRAME(APIC), PRESERVE, "Attached picture" ASPI, FRAME(ASPI), DISCARD, "Audio seek point index" COMM, FRAME(COMM), PRESERVE, "Comments" COMR, FRAME(COMR), PRESERVE, "Commercial frame" ENCR, FRAME(ENCR), PRESERVE, "Encryption method registration" EQU2, FRAME(EQU2), DISCARD, "Equalisation (2)" ETCO, FRAME(ETCO), DISCARD, "Event timing codes" GEOB, FRAME(GEOB), PRESERVE, "General encapsulated object" GRID, FRAME(GRID), PRESERVE, "Group identification registration" LINK, FRAME(LINK), PRESERVE, "Linked information" MCDI, FRAME(MCDI), PRESERVE, "Music CD identifier" MLLT, FRAME(MLLT), DISCARD, "MPEG location lookup table" OWNE, FRAME(OWNE), PRESERVE, "Ownership frame" PCNT, FRAME(PCNT), PRESERVE, "Play counter" POPM, FRAME(POPM), PRESERVE, "Popularimeter" POSS, FRAME(POSS), DISCARD, "Position synchronisation frame" PRIV, FRAME(PRIV), PRESERVE, "Private frame" RBUF, FRAME(RBUF), PRESERVE, "Recommended buffer size" RVA2, FRAME(RVA2), DISCARD, "Relative volume adjustment (2)" RVRB, FRAME(RVRB), PRESERVE, "Reverb" SEEK, FRAME(SEEK), DISCARD, "Seek frame" SIGN, FRAME(SIGN), PRESERVE, "Signature frame" SYLT, FRAME(SYLT), DISCARD, "Synchronised lyric/text" SYTC, FRAME(SYTC), DISCARD, "Synchronised tempo codes" TALB, FRAME(text), PRESERVE, "Album/movie/show title" TBPM, FRAME(text), PRESERVE, "BPM (beats per minute)" TCOM, FRAME(text), PRESERVE, "Composer" TCON, FRAME(text), PRESERVE, "Content type" TCOP, FRAME(text), PRESERVE, "Copyright message" TDEN, FRAME(text), PRESERVE, "Encoding time" TDLY, FRAME(text), PRESERVE, "Playlist delay" TDOR, FRAME(text), PRESERVE, "Original release time" TDRC, FRAME(text), PRESERVE, "Recording time" TDRL, FRAME(text), PRESERVE, "Release time" TDTG, FRAME(text), PRESERVE, "Tagging time" TENC, FRAME(text), DISCARD, "Encoded by" TEXT, FRAME(text), PRESERVE, "Lyricist/text writer" TFLT, FRAME(text), PRESERVE, "File type" TIPL, FRAME(text), PRESERVE, "Involved people list" TIT1, FRAME(text), PRESERVE, "Content group description" TIT2, FRAME(text), PRESERVE, "Title/songname/content description" TIT3, FRAME(text), PRESERVE, "Subtitle/description refinement" TKEY, FRAME(text), PRESERVE, "Initial key" TLAN, FRAME(text), PRESERVE, "Language(s)" TLEN, FRAME(text), DISCARD, "Length" TMCL, FRAME(text), PRESERVE, "Musician credits list" TMED, FRAME(text), PRESERVE, "Media type" TMOO, FRAME(text), PRESERVE, "Mood" TOAL, FRAME(text), PRESERVE, "Original album/movie/show title" TOFN, FRAME(text), PRESERVE, "Original filename" TOLY, FRAME(text), PRESERVE, "Original lyricist(s)/text writer(s)" TOPE, FRAME(text), PRESERVE, "Original artist(s)/performer(s)" TOWN, FRAME(text), PRESERVE, "File owner/licensee" TPE1, FRAME(text), PRESERVE, "Lead performer(s)/soloist(s)" TPE2, FRAME(text), PRESERVE, "Band/orchestra/accompaniment" TPE3, FRAME(text), PRESERVE, "Conductor/performer refinement" TPE4, FRAME(text), PRESERVE, "Interpreted, remixed, or otherwise modified by" TPOS, FRAME(text), PRESERVE, "Part of a set" TPRO, FRAME(text), PRESERVE, "Produced notice" TPUB, FRAME(text), PRESERVE, "Publisher" TRCK, FRAME(text), PRESERVE, "Track number/position in set" TRSN, FRAME(text), PRESERVE, "Internet radio station name" TRSO, FRAME(text), PRESERVE, "Internet radio station owner" TSOA, FRAME(text), PRESERVE, "Album sort order" TSOP, FRAME(text), PRESERVE, "Performer sort order" TSOT, FRAME(text), PRESERVE, "Title sort order" TSRC, FRAME(text), PRESERVE, "ISRC (international standard recording code)" TSSE, FRAME(text), PRESERVE, "Software/hardware and settings used for encoding" TSST, FRAME(text), PRESERVE, "Set subtitle" TXXX, FRAME(TXXX), PRESERVE, "User defined text information frame" UFID, FRAME(UFID), PRESERVE, "Unique file identifier" USER, FRAME(USER), PRESERVE, "Terms of use" USLT, FRAME(USLT), PRESERVE, "Unsynchronised lyric/text transcription" WCOM, FRAME(url), PRESERVE, "Commercial information" WCOP, FRAME(url), PRESERVE, "Copyright/legal information" WOAF, FRAME(url), PRESERVE, "Official audio file webpage" WOAR, FRAME(url), PRESERVE, "Official artist/performer webpage" WOAS, FRAME(url), PRESERVE, "Official audio source webpage" WORS, FRAME(url), PRESERVE, "Official Internet radio station homepage" WPAY, FRAME(url), PRESERVE, "Payment" WPUB, FRAME(url), PRESERVE, "Publishers official webpage" WXXX, FRAME(WXXX), PRESERVE, "User defined URL link frame" # # Special frames # ZOBS, FRAME(ZOBS), OBSOLETE, "Obsolete frame" libid3tag-0.16.3/frametype.h000066400000000000000000000027211470022143500156100ustar00rootroot00000000000000/* * libid3tag - ID3 tag manipulation library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: frametype.h,v 1.7 2004/01/23 09:41:32 rob Exp $ */ # ifndef LIBID3TAG_FRAMETYPE_H # define LIBID3TAG_FRAMETYPE_H struct id3_frametype { char const *id; unsigned int nfields; enum id3_field_type const *fields; int defaultflags; char const *description; }; extern struct id3_frametype const id3_frametype_text; extern struct id3_frametype const id3_frametype_url; extern struct id3_frametype const id3_frametype_experimental; extern struct id3_frametype const id3_frametype_unknown; extern struct id3_frametype const id3_frametype_obsolete; struct id3_frametype const *id3_frametype_lookup(register char const *, register size_t); # endif libid3tag-0.16.3/genre.c000066400000000000000000000065351470022143500147160ustar00rootroot00000000000000/* * libid3tag - ID3 tag manipulation library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: genre.c,v 1.8 2004/01/23 09:41:32 rob Exp $ */ # include "global.h" # include "id3tag.h" # include "ucs4.h" /* genres are stored in ucs4 format */ # include "genre.dat" # define NGENRES (sizeof(genre_table) / sizeof(genre_table[0])) /* * NAME: genre->index() * DESCRIPTION: return an ID3v1 genre string indexed by number */ id3_ucs4_t const *id3_genre_index(unsigned int index) { return (index < NGENRES) ? genre_table[index] : 0; } /* * NAME: genre->name() * DESCRIPTION: translate an ID3v2 genre number/keyword to its full name */ id3_ucs4_t const *id3_genre_name(id3_ucs4_t const *string) { id3_ucs4_t const *ptr; static id3_ucs4_t const genre_remix[] = { 'R', 'e', 'm', 'i', 'x', 0 }; static id3_ucs4_t const genre_cover[] = { 'C', 'o', 'v', 'e', 'r', 0 }; unsigned long number; if (string == 0 || *string == 0) return id3_ucs4_empty; if (string[0] == 'R' && string[1] == 'X' && string[2] == 0) return genre_remix; if (string[0] == 'C' && string[1] == 'R' && string[2] == 0) return genre_cover; for (ptr = string; *ptr; ++ptr) { if (*ptr < '0' || *ptr > '9') return string; } number = id3_ucs4_getnumber(string); return (number < NGENRES) ? genre_table[number] : string; } /* * NAME: translate() * DESCRIPTION: return a canonicalized character for testing genre equivalence */ static id3_ucs4_t translate(id3_ucs4_t ch) { if (ch) { if (ch >= 'A' && ch <= 'Z') ch += 'a' - 'A'; if (ch < 'a' || ch > 'z') ch = ID3_UCS4_REPLACEMENTCHAR; } return ch; } /* * NAME: compare() * DESCRIPTION: test two ucs4 genre strings for equivalence */ static int compare(id3_ucs4_t const *str1, id3_ucs4_t const *str2) { id3_ucs4_t c1, c2; if (str1 == str2) return 1; do { do c1 = translate(*str1++); while (c1 == ID3_UCS4_REPLACEMENTCHAR); do c2 = translate(*str2++); while (c2 == ID3_UCS4_REPLACEMENTCHAR); } while (c1 && c1 == c2); return c1 == c2; } /* * NAME: genre->number() * DESCRIPTION: translate an ID3v2 genre name/number to its ID3v1 index number */ int id3_genre_number(id3_ucs4_t const *string) { id3_ucs4_t const *ptr; int i; if (string == 0 || *string == 0) return -1; for (ptr = string; *ptr; ++ptr) { if (*ptr < '0' || *ptr > '9') break; } if (*ptr == 0) { unsigned long number; number = id3_ucs4_getnumber(string); return (number <= 0xff) ? number : -1; } for (i = 0; i < NGENRES; ++i) { if (compare(string, genre_table[i])) return i; } /* no equivalent */ return -1; } libid3tag-0.16.3/genre.dat000066400000000000000000000422011470022143500152320ustar00rootroot00000000000000/* Automatically generated from genre.dat.in */ /* * libid3tag - ID3 tag manipulation library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Id: genre.dat.in,v 1.7 2004/01/23 09:41:32 rob Exp */ /* * These are the ID3 genre names, taken as a combination of names from ID3v1 * (listed in Appendix A of the ID3 tag version 2.4.0 informal standard) and * the extensions made by Winamp as of version 2.80. */ /* ID3v1 names (0-79) */ static id3_ucs4_t const genre_BLUES[] = { 'B', 'l', 'u', 'e', 's', 0 }; static id3_ucs4_t const genre_CLASSIC_ROCK[] = { 'C', 'l', 'a', 's', 's', 'i', 'c', ' ', 'R', 'o', 'c', 'k', 0 }; static id3_ucs4_t const genre_COUNTRY[] = { 'C', 'o', 'u', 'n', 't', 'r', 'y', 0 }; static id3_ucs4_t const genre_DANCE[] = { 'D', 'a', 'n', 'c', 'e', 0 }; static id3_ucs4_t const genre_DISCO[] = { 'D', 'i', 's', 'c', 'o', 0 }; static id3_ucs4_t const genre_FUNK[] = { 'F', 'u', 'n', 'k', 0 }; static id3_ucs4_t const genre_GRUNGE[] = { 'G', 'r', 'u', 'n', 'g', 'e', 0 }; static id3_ucs4_t const genre_HIP_HOP[] = { 'H', 'i', 'p', '-', 'H', 'o', 'p', 0 }; static id3_ucs4_t const genre_JAZZ[] = { 'J', 'a', 'z', 'z', 0 }; static id3_ucs4_t const genre_METAL[] = { 'M', 'e', 't', 'a', 'l', 0 }; static id3_ucs4_t const genre_NEW_AGE[] = { 'N', 'e', 'w', ' ', 'A', 'g', 'e', 0 }; static id3_ucs4_t const genre_OLDIES[] = { 'O', 'l', 'd', 'i', 'e', 's', 0 }; static id3_ucs4_t const genre_OTHER[] = { 'O', 't', 'h', 'e', 'r', 0 }; static id3_ucs4_t const genre_POP[] = { 'P', 'o', 'p', 0 }; static id3_ucs4_t const genre_R_B[] = { 'R', '&', 'B', 0 }; static id3_ucs4_t const genre_RAP[] = { 'R', 'a', 'p', 0 }; static id3_ucs4_t const genre_REGGAE[] = { 'R', 'e', 'g', 'g', 'a', 'e', 0 }; static id3_ucs4_t const genre_ROCK[] = { 'R', 'o', 'c', 'k', 0 }; static id3_ucs4_t const genre_TECHNO[] = { 'T', 'e', 'c', 'h', 'n', 'o', 0 }; static id3_ucs4_t const genre_INDUSTRIAL[] = { 'I', 'n', 'd', 'u', 's', 't', 'r', 'i', 'a', 'l', 0 }; static id3_ucs4_t const genre_ALTERNATIVE[] = { 'A', 'l', 't', 'e', 'r', 'n', 'a', 't', 'i', 'v', 'e', 0 }; static id3_ucs4_t const genre_SKA[] = { 'S', 'k', 'a', 0 }; static id3_ucs4_t const genre_DEATH_METAL[] = { 'D', 'e', 'a', 't', 'h', ' ', 'M', 'e', 't', 'a', 'l', 0 }; static id3_ucs4_t const genre_PRANKS[] = { 'P', 'r', 'a', 'n', 'k', 's', 0 }; static id3_ucs4_t const genre_SOUNDTRACK[] = { 'S', 'o', 'u', 'n', 'd', 't', 'r', 'a', 'c', 'k', 0 }; static id3_ucs4_t const genre_EURO_TECHNO[] = { 'E', 'u', 'r', 'o', '-', 'T', 'e', 'c', 'h', 'n', 'o', 0 }; static id3_ucs4_t const genre_AMBIENT[] = { 'A', 'm', 'b', 'i', 'e', 'n', 't', 0 }; static id3_ucs4_t const genre_TRIP_HOP[] = { 'T', 'r', 'i', 'p', '-', 'H', 'o', 'p', 0 }; static id3_ucs4_t const genre_VOCAL[] = { 'V', 'o', 'c', 'a', 'l', 0 }; static id3_ucs4_t const genre_JAZZ_FUNK[] = { 'J', 'a', 'z', 'z', '+', 'F', 'u', 'n', 'k', 0 }; static id3_ucs4_t const genre_FUSION[] = { 'F', 'u', 's', 'i', 'o', 'n', 0 }; static id3_ucs4_t const genre_TRANCE[] = { 'T', 'r', 'a', 'n', 'c', 'e', 0 }; static id3_ucs4_t const genre_CLASSICAL[] = { 'C', 'l', 'a', 's', 's', 'i', 'c', 'a', 'l', 0 }; static id3_ucs4_t const genre_INSTRUMENTAL[] = { 'I', 'n', 's', 't', 'r', 'u', 'm', 'e', 'n', 't', 'a', 'l', 0 }; static id3_ucs4_t const genre_ACID[] = { 'A', 'c', 'i', 'd', 0 }; static id3_ucs4_t const genre_HOUSE[] = { 'H', 'o', 'u', 's', 'e', 0 }; static id3_ucs4_t const genre_GAME[] = { 'G', 'a', 'm', 'e', 0 }; static id3_ucs4_t const genre_SOUND_CLIP[] = { 'S', 'o', 'u', 'n', 'd', ' ', 'C', 'l', 'i', 'p', 0 }; static id3_ucs4_t const genre_GOSPEL[] = { 'G', 'o', 's', 'p', 'e', 'l', 0 }; static id3_ucs4_t const genre_NOISE[] = { 'N', 'o', 'i', 's', 'e', 0 }; static id3_ucs4_t const genre_ALTERNROCK[] = { 'A', 'l', 't', 'e', 'r', 'n', 'R', 'o', 'c', 'k', 0 }; static id3_ucs4_t const genre_BASS[] = { 'B', 'a', 's', 's', 0 }; static id3_ucs4_t const genre_SOUL[] = { 'S', 'o', 'u', 'l', 0 }; static id3_ucs4_t const genre_PUNK[] = { 'P', 'u', 'n', 'k', 0 }; static id3_ucs4_t const genre_SPACE[] = { 'S', 'p', 'a', 'c', 'e', 0 }; static id3_ucs4_t const genre_MEDITATIVE[] = { 'M', 'e', 'd', 'i', 't', 'a', 't', 'i', 'v', 'e', 0 }; static id3_ucs4_t const genre_INSTRUMENTAL_POP[] = { 'I', 'n', 's', 't', 'r', 'u', 'm', 'e', 'n', 't', 'a', 'l', ' ', 'P', 'o', 'p', 0 }; static id3_ucs4_t const genre_INSTRUMENTAL_ROCK[] = { 'I', 'n', 's', 't', 'r', 'u', 'm', 'e', 'n', 't', 'a', 'l', ' ', 'R', 'o', 'c', 'k', 0 }; static id3_ucs4_t const genre_ETHNIC[] = { 'E', 't', 'h', 'n', 'i', 'c', 0 }; static id3_ucs4_t const genre_GOTHIC[] = { 'G', 'o', 't', 'h', 'i', 'c', 0 }; static id3_ucs4_t const genre_DARKWAVE[] = { 'D', 'a', 'r', 'k', 'w', 'a', 'v', 'e', 0 }; static id3_ucs4_t const genre_TECHNO_INDUSTRIAL[] = { 'T', 'e', 'c', 'h', 'n', 'o', '-', 'I', 'n', 'd', 'u', 's', 't', 'r', 'i', 'a', 'l', 0 }; static id3_ucs4_t const genre_ELECTRONIC[] = { 'E', 'l', 'e', 'c', 't', 'r', 'o', 'n', 'i', 'c', 0 }; static id3_ucs4_t const genre_POP_FOLK[] = { 'P', 'o', 'p', '-', 'F', 'o', 'l', 'k', 0 }; static id3_ucs4_t const genre_EURODANCE[] = { 'E', 'u', 'r', 'o', 'd', 'a', 'n', 'c', 'e', 0 }; static id3_ucs4_t const genre_DREAM[] = { 'D', 'r', 'e', 'a', 'm', 0 }; static id3_ucs4_t const genre_SOUTHERN_ROCK[] = { 'S', 'o', 'u', 't', 'h', 'e', 'r', 'n', ' ', 'R', 'o', 'c', 'k', 0 }; static id3_ucs4_t const genre_COMEDY[] = { 'C', 'o', 'm', 'e', 'd', 'y', 0 }; static id3_ucs4_t const genre_CULT[] = { 'C', 'u', 'l', 't', 0 }; static id3_ucs4_t const genre_GANGSTA[] = { 'G', 'a', 'n', 'g', 's', 't', 'a', 0 }; static id3_ucs4_t const genre_TOP_40[] = { 'T', 'o', 'p', ' ', '4', '0', 0 }; static id3_ucs4_t const genre_CHRISTIAN_RAP[] = { 'C', 'h', 'r', 'i', 's', 't', 'i', 'a', 'n', ' ', 'R', 'a', 'p', 0 }; static id3_ucs4_t const genre_POP_FUNK[] = { 'P', 'o', 'p', '/', 'F', 'u', 'n', 'k', 0 }; static id3_ucs4_t const genre_JUNGLE[] = { 'J', 'u', 'n', 'g', 'l', 'e', 0 }; static id3_ucs4_t const genre_NATIVE_AMERICAN[] = { 'N', 'a', 't', 'i', 'v', 'e', ' ', 'A', 'm', 'e', 'r', 'i', 'c', 'a', 'n', 0 }; static id3_ucs4_t const genre_CABARET[] = { 'C', 'a', 'b', 'a', 'r', 'e', 't', 0 }; static id3_ucs4_t const genre_NEW_WAVE[] = { 'N', 'e', 'w', ' ', 'W', 'a', 'v', 'e', 0 }; static id3_ucs4_t const genre_PSYCHEDELIC[] = { 'P', 's', 'y', 'c', 'h', 'e', 'd', 'e', 'l', 'i', 'c', 0 }; static id3_ucs4_t const genre_RAVE[] = { 'R', 'a', 'v', 'e', 0 }; static id3_ucs4_t const genre_SHOWTUNES[] = { 'S', 'h', 'o', 'w', 't', 'u', 'n', 'e', 's', 0 }; static id3_ucs4_t const genre_TRAILER[] = { 'T', 'r', 'a', 'i', 'l', 'e', 'r', 0 }; static id3_ucs4_t const genre_LO_FI[] = { 'L', 'o', '-', 'F', 'i', 0 }; static id3_ucs4_t const genre_TRIBAL[] = { 'T', 'r', 'i', 'b', 'a', 'l', 0 }; static id3_ucs4_t const genre_ACID_PUNK[] = { 'A', 'c', 'i', 'd', ' ', 'P', 'u', 'n', 'k', 0 }; static id3_ucs4_t const genre_ACID_JAZZ[] = { 'A', 'c', 'i', 'd', ' ', 'J', 'a', 'z', 'z', 0 }; static id3_ucs4_t const genre_POLKA[] = { 'P', 'o', 'l', 'k', 'a', 0 }; static id3_ucs4_t const genre_RETRO[] = { 'R', 'e', 't', 'r', 'o', 0 }; static id3_ucs4_t const genre_MUSICAL[] = { 'M', 'u', 's', 'i', 'c', 'a', 'l', 0 }; static id3_ucs4_t const genre_ROCK___ROLL[] = { 'R', 'o', 'c', 'k', ' ', '&', ' ', 'R', 'o', 'l', 'l', 0 }; static id3_ucs4_t const genre_HARD_ROCK[] = { 'H', 'a', 'r', 'd', ' ', 'R', 'o', 'c', 'k', 0 }; /* Winamp extensions (80-147) */ static id3_ucs4_t const genre_FOLK[] = { 'F', 'o', 'l', 'k', 0 }; static id3_ucs4_t const genre_FOLK_ROCK[] = { 'F', 'o', 'l', 'k', '/', 'R', 'o', 'c', 'k', 0 }; static id3_ucs4_t const genre_NATIONAL_FOLK[] = { 'N', 'a', 't', 'i', 'o', 'n', 'a', 'l', ' ', 'F', 'o', 'l', 'k', 0 }; static id3_ucs4_t const genre_SWING[] = { 'S', 'w', 'i', 'n', 'g', 0 }; static id3_ucs4_t const genre_FAST_FUSION[] = { 'F', 'a', 's', 't', '-', 'F', 'u', 's', 'i', 'o', 'n', 0 }; static id3_ucs4_t const genre_BEBOB[] = { 'B', 'e', 'b', 'o', 'b', 0 }; static id3_ucs4_t const genre_LATIN[] = { 'L', 'a', 't', 'i', 'n', 0 }; static id3_ucs4_t const genre_REVIVAL[] = { 'R', 'e', 'v', 'i', 'v', 'a', 'l', 0 }; static id3_ucs4_t const genre_CELTIC[] = { 'C', 'e', 'l', 't', 'i', 'c', 0 }; static id3_ucs4_t const genre_BLUEGRASS[] = { 'B', 'l', 'u', 'e', 'g', 'r', 'a', 's', 's', 0 }; static id3_ucs4_t const genre_AVANTGARDE[] = { 'A', 'v', 'a', 'n', 't', 'g', 'a', 'r', 'd', 'e', 0 }; static id3_ucs4_t const genre_GOTHIC_ROCK[] = { 'G', 'o', 't', 'h', 'i', 'c', ' ', 'R', 'o', 'c', 'k', 0 }; static id3_ucs4_t const genre_PROGRESSIVE_ROCK[] = { 'P', 'r', 'o', 'g', 'r', 'e', 's', 's', 'i', 'v', 'e', ' ', 'R', 'o', 'c', 'k', 0 }; static id3_ucs4_t const genre_PSYCHEDELIC_ROCK[] = { 'P', 's', 'y', 'c', 'h', 'e', 'd', 'e', 'l', 'i', 'c', ' ', 'R', 'o', 'c', 'k', 0 }; static id3_ucs4_t const genre_SYMPHONIC_ROCK[] = { 'S', 'y', 'm', 'p', 'h', 'o', 'n', 'i', 'c', ' ', 'R', 'o', 'c', 'k', 0 }; static id3_ucs4_t const genre_SLOW_ROCK[] = { 'S', 'l', 'o', 'w', ' ', 'R', 'o', 'c', 'k', 0 }; static id3_ucs4_t const genre_BIG_BAND[] = { 'B', 'i', 'g', ' ', 'B', 'a', 'n', 'd', 0 }; static id3_ucs4_t const genre_CHORUS[] = { 'C', 'h', 'o', 'r', 'u', 's', 0 }; static id3_ucs4_t const genre_EASY_LISTENING[] = { 'E', 'a', 's', 'y', ' ', 'L', 'i', 's', 't', 'e', 'n', 'i', 'n', 'g', 0 }; static id3_ucs4_t const genre_ACOUSTIC[] = { 'A', 'c', 'o', 'u', 's', 't', 'i', 'c', 0 }; static id3_ucs4_t const genre_HUMOUR[] = { 'H', 'u', 'm', 'o', 'u', 'r', 0 }; static id3_ucs4_t const genre_SPEECH[] = { 'S', 'p', 'e', 'e', 'c', 'h', 0 }; static id3_ucs4_t const genre_CHANSON[] = { 'C', 'h', 'a', 'n', 's', 'o', 'n', 0 }; static id3_ucs4_t const genre_OPERA[] = { 'O', 'p', 'e', 'r', 'a', 0 }; static id3_ucs4_t const genre_CHAMBER_MUSIC[] = { 'C', 'h', 'a', 'm', 'b', 'e', 'r', ' ', 'M', 'u', 's', 'i', 'c', 0 }; static id3_ucs4_t const genre_SONATA[] = { 'S', 'o', 'n', 'a', 't', 'a', 0 }; static id3_ucs4_t const genre_SYMPHONY[] = { 'S', 'y', 'm', 'p', 'h', 'o', 'n', 'y', 0 }; static id3_ucs4_t const genre_BOOTY_BASS[] = { 'B', 'o', 'o', 't', 'y', ' ', 'B', 'a', 's', 's', 0 }; static id3_ucs4_t const genre_PRIMUS[] = { 'P', 'r', 'i', 'm', 'u', 's', 0 }; static id3_ucs4_t const genre_PORN_GROOVE[] = { 'P', 'o', 'r', 'n', ' ', 'G', 'r', 'o', 'o', 'v', 'e', 0 }; static id3_ucs4_t const genre_SATIRE[] = { 'S', 'a', 't', 'i', 'r', 'e', 0 }; static id3_ucs4_t const genre_SLOW_JAM[] = { 'S', 'l', 'o', 'w', ' ', 'J', 'a', 'm', 0 }; static id3_ucs4_t const genre_CLUB[] = { 'C', 'l', 'u', 'b', 0 }; static id3_ucs4_t const genre_TANGO[] = { 'T', 'a', 'n', 'g', 'o', 0 }; static id3_ucs4_t const genre_SAMBA[] = { 'S', 'a', 'm', 'b', 'a', 0 }; static id3_ucs4_t const genre_FOLKLORE[] = { 'F', 'o', 'l', 'k', 'l', 'o', 'r', 'e', 0 }; static id3_ucs4_t const genre_BALLAD[] = { 'B', 'a', 'l', 'l', 'a', 'd', 0 }; static id3_ucs4_t const genre_POWER_BALLAD[] = { 'P', 'o', 'w', 'e', 'r', ' ', 'B', 'a', 'l', 'l', 'a', 'd', 0 }; static id3_ucs4_t const genre_RHYTHMIC_SOUL[] = { 'R', 'h', 'y', 't', 'h', 'm', 'i', 'c', ' ', 'S', 'o', 'u', 'l', 0 }; static id3_ucs4_t const genre_FREESTYLE[] = { 'F', 'r', 'e', 'e', 's', 't', 'y', 'l', 'e', 0 }; static id3_ucs4_t const genre_DUET[] = { 'D', 'u', 'e', 't', 0 }; static id3_ucs4_t const genre_PUNK_ROCK[] = { 'P', 'u', 'n', 'k', ' ', 'R', 'o', 'c', 'k', 0 }; static id3_ucs4_t const genre_DRUM_SOLO[] = { 'D', 'r', 'u', 'm', ' ', 'S', 'o', 'l', 'o', 0 }; static id3_ucs4_t const genre_A_CAPELLA[] = { 'A', ' ', 'C', 'a', 'p', 'e', 'l', 'l', 'a', 0 }; static id3_ucs4_t const genre_EURO_HOUSE[] = { 'E', 'u', 'r', 'o', '-', 'H', 'o', 'u', 's', 'e', 0 }; static id3_ucs4_t const genre_DANCE_HALL[] = { 'D', 'a', 'n', 'c', 'e', ' ', 'H', 'a', 'l', 'l', 0 }; static id3_ucs4_t const genre_GOA[] = { 'G', 'o', 'a', 0 }; static id3_ucs4_t const genre_DRUM___BASS[] = { 'D', 'r', 'u', 'm', ' ', '&', ' ', 'B', 'a', 's', 's', 0 }; static id3_ucs4_t const genre_CLUB_HOUSE[] = { 'C', 'l', 'u', 'b', '-', 'H', 'o', 'u', 's', 'e', 0 }; static id3_ucs4_t const genre_HARDCORE[] = { 'H', 'a', 'r', 'd', 'c', 'o', 'r', 'e', 0 }; static id3_ucs4_t const genre_TERROR[] = { 'T', 'e', 'r', 'r', 'o', 'r', 0 }; static id3_ucs4_t const genre_INDIE[] = { 'I', 'n', 'd', 'i', 'e', 0 }; static id3_ucs4_t const genre_BRITPOP[] = { 'B', 'r', 'i', 't', 'P', 'o', 'p', 0 }; static id3_ucs4_t const genre_NEGERPUNK[] = { 'N', 'e', 'g', 'e', 'r', 'p', 'u', 'n', 'k', 0 }; static id3_ucs4_t const genre_POLSK_PUNK[] = { 'P', 'o', 'l', 's', 'k', ' ', 'P', 'u', 'n', 'k', 0 }; static id3_ucs4_t const genre_BEAT[] = { 'B', 'e', 'a', 't', 0 }; static id3_ucs4_t const genre_CHRISTIAN_GANGSTA_RAP[] = { 'C', 'h', 'r', 'i', 's', 't', 'i', 'a', 'n', ' ', 'G', 'a', 'n', 'g', 's', 't', 'a', ' ', 'R', 'a', 'p', 0 }; static id3_ucs4_t const genre_HEAVY_METAL[] = { 'H', 'e', 'a', 'v', 'y', ' ', 'M', 'e', 't', 'a', 'l', 0 }; static id3_ucs4_t const genre_BLACK_METAL[] = { 'B', 'l', 'a', 'c', 'k', ' ', 'M', 'e', 't', 'a', 'l', 0 }; static id3_ucs4_t const genre_CROSSOVER[] = { 'C', 'r', 'o', 's', 's', 'o', 'v', 'e', 'r', 0 }; static id3_ucs4_t const genre_CONTEMPORARY_CHRISTIAN[] = { 'C', 'o', 'n', 't', 'e', 'm', 'p', 'o', 'r', 'a', 'r', 'y', ' ', 'C', 'h', 'r', 'i', 's', 't', 'i', 'a', 'n', 0 }; static id3_ucs4_t const genre_CHRISTIAN_ROCK[] = { 'C', 'h', 'r', 'i', 's', 't', 'i', 'a', 'n', ' ', 'R', 'o', 'c', 'k', 0 }; static id3_ucs4_t const genre_MERENGUE[] = { 'M', 'e', 'r', 'e', 'n', 'g', 'u', 'e', 0 }; static id3_ucs4_t const genre_SALSA[] = { 'S', 'a', 'l', 's', 'a', 0 }; static id3_ucs4_t const genre_THRASH_METAL[] = { 'T', 'h', 'r', 'a', 's', 'h', ' ', 'M', 'e', 't', 'a', 'l', 0 }; static id3_ucs4_t const genre_ANIME[] = { 'A', 'n', 'i', 'm', 'e', 0 }; static id3_ucs4_t const genre_JPOP[] = { 'J', 'P', 'o', 'p', 0 }; static id3_ucs4_t const genre_SYNTHPOP[] = { 'S', 'y', 'n', 't', 'h', 'p', 'o', 'p', 0 }; static id3_ucs4_t const *const genre_table[] = { genre_BLUES, genre_CLASSIC_ROCK, genre_COUNTRY, genre_DANCE, genre_DISCO, genre_FUNK, genre_GRUNGE, genre_HIP_HOP, genre_JAZZ, genre_METAL, genre_NEW_AGE, genre_OLDIES, genre_OTHER, genre_POP, genre_R_B, genre_RAP, genre_REGGAE, genre_ROCK, genre_TECHNO, genre_INDUSTRIAL, genre_ALTERNATIVE, genre_SKA, genre_DEATH_METAL, genre_PRANKS, genre_SOUNDTRACK, genre_EURO_TECHNO, genre_AMBIENT, genre_TRIP_HOP, genre_VOCAL, genre_JAZZ_FUNK, genre_FUSION, genre_TRANCE, genre_CLASSICAL, genre_INSTRUMENTAL, genre_ACID, genre_HOUSE, genre_GAME, genre_SOUND_CLIP, genre_GOSPEL, genre_NOISE, genre_ALTERNROCK, genre_BASS, genre_SOUL, genre_PUNK, genre_SPACE, genre_MEDITATIVE, genre_INSTRUMENTAL_POP, genre_INSTRUMENTAL_ROCK, genre_ETHNIC, genre_GOTHIC, genre_DARKWAVE, genre_TECHNO_INDUSTRIAL, genre_ELECTRONIC, genre_POP_FOLK, genre_EURODANCE, genre_DREAM, genre_SOUTHERN_ROCK, genre_COMEDY, genre_CULT, genre_GANGSTA, genre_TOP_40, genre_CHRISTIAN_RAP, genre_POP_FUNK, genre_JUNGLE, genre_NATIVE_AMERICAN, genre_CABARET, genre_NEW_WAVE, genre_PSYCHEDELIC, genre_RAVE, genre_SHOWTUNES, genre_TRAILER, genre_LO_FI, genre_TRIBAL, genre_ACID_PUNK, genre_ACID_JAZZ, genre_POLKA, genre_RETRO, genre_MUSICAL, genre_ROCK___ROLL, genre_HARD_ROCK, genre_FOLK, genre_FOLK_ROCK, genre_NATIONAL_FOLK, genre_SWING, genre_FAST_FUSION, genre_BEBOB, genre_LATIN, genre_REVIVAL, genre_CELTIC, genre_BLUEGRASS, genre_AVANTGARDE, genre_GOTHIC_ROCK, genre_PROGRESSIVE_ROCK, genre_PSYCHEDELIC_ROCK, genre_SYMPHONIC_ROCK, genre_SLOW_ROCK, genre_BIG_BAND, genre_CHORUS, genre_EASY_LISTENING, genre_ACOUSTIC, genre_HUMOUR, genre_SPEECH, genre_CHANSON, genre_OPERA, genre_CHAMBER_MUSIC, genre_SONATA, genre_SYMPHONY, genre_BOOTY_BASS, genre_PRIMUS, genre_PORN_GROOVE, genre_SATIRE, genre_SLOW_JAM, genre_CLUB, genre_TANGO, genre_SAMBA, genre_FOLKLORE, genre_BALLAD, genre_POWER_BALLAD, genre_RHYTHMIC_SOUL, genre_FREESTYLE, genre_DUET, genre_PUNK_ROCK, genre_DRUM_SOLO, genre_A_CAPELLA, genre_EURO_HOUSE, genre_DANCE_HALL, genre_GOA, genre_DRUM___BASS, genre_CLUB_HOUSE, genre_HARDCORE, genre_TERROR, genre_INDIE, genre_BRITPOP, genre_NEGERPUNK, genre_POLSK_PUNK, genre_BEAT, genre_CHRISTIAN_GANGSTA_RAP, genre_HEAVY_METAL, genre_BLACK_METAL, genre_CROSSOVER, genre_CONTEMPORARY_CHRISTIAN, genre_CHRISTIAN_ROCK, genre_MERENGUE, genre_SALSA, genre_THRASH_METAL, genre_ANIME, genre_JPOP, genre_SYNTHPOP }; libid3tag-0.16.3/genre.dat.in000066400000000000000000000046731470022143500156520ustar00rootroot00000000000000/* * libid3tag - ID3 tag manipulation library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: genre.dat.in,v 1.7 2004/01/23 09:41:32 rob Exp $ */ /* * These are the ID3 genre names, taken as a combination of names from ID3v1 * (listed in Appendix A of the ID3 tag version 2.4.0 informal standard) and * the extensions made by Winamp as of version 2.80. */ /* ID3v1 names (0-79) */ 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 AlternRock 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 /* Winamp extensions (80-147) */ Folk Folk/Rock National Folk Swing Fast-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 libid3tag-0.16.3/genre.dat.sed000066400000000000000000000026031470022143500160060ustar00rootroot00000000000000# # libid3tag - ID3 tag manipulation library # Copyright (C) 2000-2004 Underbit Technologies, Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # $Id: genre.dat.sed,v 1.10 2004/01/23 09:41:32 rob Exp $ # 1i\ /* Automatically generated from genre.dat.in */ # generate an array from a string /^[A-Za-z]/{ H y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/ s/[^A-Z0-9]/_/g s/.*/static id3_ucs4_t const genre_&[] =/p g s/.*\n// s/./'&', /g s/.*/ { &0 };/ } # write the final table of arrays ${ p i\ \ static id3_ucs4_t const *const genre_table[] = { g s/^\(\n\)\(.*\)$/\2\1/ y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/ s/[^A-Z0-9\n]/_/g s/\([^\n]*\)\(\n\)/ genre_\1,\2/g s/,\n$// a\ }; } # print the pattern space (assumes -n) p libid3tag-0.16.3/genre.h000066400000000000000000000017131470022143500147140ustar00rootroot00000000000000/* * libid3tag - ID3 tag manipulation library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: genre.h,v 1.6 2004/01/23 09:41:32 rob Exp $ */ # ifndef LIBID3TAG_GENRE_H # define LIBID3TAG_GENRE_H # define ID3_GENRE_OTHER 12 # endif libid3tag-0.16.3/global.h000066400000000000000000000033241470022143500150540ustar00rootroot00000000000000/* * libid3tag - ID3 tag manipulation library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: global.h,v 1.9 2004/01/23 09:41:32 rob Exp $ */ # ifndef LIBID3TAG_GLOBAL_H # define LIBID3TAG_GLOBAL_H /* conditional debugging */ # if defined(DEBUG) && defined(NDEBUG) # error "cannot define both DEBUG and NDEBUG" # endif # if defined(DEBUG) # include # include "debug.h" # define malloc(sz) id3_debug_malloc(sz, __FILE__, __LINE__) # define calloc(n, sz) id3_debug_calloc(n, sz, __FILE__, __LINE__) # define realloc(ptr, sz) id3_debug_realloc(ptr, sz, __FILE__, __LINE__) # define free(ptr) id3_debug_free(ptr, __FILE__, __LINE__) # define release(ptr) id3_debug_release(ptr, __FILE__, __LINE__) # else # define release(ptr) (ptr) # endif /* conditional features */ # if !defined(HAVE_ASSERT_H) # if defined(NDEBUG) # define assert(x) /* nothing */ # else # define assert(x) do { if (!(x)) abort(); } while (0) # endif # endif # endif libid3tag-0.16.3/id3tag.h.in000066400000000000000000000247551470022143500154070ustar00rootroot00000000000000/* * libid3tag - ID3 tag manipulation library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * If you would like to negotiate alternate licensing terms, you may do * so by contacting: Underbit Technologies, Inc. * * $Id: id3tag.h,v 1.17 2004/01/23 23:22:46 rob Exp $ */ # ifndef LIBID3TAG_ID3TAG_H # define LIBID3TAG_ID3TAG_H #include # ifdef __cplusplus extern "C" { # endif # define ID3_TAG_VERSION 0x0400 # define ID3_TAG_VERSION_MAJOR(x) (((x) >> 8) & 0xff) # define ID3_TAG_VERSION_MINOR(x) (((x) >> 0) & 0xff) typedef unsigned char id3_byte_t; typedef unsigned long id3_length_t; typedef uint32_t id3_ucs4_t; typedef unsigned char id3_latin1_t; typedef uint16_t id3_utf16_t; typedef signed char id3_utf8_t; struct id3_tag { unsigned int refcount; unsigned int version; int flags; int extendedflags; int restrictions; int options; unsigned int nframes; struct id3_frame **frames; id3_length_t paddedsize; }; # define ID3_TAG_QUERYSIZE 10 /* ID3v1 field frames */ # define ID3_FRAME_TITLE "TIT2" # define ID3_FRAME_ARTIST "TPE1" # define ID3_FRAME_ALBUM "TALB" # define ID3_FRAME_TRACK "TRCK" # define ID3_FRAME_YEAR "TDRC" # define ID3_FRAME_GENRE "TCON" # define ID3_FRAME_COMMENT "COMM" /* special frames */ # define ID3_FRAME_OBSOLETE "ZOBS" /* with apologies to the French */ /* tag flags */ enum { ID3_TAG_FLAG_UNSYNCHRONISATION = 0x80, ID3_TAG_FLAG_EXTENDEDHEADER = 0x40, ID3_TAG_FLAG_EXPERIMENTALINDICATOR = 0x20, ID3_TAG_FLAG_FOOTERPRESENT = 0x10, ID3_TAG_FLAG_KNOWNFLAGS = 0xf0 }; /* tag extended flags */ enum { ID3_TAG_EXTENDEDFLAG_TAGISANUPDATE = 0x40, ID3_TAG_EXTENDEDFLAG_CRCDATAPRESENT = 0x20, ID3_TAG_EXTENDEDFLAG_TAGRESTRICTIONS = 0x10, ID3_TAG_EXTENDEDFLAG_KNOWNFLAGS = 0x70 }; /* tag restrictions */ enum { ID3_TAG_RESTRICTION_TAGSIZE_MASK = 0xc0, ID3_TAG_RESTRICTION_TAGSIZE_128_FRAMES_1_MB = 0x00, ID3_TAG_RESTRICTION_TAGSIZE_64_FRAMES_128_KB = 0x40, ID3_TAG_RESTRICTION_TAGSIZE_32_FRAMES_40_KB = 0x80, ID3_TAG_RESTRICTION_TAGSIZE_32_FRAMES_4_KB = 0xc0 }; enum { ID3_TAG_RESTRICTION_TEXTENCODING_MASK = 0x20, ID3_TAG_RESTRICTION_TEXTENCODING_NONE = 0x00, ID3_TAG_RESTRICTION_TEXTENCODING_LATIN1_UTF8 = 0x20 }; enum { ID3_TAG_RESTRICTION_TEXTSIZE_MASK = 0x18, ID3_TAG_RESTRICTION_TEXTSIZE_NONE = 0x00, ID3_TAG_RESTRICTION_TEXTSIZE_1024_CHARS = 0x08, ID3_TAG_RESTRICTION_TEXTSIZE_128_CHARS = 0x10, ID3_TAG_RESTRICTION_TEXTSIZE_30_CHARS = 0x18 }; enum { ID3_TAG_RESTRICTION_IMAGEENCODING_MASK = 0x04, ID3_TAG_RESTRICTION_IMAGEENCODING_NONE = 0x00, ID3_TAG_RESTRICTION_IMAGEENCODING_PNG_JPEG = 0x04 }; enum { ID3_TAG_RESTRICTION_IMAGESIZE_MASK = 0x03, ID3_TAG_RESTRICTION_IMAGESIZE_NONE = 0x00, ID3_TAG_RESTRICTION_IMAGESIZE_256_256 = 0x01, ID3_TAG_RESTRICTION_IMAGESIZE_64_64 = 0x02, ID3_TAG_RESTRICTION_IMAGESIZE_64_64_EXACT = 0x03 }; /* library options */ enum { ID3_TAG_OPTION_UNSYNCHRONISATION = 0x0001, /* use unsynchronisation */ ID3_TAG_OPTION_COMPRESSION = 0x0002, /* use compression */ ID3_TAG_OPTION_CRC = 0x0004, /* use CRC */ ID3_TAG_OPTION_APPENDEDTAG = 0x0010, /* tag will be appended */ ID3_TAG_OPTION_FILEALTERED = 0x0020, /* audio data was altered */ ID3_TAG_OPTION_ID3V1 = 0x0100 /* render ID3v1/ID3v1.1 tag */ }; struct id3_frame { char id[5]; char const *description; unsigned int refcount; int flags; int group_id; int encryption_method; id3_byte_t *encoded; id3_length_t encoded_length; id3_length_t decoded_length; unsigned int nfields; union id3_field *fields; }; enum { /* frame status flags */ ID3_FRAME_FLAG_TAGALTERPRESERVATION = 0x4000, ID3_FRAME_FLAG_FILEALTERPRESERVATION = 0x2000, ID3_FRAME_FLAG_READONLY = 0x1000, ID3_FRAME_FLAG_STATUSFLAGS = 0xff00, /* frame format flags */ ID3_FRAME_FLAG_GROUPINGIDENTITY = 0x0040, ID3_FRAME_FLAG_COMPRESSION = 0x0008, ID3_FRAME_FLAG_ENCRYPTION = 0x0004, ID3_FRAME_FLAG_UNSYNCHRONISATION = 0x0002, ID3_FRAME_FLAG_DATALENGTHINDICATOR = 0x0001, ID3_FRAME_FLAG_FORMATFLAGS = 0x00ff, ID3_FRAME_FLAG_KNOWNFLAGS = 0x704f }; enum id3_field_type { ID3_FIELD_TYPE_TEXTENCODING, ID3_FIELD_TYPE_LATIN1, ID3_FIELD_TYPE_LATIN1FULL, ID3_FIELD_TYPE_LATIN1LIST, ID3_FIELD_TYPE_STRING, ID3_FIELD_TYPE_STRINGFULL, ID3_FIELD_TYPE_STRINGLIST, ID3_FIELD_TYPE_LANGUAGE, ID3_FIELD_TYPE_FRAMEID, ID3_FIELD_TYPE_DATE, ID3_FIELD_TYPE_INT8, ID3_FIELD_TYPE_INT16, ID3_FIELD_TYPE_INT24, ID3_FIELD_TYPE_INT32, ID3_FIELD_TYPE_INT32PLUS, ID3_FIELD_TYPE_BINARYDATA }; enum id3_field_textencoding { ID3_FIELD_TEXTENCODING_ISO_8859_1 = 0x00, ID3_FIELD_TEXTENCODING_UTF_16 = 0x01, ID3_FIELD_TEXTENCODING_UTF_16BE = 0x02, ID3_FIELD_TEXTENCODING_UTF_8 = 0x03 }; union id3_field { enum id3_field_type type; struct { enum id3_field_type type; signed long value; } number; struct { enum id3_field_type type; id3_latin1_t *ptr; } latin1; struct { enum id3_field_type type; unsigned int nstrings; id3_latin1_t **strings; } latin1list; struct { enum id3_field_type type; id3_ucs4_t *ptr; } string; struct { enum id3_field_type type; unsigned int nstrings; id3_ucs4_t **strings; } stringlist; struct { enum id3_field_type type; char value[9]; } immediate; struct { enum id3_field_type type; id3_byte_t *data; id3_length_t length; } binary; }; /* file interface */ enum id3_file_mode { ID3_FILE_MODE_READONLY = 0, ID3_FILE_MODE_READWRITE }; struct id3_file *id3_file_open(char const *, enum id3_file_mode); struct id3_file *id3_file_fdopen(int, enum id3_file_mode); int id3_file_close(struct id3_file *); struct id3_tag *id3_file_tag(struct id3_file const *); int id3_file_update(struct id3_file *); /* tag interface */ struct id3_tag *id3_tag_new(void); void id3_tag_delete(struct id3_tag *); unsigned int id3_tag_version(struct id3_tag const *); int id3_tag_options(struct id3_tag *, int, int); void id3_tag_setlength(struct id3_tag *, id3_length_t); void id3_tag_clearframes(struct id3_tag *); int id3_tag_attachframe(struct id3_tag *, struct id3_frame *); int id3_tag_detachframe(struct id3_tag *, struct id3_frame *); struct id3_frame *id3_tag_findframe(struct id3_tag const *, char const *, unsigned int); signed long id3_tag_query(id3_byte_t const *, id3_length_t); struct id3_tag *id3_tag_parse(id3_byte_t const *, id3_length_t); id3_length_t id3_tag_render(struct id3_tag const *, id3_byte_t *); /* frame interface */ struct id3_frame *id3_frame_new(char const *); void id3_frame_delete(struct id3_frame *); union id3_field *id3_frame_field(struct id3_frame const *, unsigned int); /* field interface */ enum id3_field_type id3_field_type(union id3_field const *); int id3_field_setint(union id3_field *, signed long); int id3_field_settextencoding(union id3_field *, enum id3_field_textencoding); int id3_field_setstrings(union id3_field *, unsigned int, id3_ucs4_t **); int id3_field_addstring(union id3_field *, id3_ucs4_t const *); int id3_field_setlanguage(union id3_field *, char const *); int id3_field_setlatin1(union id3_field *, id3_latin1_t const *); int id3_field_setfulllatin1(union id3_field *, id3_latin1_t const *); int id3_field_setstring(union id3_field *, id3_ucs4_t const *); int id3_field_setfullstring(union id3_field *, id3_ucs4_t const *); int id3_field_setframeid(union id3_field *, char const *); int id3_field_setbinarydata(union id3_field *, id3_byte_t const *, id3_length_t); signed long id3_field_getint(union id3_field const *); enum id3_field_textencoding id3_field_gettextencoding(union id3_field const *); id3_latin1_t const *id3_field_getlatin1(union id3_field const *); id3_latin1_t const *id3_field_getfulllatin1(union id3_field const *); id3_ucs4_t const *id3_field_getstring(union id3_field const *); id3_ucs4_t const *id3_field_getfullstring(union id3_field const *); unsigned int id3_field_getnstrings(union id3_field const *); id3_ucs4_t const *id3_field_getstrings(union id3_field const *, unsigned int); char const *id3_field_getframeid(union id3_field const *); id3_byte_t const *id3_field_getbinarydata(union id3_field const *, id3_length_t *); /* genre interface */ id3_ucs4_t const *id3_genre_index(unsigned int); id3_ucs4_t const *id3_genre_name(id3_ucs4_t const *); int id3_genre_number(id3_ucs4_t const *); /* ucs4 interface */ id3_latin1_t *id3_ucs4_latin1duplicate(id3_ucs4_t const *); id3_utf16_t *id3_ucs4_utf16duplicate(id3_ucs4_t const *); id3_utf8_t *id3_ucs4_utf8duplicate(id3_ucs4_t const *); void id3_ucs4_putnumber(id3_ucs4_t *, unsigned long); unsigned long id3_ucs4_getnumber(id3_ucs4_t const *); /* latin1/utf16/utf8 interfaces */ id3_ucs4_t *id3_latin1_ucs4duplicate(id3_latin1_t const *); id3_ucs4_t *id3_utf16_ucs4duplicate(id3_utf16_t const *); id3_ucs4_t *id3_utf8_ucs4duplicate(id3_utf8_t const *); /* version interface */ # define ID3_VERSION_MAJOR @CMAKE_PROJECT_VERSION_MAJOR@ # define ID3_VERSION_MINOR @CMAKE_PROJECT_VERSION_MINOR@ # define ID3_VERSION_PATCH @CMAKE_PROJECT_VERSION_PATCH@ # define ID3_VERSION_EXTRA "" # define ID3_VERSION_STRINGIZE(str) #str # define ID3_VERSION_STRING(num) ID3_VERSION_STRINGIZE(num) # define ID3_VERSION ID3_VERSION_STRING(ID3_VERSION_MAJOR) "." \ ID3_VERSION_STRING(ID3_VERSION_MINOR) "." \ ID3_VERSION_STRING(ID3_VERSION_PATCH) \ ID3_VERSION_EXTRA # define ID3_PUBLISHYEAR "2000-2004" # define ID3_AUTHOR "Underbit Technologies, Inc." # define ID3_EMAIL "info@underbit.com" extern char const id3_version[]; extern char const id3_copyright[]; extern char const id3_author[]; extern char const id3_build[]; # ifdef __cplusplus } # endif # endif libid3tag-0.16.3/latin1.c000066400000000000000000000112171470022143500147770ustar00rootroot00000000000000/* * libid3tag - ID3 tag manipulation library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: latin1.c,v 1.10 2004/01/23 09:41:32 rob Exp $ */ # include "global.h" # include # include "id3tag.h" # include "latin1.h" # include "ucs4.h" /* * NAME: latin1->length() * DESCRIPTION: return the number of ucs4 chars represented by a latin1 string */ id3_length_t id3_latin1_length(id3_latin1_t const *latin1) { id3_latin1_t const *ptr = latin1; while (*ptr) ++ptr; return ptr - latin1; } /* * NAME: latin1->size() * DESCRIPTION: return the encoding size of a latin1 string */ id3_length_t id3_latin1_size(id3_latin1_t const *latin1) { return id3_latin1_length(latin1) + 1; } /* * NAME: latin1->copy() * DESCRIPTION: copy a latin1 string */ void id3_latin1_copy(id3_latin1_t *dest, id3_latin1_t const *src) { while ((*dest++ = *src++)) ; } /* * NAME: latin1->duplicate() * DESCRIPTION: duplicate a latin1 string */ id3_latin1_t *id3_latin1_duplicate(id3_latin1_t const *src) { id3_latin1_t *latin1; latin1 = malloc(id3_latin1_size(src) * sizeof(*latin1)); if (latin1) id3_latin1_copy(latin1, src); return latin1; } /* * NAME: latin1->ucs4duplicate() * DESCRIPTION: duplicate and decode a latin1 string into ucs4 */ id3_ucs4_t *id3_latin1_ucs4duplicate(id3_latin1_t const *latin1) { id3_ucs4_t *ucs4; ucs4 = malloc((id3_latin1_length(latin1) + 1) * sizeof(*ucs4)); if (ucs4) id3_latin1_decode(latin1, ucs4); return release(ucs4); } /* * NAME: latin1->decodechar() * DESCRIPTION: decode a (single) latin1 char into a single ucs4 char */ id3_length_t id3_latin1_decodechar(id3_latin1_t const *latin1, id3_ucs4_t *ucs4) { *ucs4 = *latin1; return 1; } /* * NAME: latin1->encodechar() * DESCRIPTION: encode a single ucs4 char into a (single) latin1 char */ id3_length_t id3_latin1_encodechar(id3_latin1_t *latin1, id3_ucs4_t ucs4) { *latin1 = ucs4; if (ucs4 > 0x000000ffL) *latin1 = ID3_UCS4_REPLACEMENTCHAR; return 1; } /* * NAME: latin1->decode() * DESCRIPTION: decode a complete latin1 string into a ucs4 string */ void id3_latin1_decode(id3_latin1_t const *latin1, id3_ucs4_t *ucs4) { do latin1 += id3_latin1_decodechar(latin1, ucs4); while (*ucs4++); } /* * NAME: latin1->encode() * DESCRIPTION: encode a complete ucs4 string into a latin1 string */ void id3_latin1_encode(id3_latin1_t *latin1, id3_ucs4_t const *ucs4) { do latin1 += id3_latin1_encodechar(latin1, *ucs4); while (*ucs4++); } /* * NAME: latin1->put() * DESCRIPTION: serialize a single latin1 character */ id3_length_t id3_latin1_put(id3_byte_t **ptr, id3_latin1_t latin1) { if (ptr) *(*ptr)++ = latin1; return 1; } /* * NAME: latin1->get() * DESCRIPTION: deserialize a single latin1 character */ id3_latin1_t id3_latin1_get(id3_byte_t const **ptr) { return *(*ptr)++; } /* * NAME: latin1->serialize() * DESCRIPTION: serialize a ucs4 string using latin1 encoding */ id3_length_t id3_latin1_serialize(id3_byte_t **ptr, id3_ucs4_t const *ucs4, int terminate) { id3_length_t size = 0; id3_latin1_t latin1[1], *out; while (*ucs4) { switch (id3_latin1_encodechar(out = latin1, *ucs4++)) { case 1: size += id3_latin1_put(ptr, *out++); case 0: break; } } if (terminate) size += id3_latin1_put(ptr, 0); return size; } /* * NAME: latin1->deserialize() * DESCRIPTION: deserialize a ucs4 string using latin1 encoding */ id3_ucs4_t *id3_latin1_deserialize(id3_byte_t const **ptr, id3_length_t length) { id3_byte_t const *end; id3_latin1_t *latin1ptr, *latin1; id3_ucs4_t *ucs4; end = *ptr + length; latin1 = malloc((length + 1) * sizeof(*latin1)); if (latin1 == 0) return 0; latin1ptr = latin1; while (end - *ptr > 0 && (*latin1ptr = id3_latin1_get(ptr))) ++latin1ptr; *latin1ptr = 0; ucs4 = malloc((id3_latin1_length(latin1) + 1) * sizeof(*ucs4)); if (ucs4) id3_latin1_decode(latin1, ucs4); free(latin1); return ucs4; } libid3tag-0.16.3/latin1.h000066400000000000000000000032521470022143500150040ustar00rootroot00000000000000/* * libid3tag - ID3 tag manipulation library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: latin1.h,v 1.8 2004/01/23 09:41:32 rob Exp $ */ # ifndef LIBID3TAG_LATIN1_H # define LIBID3TAG_LATIN1_H # include "id3tag.h" id3_length_t id3_latin1_length(id3_latin1_t const *); id3_length_t id3_latin1_size(id3_latin1_t const *); void id3_latin1_copy(id3_latin1_t *, id3_latin1_t const *); id3_latin1_t *id3_latin1_duplicate(id3_latin1_t const *); id3_length_t id3_latin1_decodechar(id3_latin1_t const *, id3_ucs4_t *); id3_length_t id3_latin1_encodechar(id3_latin1_t *, id3_ucs4_t); void id3_latin1_decode(id3_latin1_t const *, id3_ucs4_t *); void id3_latin1_encode(id3_latin1_t *, id3_ucs4_t const *); id3_length_t id3_latin1_put(id3_byte_t **, id3_latin1_t); id3_latin1_t id3_latin1_get(id3_byte_t const **); id3_length_t id3_latin1_serialize(id3_byte_t **, id3_ucs4_t const *, int); id3_ucs4_t *id3_latin1_deserialize(id3_byte_t const **, id3_length_t); # endif libid3tag-0.16.3/libid3tag.list.in000066400000000000000000000011061470022143500166030ustar00rootroot00000000000000# @configure_input@ # Directories... $prefix=@prefix@ $exec_prefix=@exec_prefix@ $srcdir=@srcdir@ # Product information %product @PACKAGE@ %copyright GPL %vendor Underbit Technologies, Inc. %license @srcdir@/COPYING %readme @srcdir@/README %description libid3tag is an ID3 tag manipulation library. %version @VERSION@ %packager Giuseppe "Cowo" Corbelli %system all f 0755 root root @libdir@/libid3tag.la .libs/libid3tag.lai f 0644 root root @libdir@/libid3tag.a .libs/libid3tag.a f 0644 root root @includedir@/id3tag.h @srcdir@/id3tag.h libid3tag-0.16.3/packaging/000077500000000000000000000000001470022143500153655ustar00rootroot00000000000000libid3tag-0.16.3/packaging/id3tag.pc.in000066400000000000000000000004651470022143500174760ustar00rootroot00000000000000prefix=@CMAKE_INSTALL_PREFIX@ includedir=${prefix}/include libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@ Name: libid3tag Description: ID3 tag manipulation library for MP3 files Version: @CMAKE_PROJECT_VERSION@ URL: https://codeberg.org/tenacityteam/libid3tag Libs: -L${libdir} -lid3tag -lz Cflags: -I${includedir} libid3tag-0.16.3/packaging/id3tagConfig.cmake.in000066400000000000000000000002451470022143500212760ustar00rootroot00000000000000@PACKAGE_INIT@ include("${CMAKE_CURRENT_LIST_DIR}/id3tagTargets.cmake") include(CMakeFindDependencyMacro) find_dependency(ZLIB) check_required_components(id3tag) libid3tag-0.16.3/parse.c000066400000000000000000000105321470022143500147200ustar00rootroot00000000000000/* * libid3tag - ID3 tag manipulation library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: parse.c,v 1.9 2004/01/23 09:41:32 rob Exp $ */ # include "global.h" # ifdef HAVE_ASSERT_H # include # endif # include # include # include "id3tag.h" # include "parse.h" # include "latin1.h" # include "utf16.h" # include "utf8.h" signed long id3_parse_int(id3_byte_t const **ptr, unsigned int bytes) { signed long value = 0; assert(bytes >= 1 && bytes <= 4); if (**ptr & 0x80) value = ~0; switch (bytes) { case 4: value = (value << 8) | *(*ptr)++; case 3: value = (value << 8) | *(*ptr)++; case 2: value = (value << 8) | *(*ptr)++; case 1: value = (value << 8) | *(*ptr)++; } return value; } unsigned long id3_parse_uint(id3_byte_t const **ptr, unsigned int bytes) { unsigned long value = 0; assert(bytes >= 1 && bytes <= 4); switch (bytes) { case 4: value = (value << 8) | *(*ptr)++; case 3: value = (value << 8) | *(*ptr)++; case 2: value = (value << 8) | *(*ptr)++; case 1: value = (value << 8) | *(*ptr)++; } return value; } unsigned long id3_parse_syncsafe(id3_byte_t const **ptr, unsigned int bytes) { unsigned long value = 0; assert(bytes == 4 || bytes == 5); switch (bytes) { case 5: value = (value << 4) | (*(*ptr)++ & 0x0f); case 4: value = (value << 7) | (*(*ptr)++ & 0x7f); value = (value << 7) | (*(*ptr)++ & 0x7f); value = (value << 7) | (*(*ptr)++ & 0x7f); value = (value << 7) | (*(*ptr)++ & 0x7f); } return value; } void id3_parse_immediate(id3_byte_t const **ptr, unsigned int bytes, char *value) { assert(value); assert(bytes == 8 || bytes == 4 || bytes == 3); switch (bytes) { case 8: *value++ = *(*ptr)++; *value++ = *(*ptr)++; *value++ = *(*ptr)++; *value++ = *(*ptr)++; case 4: *value++ = *(*ptr)++; case 3: *value++ = *(*ptr)++; *value++ = *(*ptr)++; *value++ = *(*ptr)++; } *value = 0; } id3_latin1_t *id3_parse_latin1(id3_byte_t const **ptr, id3_length_t length, int full) { id3_byte_t const *end; int terminated = 0; id3_latin1_t *latin1; end = memchr(*ptr, 0, length); if (end == 0) end = *ptr + length; else { length = end - *ptr; terminated = 1; } latin1 = malloc(length + 1); if (latin1) { memcpy(latin1, *ptr, length); latin1[length] = 0; if (!full) { id3_latin1_t *check; for (check = latin1; *check; ++check) { if (*check == '\n') *check = ' '; } } } *ptr += length + terminated; return latin1; } id3_ucs4_t *id3_parse_string(id3_byte_t const **ptr, id3_length_t length, enum id3_field_textencoding encoding, int full) { id3_ucs4_t *ucs4 = 0; enum id3_utf16_byteorder byteorder = ID3_UTF16_BYTEORDER_ANY; switch (encoding) { case ID3_FIELD_TEXTENCODING_ISO_8859_1: ucs4 = id3_latin1_deserialize(ptr, length); break; case ID3_FIELD_TEXTENCODING_UTF_16BE: byteorder = ID3_UTF16_BYTEORDER_BE; case ID3_FIELD_TEXTENCODING_UTF_16: ucs4 = id3_utf16_deserialize(ptr, length, byteorder); break; case ID3_FIELD_TEXTENCODING_UTF_8: ucs4 = id3_utf8_deserialize(ptr, length); break; default: /* FIXME: Unknown encoding! Print warning? */ return NULL; } if (ucs4 && !full) { id3_ucs4_t *check; for (check = ucs4; *check; ++check) { if (*check == '\n') *check = ' '; } } return ucs4; } id3_byte_t *id3_parse_binary(id3_byte_t const **ptr, id3_length_t length) { id3_byte_t *data; if (length == 0) return malloc(1); data = malloc(length); if (data) memcpy(data, *ptr, length); *ptr += length; return data; } libid3tag-0.16.3/parse.h000066400000000000000000000026531470022143500147320ustar00rootroot00000000000000/* * libid3tag - ID3 tag manipulation library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: parse.h,v 1.6 2004/01/23 09:41:32 rob Exp $ */ # ifndef LIBID3TAG_PARSE_H # define LIBID3TAG_PARSE_H signed long id3_parse_int(id3_byte_t const **, unsigned int); unsigned long id3_parse_uint(id3_byte_t const **, unsigned int); unsigned long id3_parse_syncsafe(id3_byte_t const **, unsigned int); void id3_parse_immediate(id3_byte_t const **, unsigned int, char *); id3_latin1_t *id3_parse_latin1(id3_byte_t const **, id3_length_t, int); id3_ucs4_t *id3_parse_string(id3_byte_t const **, id3_length_t, enum id3_field_textencoding, int); id3_byte_t *id3_parse_binary(id3_byte_t const **, id3_length_t); # endif libid3tag-0.16.3/render.c000066400000000000000000000103711470022143500150660ustar00rootroot00000000000000/* * libid3tag - ID3 tag manipulation library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: render.c,v 1.11 2004/01/23 09:41:32 rob Exp $ */ # include "global.h" # include # include # ifdef HAVE_ASSERT_H # include # endif # include "id3tag.h" # include "render.h" # include "ucs4.h" # include "latin1.h" # include "utf16.h" # include "utf8.h" id3_length_t id3_render_immediate(id3_byte_t **ptr, char const *value, unsigned int bytes) { assert(value); assert(bytes == 8 || bytes == 4 || bytes == 3); if (ptr) { switch (bytes) { case 8: *(*ptr)++ = *value++; *(*ptr)++ = *value++; *(*ptr)++ = *value++; *(*ptr)++ = *value++; case 4: *(*ptr)++ = *value++; case 3: *(*ptr)++ = *value++; *(*ptr)++ = *value++; *(*ptr)++ = *value++; } } return bytes; } id3_length_t id3_render_syncsafe(id3_byte_t **ptr, unsigned long num, unsigned int bytes) { assert(bytes == 4 || bytes == 5); if (ptr) { switch (bytes) { case 5: *(*ptr)++ = (num >> 28) & 0x0f; case 4: *(*ptr)++ = (num >> 21) & 0x7f; *(*ptr)++ = (num >> 14) & 0x7f; *(*ptr)++ = (num >> 7) & 0x7f; *(*ptr)++ = (num >> 0) & 0x7f; } } return bytes; } id3_length_t id3_render_int(id3_byte_t **ptr, signed long num, unsigned int bytes) { assert(bytes >= 1 && bytes <= 4); if (ptr) { switch (bytes) { case 4: *(*ptr)++ = num >> 24; case 3: *(*ptr)++ = num >> 16; case 2: *(*ptr)++ = num >> 8; case 1: *(*ptr)++ = num >> 0; } } return bytes; } id3_length_t id3_render_binary(id3_byte_t **ptr, id3_byte_t const *data, id3_length_t length) { if (data == 0) return 0; if (ptr) { memcpy(*ptr, data, length); *ptr += length; } return length; } id3_length_t id3_render_latin1(id3_byte_t **ptr, id3_latin1_t const *latin1, int terminate) { id3_length_t size; if (latin1 == 0) latin1 = ""; size = id3_latin1_size(latin1); if (!terminate) --size; if (ptr) { memcpy(*ptr, latin1, size); *ptr += size; } return size; } id3_length_t id3_render_string(id3_byte_t **ptr, id3_ucs4_t const *ucs4, enum id3_field_textencoding encoding, int terminate) { enum id3_utf16_byteorder byteorder = ID3_UTF16_BYTEORDER_ANY; if (ucs4 == 0) ucs4 = id3_ucs4_empty; switch (encoding) { case ID3_FIELD_TEXTENCODING_ISO_8859_1: return id3_latin1_serialize(ptr, ucs4, terminate); case ID3_FIELD_TEXTENCODING_UTF_16BE: byteorder = ID3_UTF16_BYTEORDER_BE; case ID3_FIELD_TEXTENCODING_UTF_16: return id3_utf16_serialize(ptr, ucs4, byteorder, terminate); case ID3_FIELD_TEXTENCODING_UTF_8: return id3_utf8_serialize(ptr, ucs4, terminate); } return 0; } id3_length_t id3_render_padding(id3_byte_t **ptr, id3_byte_t value, id3_length_t length) { if (ptr) { memset(*ptr, value, length); *ptr += length; } return length; } /* * NAME: render->paddedstring() * DESCRIPTION: render a space-padded string using latin1 encoding */ id3_length_t id3_render_paddedstring(id3_byte_t **ptr, id3_ucs4_t const *ucs4, id3_length_t length) { id3_ucs4_t padded[31], *data, *end; /* latin1 encoding only (this is used for ID3v1 fields) */ assert(length <= 30); data = padded; end = data + length; if (ucs4) { while (*ucs4 && end - data > 0) *data++ = *ucs4++; } *data = 0; id3_latin1_serialize(ptr, padded, 0); if (end - data > 0) id3_render_padding(ptr, 0, end - data); return length; } libid3tag-0.16.3/render.h000066400000000000000000000031511470022143500150710ustar00rootroot00000000000000/* * libid3tag - ID3 tag manipulation library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: render.h,v 1.7 2004/01/23 09:41:32 rob Exp $ */ # ifndef LIBID3TAG_RENDER_H # define LIBID3TAG_RENDER_H # include "id3tag.h" id3_length_t id3_render_immediate(id3_byte_t **, char const *, unsigned int); id3_length_t id3_render_syncsafe(id3_byte_t **, unsigned long, unsigned int); id3_length_t id3_render_int(id3_byte_t **, signed long, unsigned int); id3_length_t id3_render_binary(id3_byte_t **, id3_byte_t const *, id3_length_t); id3_length_t id3_render_latin1(id3_byte_t **, id3_latin1_t const *, int); id3_length_t id3_render_string(id3_byte_t **, id3_ucs4_t const *, enum id3_field_textencoding, int); id3_length_t id3_render_padding(id3_byte_t **, id3_byte_t, id3_length_t); id3_length_t id3_render_paddedstring(id3_byte_t **, id3_ucs4_t const *, id3_length_t); # endif libid3tag-0.16.3/tag.c000066400000000000000000000454101470022143500143640ustar00rootroot00000000000000/* * libid3tag - ID3 tag manipulation library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: tag.c,v 1.20 2004/02/17 02:04:10 rob Exp $ */ # include "global.h" # include # include # ifdef HAVE_ASSERT_H # include # endif # include "id3tag.h" # include "tag.h" # include "frame.h" # include "compat.h" # include "parse.h" # include "render.h" # include "latin1.h" # include "ucs4.h" # include "genre.h" # include "crc.h" # include "field.h" # include "util.h" /* * NAME: tag->new() * DESCRIPTION: allocate and return a new, empty tag */ struct id3_tag *id3_tag_new(void) { struct id3_tag *tag; tag = malloc(sizeof(*tag)); if (tag) { tag->refcount = 0; tag->version = ID3_TAG_VERSION; tag->flags = 0; tag->extendedflags = 0; tag->restrictions = 0; tag->options = /* ID3_TAG_OPTION_UNSYNCHRONISATION | */ ID3_TAG_OPTION_COMPRESSION | ID3_TAG_OPTION_CRC; tag->nframes = 0; tag->frames = 0; tag->paddedsize = 0; } return tag; } /* * NAME: tag->delete() * DESCRIPTION: destroy a tag and deallocate all associated memory */ void id3_tag_delete(struct id3_tag *tag) { assert(tag); if (tag->refcount == 0) { id3_tag_clearframes(tag); if (tag->frames) free(tag->frames); free(tag); } } /* * NAME: tag->addref() * DESCRIPTION: add an external reference to a tag */ void id3_tag_addref(struct id3_tag *tag) { assert(tag); ++tag->refcount; } /* * NAME: tag->delref() * DESCRIPTION: remove an external reference to a tag */ void id3_tag_delref(struct id3_tag *tag) { assert(tag && tag->refcount > 0); --tag->refcount; } /* * NAME: tag->version() * DESCRIPTION: return the tag's original ID3 version number */ unsigned int id3_tag_version(struct id3_tag const *tag) { assert(tag); return tag->version; } /* * NAME: tag->options() * DESCRIPTION: get or set tag options */ int id3_tag_options(struct id3_tag *tag, int mask, int values) { assert(tag); if (mask) tag->options = (tag->options & ~mask) | (values & mask); return tag->options; } /* * NAME: tag->setlength() * DESCRIPTION: set the minimum rendered tag size */ void id3_tag_setlength(struct id3_tag *tag, id3_length_t length) { assert(tag); tag->paddedsize = length; } /* * NAME: tag->clearframes() * DESCRIPTION: detach and delete all frames associated with a tag */ void id3_tag_clearframes(struct id3_tag *tag) { unsigned int i; assert(tag); for (i = 0; i < tag->nframes; ++i) { id3_frame_delref(tag->frames[i]); id3_frame_delete(tag->frames[i]); } tag->nframes = 0; } /* * NAME: tag->attachframe() * DESCRIPTION: attach a frame to a tag */ int id3_tag_attachframe(struct id3_tag *tag, struct id3_frame *frame) { struct id3_frame **frames; assert(tag && frame); frames = realloc(tag->frames, (tag->nframes + 1) * sizeof(*frames)); if (frames == 0) return -1; tag->frames = frames; tag->frames[tag->nframes++] = frame; id3_frame_addref(frame); return 0; } /* * NAME: tag->detachframe() * DESCRIPTION: detach (but don't delete) a frame from a tag */ int id3_tag_detachframe(struct id3_tag *tag, struct id3_frame *frame) { unsigned int i; assert(tag && frame); for (i = 0; i < tag->nframes; ++i) { if (tag->frames[i] == frame) break; } if (i == tag->nframes) return -1; --tag->nframes; while (i++ < tag->nframes) tag->frames[i - 1] = tag->frames[i]; id3_frame_delref(frame); return 0; } /* * NAME: tag->findframe() * DESCRIPTION: find in a tag the nth (0-based) frame with the given frame ID */ struct id3_frame *id3_tag_findframe(struct id3_tag const *tag, char const *id, unsigned int index) { unsigned int len, i; assert(tag); if (id == 0 || *id == 0) return (index < tag->nframes) ? tag->frames[index] : 0; len = strlen(id); if (len == 4) { struct id3_compat const *compat; compat = id3_compat_lookup(id, len); if (compat && compat->equiv && !compat->translate) { id = compat->equiv; len = strlen(id); } } for (i = 0; i < tag->nframes; ++i) { if (strncmp(tag->frames[i]->id, id, len) == 0 && index-- == 0) return tag->frames[i]; } return 0; } enum tagtype { TAGTYPE_NONE = 0, TAGTYPE_ID3V1, TAGTYPE_ID3V2, TAGTYPE_ID3V2_FOOTER }; static enum tagtype tagtype(id3_byte_t const *data, id3_length_t length) { if (length >= 3 && data[0] == 'T' && data[1] == 'A' && data[2] == 'G') return TAGTYPE_ID3V1; if (length >= 10 && ((data[0] == 'I' && data[1] == 'D' && data[2] == '3') || (data[0] == '3' && data[1] == 'D' && data[2] == 'I')) && data[3] < 0xff && data[4] < 0xff && data[6] < 0x80 && data[7] < 0x80 && data[8] < 0x80 && data[9] < 0x80) return data[0] == 'I' ? TAGTYPE_ID3V2 : TAGTYPE_ID3V2_FOOTER; return TAGTYPE_NONE; } static void parse_header(id3_byte_t const **ptr, unsigned int *version, int *flags, id3_length_t *size) { *ptr += 3; *version = id3_parse_uint(ptr, 2); *flags = id3_parse_uint(ptr, 1); *size = id3_parse_syncsafe(ptr, 4); } /* * NAME: tag->query() * DESCRIPTION: if a tag begins at the given location, return its size */ signed long id3_tag_query(id3_byte_t const *data, id3_length_t length) { unsigned int version; int flags; id3_length_t size; assert(data); switch (tagtype(data, length)) { case TAGTYPE_ID3V1: return 128; case TAGTYPE_ID3V2: parse_header(&data, &version, &flags, &size); if (flags & ID3_TAG_FLAG_FOOTERPRESENT) size += 10; return 10 + size; case TAGTYPE_ID3V2_FOOTER: parse_header(&data, &version, &flags, &size); return -size - 10; case TAGTYPE_NONE: break; } return 0; } static void trim(char *str) { char *ptr; ptr = str + strlen(str); while (ptr > str && ptr[-1] == ' ') --ptr; *ptr = 0; } static int v1_attachstr(struct id3_tag *tag, char const *id, char *text, unsigned long number) { struct id3_frame *frame; id3_ucs4_t ucs4[31]; if (text) { trim(text); if (*text == 0) return 0; } frame = id3_frame_new(id); if (frame == 0) return -1; if (id3_field_settextencoding(&frame->fields[0], ID3_FIELD_TEXTENCODING_ISO_8859_1) == -1) goto fail; if (text) id3_latin1_decode(text, ucs4); else id3_ucs4_putnumber(ucs4, number); if (strcmp(id, ID3_FRAME_COMMENT) == 0) { if (id3_field_setlanguage(&frame->fields[1], "XXX") == -1 || id3_field_setstring(&frame->fields[2], id3_ucs4_empty) == -1 || id3_field_setfullstring(&frame->fields[3], ucs4) == -1) goto fail; } else { id3_ucs4_t *ptr = ucs4; if (id3_field_setstrings(&frame->fields[1], 1, &ptr) == -1) goto fail; } if (id3_tag_attachframe(tag, frame) == -1) goto fail; return 0; fail: id3_frame_delete(frame); return -1; } static struct id3_tag *v1_parse(id3_byte_t const *data) { struct id3_tag *tag; tag = id3_tag_new(); if (tag) { char title[31], artist[31], album[31], year[5], comment[31]; unsigned int genre, track; tag->version = 0x0100; tag->options |= ID3_TAG_OPTION_ID3V1; tag->options &= ~ID3_TAG_OPTION_COMPRESSION; tag->restrictions = ID3_TAG_RESTRICTION_TEXTENCODING_LATIN1_UTF8 | ID3_TAG_RESTRICTION_TEXTSIZE_30_CHARS; title[30] = artist[30] = album[30] = year[4] = comment[30] = 0; memcpy(title, &data[3], 30); memcpy(artist, &data[33], 30); memcpy(album, &data[63], 30); memcpy(year, &data[93], 4); memcpy(comment, &data[97], 30); genre = data[127]; track = 0; if (comment[28] == 0 && comment[29] != 0) { track = comment[29]; tag->version = 0x0101; } /* populate tag frames */ if (v1_attachstr(tag, ID3_FRAME_TITLE, title, 0) == -1 || v1_attachstr(tag, ID3_FRAME_ARTIST, artist, 0) == -1 || v1_attachstr(tag, ID3_FRAME_ALBUM, album, 0) == -1 || v1_attachstr(tag, ID3_FRAME_YEAR, year, 0) == -1 || (track && v1_attachstr(tag, ID3_FRAME_TRACK, 0, track) == -1) || (genre < 0xff && v1_attachstr(tag, ID3_FRAME_GENRE, 0, genre) == -1) || v1_attachstr(tag, ID3_FRAME_COMMENT, comment, 0) == -1) { id3_tag_delete(tag); tag = 0; } } return tag; } static struct id3_tag *v2_parse(id3_byte_t const *ptr) { struct id3_tag *tag; id3_byte_t *mem = 0; tag = id3_tag_new(); if (tag) { id3_byte_t const *end; id3_length_t size; parse_header(&ptr, &tag->version, &tag->flags, &size); tag->paddedsize = 10 + size; if ((tag->flags & ID3_TAG_FLAG_UNSYNCHRONISATION) && ID3_TAG_VERSION_MAJOR(tag->version) < 4) { mem = malloc(size); if (mem == 0) goto fail; memcpy(mem, ptr, size); size = id3_util_deunsynchronise(mem, size); ptr = mem; } end = ptr + size; if (tag->flags & ID3_TAG_FLAG_EXTENDEDHEADER) { switch (ID3_TAG_VERSION_MAJOR(tag->version)) { case 2: goto fail; case 3: { id3_byte_t const *ehptr, *ehend; id3_length_t ehsize; enum { EH_FLAG_CRC = 0x8000 /* CRC data present */ }; if (end - ptr < 4) goto fail; ehsize = id3_parse_uint(&ptr, 4); if (ehsize > end - ptr) goto fail; ehptr = ptr; ehend = ptr + ehsize; ptr = ehend; if (ehend - ehptr >= 6) { int ehflags; id3_length_t padsize; ehflags = id3_parse_uint(&ehptr, 2); padsize = id3_parse_uint(&ehptr, 4); if (padsize > end - ptr) goto fail; end -= padsize; if (ehflags & EH_FLAG_CRC) { unsigned long crc; if (ehend - ehptr < 4) goto fail; crc = id3_parse_uint(&ehptr, 4); if (crc != id3_crc_compute(ptr, end - ptr)) goto fail; tag->extendedflags |= ID3_TAG_EXTENDEDFLAG_CRCDATAPRESENT; } } } break; case 4: { id3_byte_t const *ehptr, *ehend; id3_length_t ehsize; unsigned int bytes; if (end - ptr < 4) goto fail; ehptr = ptr; ehsize = id3_parse_syncsafe(&ptr, 4); if (ehsize < 6 || ehsize > end - ehptr) goto fail; ehend = ehptr + ehsize; bytes = id3_parse_uint(&ptr, 1); if (bytes < 1 || bytes > ehend - ptr) goto fail; ehptr = ptr + bytes; /* verify extended header size */ { id3_byte_t const *flagsptr = ptr, *dataptr = ehptr; unsigned int datalen; int ehflags; while (bytes--) { for (ehflags = id3_parse_uint(&flagsptr, 1); ehflags; ehflags = (ehflags << 1) & 0xff) { if (ehflags & 0x80) { if (dataptr == ehend) goto fail; datalen = id3_parse_uint(&dataptr, 1); if (datalen > 0x7f || datalen > ehend - dataptr) goto fail; dataptr += datalen; } } } } tag->extendedflags = id3_parse_uint(&ptr, 1); ptr = ehend; if (tag->extendedflags & ID3_TAG_EXTENDEDFLAG_TAGISANUPDATE) { bytes = id3_parse_uint(&ehptr, 1); ehptr += bytes; } if (tag->extendedflags & ID3_TAG_EXTENDEDFLAG_CRCDATAPRESENT) { unsigned long crc; bytes = id3_parse_uint(&ehptr, 1); if (bytes < 5) goto fail; crc = id3_parse_syncsafe(&ehptr, 5); ehptr += bytes - 5; if (crc != id3_crc_compute(ptr, end - ptr)) goto fail; } if (tag->extendedflags & ID3_TAG_EXTENDEDFLAG_TAGRESTRICTIONS) { bytes = id3_parse_uint(&ehptr, 1); if (bytes < 1) goto fail; tag->restrictions = id3_parse_uint(&ehptr, 1); ehptr += bytes - 1; } } break; } } /* frames */ while (ptr < end) { struct id3_frame *frame; if (*ptr == 0) break; /* padding */ frame = id3_frame_parse(&ptr, end - ptr, tag->version); if (frame == 0 || id3_tag_attachframe(tag, frame) == -1) goto fail; } if (ID3_TAG_VERSION_MAJOR(tag->version) < 4 && id3_compat_fixup(tag) == -1) goto fail; } if (0) { fail: id3_tag_delete(tag); tag = 0; } if (mem) free(mem); return tag; } /* * NAME: tag->parse() * DESCRIPTION: parse a complete ID3 tag */ struct id3_tag *id3_tag_parse(id3_byte_t const *data, id3_length_t length) { id3_byte_t const *ptr; unsigned int version; int flags; id3_length_t size; assert(data); switch (tagtype(data, length)) { case TAGTYPE_ID3V1: return (length < 128) ? 0 : v1_parse(data); case TAGTYPE_ID3V2: break; case TAGTYPE_ID3V2_FOOTER: case TAGTYPE_NONE: return 0; } /* ID3v2.x */ ptr = data; parse_header(&ptr, &version, &flags, &size); switch (ID3_TAG_VERSION_MAJOR(version)) { case 4: if (flags & ID3_TAG_FLAG_FOOTERPRESENT) size += 10; case 2: case 3: return (length < 10 + size) ? 0 : v2_parse(data); } return 0; } static void v1_renderstr(struct id3_tag const *tag, char const *frameid, id3_byte_t **buffer, id3_length_t length) { struct id3_frame *frame; id3_ucs4_t const *string; frame = id3_tag_findframe(tag, frameid, 0); if (frame == 0) string = id3_ucs4_empty; else { if (strcmp(frameid, ID3_FRAME_COMMENT) == 0) string = id3_field_getfullstring(&frame->fields[3]); else string = id3_field_getstrings(&frame->fields[1], 0); } id3_render_paddedstring(buffer, string, length); } /* * NAME: v1->render() * DESCRIPTION: render an ID3v1 (or ID3v1.1) tag */ static id3_length_t v1_render(struct id3_tag const *tag, id3_byte_t *buffer) { id3_byte_t data[128], *ptr; struct id3_frame *frame; unsigned int i; int genre = -1; ptr = data; id3_render_immediate(&ptr, "TAG", 3); v1_renderstr(tag, ID3_FRAME_TITLE, &ptr, 30); v1_renderstr(tag, ID3_FRAME_ARTIST, &ptr, 30); v1_renderstr(tag, ID3_FRAME_ALBUM, &ptr, 30); v1_renderstr(tag, ID3_FRAME_YEAR, &ptr, 4); v1_renderstr(tag, ID3_FRAME_COMMENT, &ptr, 30); /* ID3v1.1 track number */ frame = id3_tag_findframe(tag, ID3_FRAME_TRACK, 0); if (frame) { id3_ucs4_t const *string; unsigned int track = 0; string = id3_field_getstrings(&frame->fields[1], 0); if (string) track = id3_ucs4_getnumber(string); if (track > 0 && track <= 0xff) { ptr[-2] = 0; ptr[-1] = track; } } /* ID3v1 genre number */ frame = id3_tag_findframe(tag, ID3_FRAME_GENRE, 0); if (frame) { unsigned int nstrings; nstrings = id3_field_getnstrings(&frame->fields[1]); for (i = 0; i < nstrings; ++i) { genre = id3_genre_number(id3_field_getstrings(&frame->fields[1], i)); if (genre != -1) break; } if (i == nstrings && nstrings > 0) genre = ID3_GENRE_OTHER; } id3_render_int(&ptr, genre, 1); /* make sure the tag is not empty */ if (genre == -1) { for (i = 3; i < 127; ++i) { if (data[i] != ' ') break; } if (i == 127) return 0; } if (buffer) memcpy(buffer, data, 128); return 128; } /* * NAME: tag->render() * DESCRIPTION: render a complete ID3 tag */ id3_length_t id3_tag_render(struct id3_tag const *tag, id3_byte_t *buffer) { id3_length_t size = 0; id3_byte_t **ptr, *header_ptr = 0, *tagsize_ptr = 0, *crc_ptr = 0, *frames_ptr = 0; int flags, extendedflags; unsigned int i; assert(tag); if (tag->options & ID3_TAG_OPTION_ID3V1) return v1_render(tag, buffer); /* a tag must contain at least one (renderable) frame */ for (i = 0; i < tag->nframes; ++i) { if (id3_frame_render(tag->frames[i], 0, 0) > 0) break; } if (i == tag->nframes) return 0; ptr = buffer ? &buffer : 0; /* get flags */ flags = tag->flags & ID3_TAG_FLAG_KNOWNFLAGS; extendedflags = tag->extendedflags & ID3_TAG_EXTENDEDFLAG_KNOWNFLAGS; extendedflags &= ~ID3_TAG_EXTENDEDFLAG_CRCDATAPRESENT; if (tag->options & ID3_TAG_OPTION_CRC) extendedflags |= ID3_TAG_EXTENDEDFLAG_CRCDATAPRESENT; extendedflags &= ~ID3_TAG_EXTENDEDFLAG_TAGRESTRICTIONS; if (tag->restrictions) extendedflags |= ID3_TAG_EXTENDEDFLAG_TAGRESTRICTIONS; flags &= ~ID3_TAG_FLAG_UNSYNCHRONISATION; if (tag->options & ID3_TAG_OPTION_UNSYNCHRONISATION) flags |= ID3_TAG_FLAG_UNSYNCHRONISATION; flags &= ~ID3_TAG_FLAG_EXTENDEDHEADER; if (extendedflags) flags |= ID3_TAG_FLAG_EXTENDEDHEADER; flags &= ~ID3_TAG_FLAG_FOOTERPRESENT; if (tag->options & ID3_TAG_OPTION_APPENDEDTAG) flags |= ID3_TAG_FLAG_FOOTERPRESENT; /* header */ if (ptr) header_ptr = *ptr; size += id3_render_immediate(ptr, "ID3", 3); size += id3_render_int(ptr, ID3_TAG_VERSION, 2); size += id3_render_int(ptr, flags, 1); if (ptr) tagsize_ptr = *ptr; size += id3_render_syncsafe(ptr, 0, 4); /* extended header */ if (flags & ID3_TAG_FLAG_EXTENDEDHEADER) { id3_length_t ehsize = 0; id3_byte_t *ehsize_ptr = 0; if (ptr) ehsize_ptr = *ptr; ehsize += id3_render_syncsafe(ptr, 0, 4); ehsize += id3_render_int(ptr, 1, 1); ehsize += id3_render_int(ptr, extendedflags, 1); if (extendedflags & ID3_TAG_EXTENDEDFLAG_TAGISANUPDATE) ehsize += id3_render_int(ptr, 0, 1); if (extendedflags & ID3_TAG_EXTENDEDFLAG_CRCDATAPRESENT) { ehsize += id3_render_int(ptr, 5, 1); if (ptr) crc_ptr = *ptr; ehsize += id3_render_syncsafe(ptr, 0, 5); } if (extendedflags & ID3_TAG_EXTENDEDFLAG_TAGRESTRICTIONS) { ehsize += id3_render_int(ptr, 1, 1); ehsize += id3_render_int(ptr, tag->restrictions, 1); } if (ehsize_ptr) id3_render_syncsafe(&ehsize_ptr, ehsize, 4); size += ehsize; } /* frames */ if (ptr) frames_ptr = *ptr; for (i = 0; i < tag->nframes; ++i) size += id3_frame_render(tag->frames[i], ptr, tag->options); /* padding */ if (!(flags & ID3_TAG_FLAG_FOOTERPRESENT)) { if (size < tag->paddedsize) size += id3_render_padding(ptr, 0, tag->paddedsize - size); else if (tag->options & ID3_TAG_OPTION_UNSYNCHRONISATION) { if (ptr == 0) size += 1; else { if ((*ptr)[-1] == 0xff) size += id3_render_padding(ptr, 0, 1); } } } /* patch tag size and CRC */ if (tagsize_ptr) id3_render_syncsafe(&tagsize_ptr, size - 10, 4); if (crc_ptr) { id3_render_syncsafe(&crc_ptr, id3_crc_compute(frames_ptr, *ptr - frames_ptr), 5); } /* footer */ if (flags & ID3_TAG_FLAG_FOOTERPRESENT) { size += id3_render_immediate(ptr, "3DI", 3); size += id3_render_binary(ptr, header_ptr + 3, 7); } return size; } libid3tag-0.16.3/tag.h000066400000000000000000000020151470022143500143630ustar00rootroot00000000000000/* * libid3tag - ID3 tag manipulation library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: tag.h,v 1.10 2004/01/23 09:41:32 rob Exp $ */ # ifndef LIBID3TAG_TAG_H # define LIBID3TAG_TAG_H # include "id3tag.h" void id3_tag_addref(struct id3_tag *); void id3_tag_delref(struct id3_tag *); # endif libid3tag-0.16.3/ucs4.c000066400000000000000000000112031470022143500144600ustar00rootroot00000000000000/* * libid3tag - ID3 tag manipulation library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: ucs4.c,v 1.13 2004/01/23 09:41:32 rob Exp $ */ # include "global.h" # include # include "id3tag.h" # include "ucs4.h" # include "latin1.h" # include "utf16.h" # include "utf8.h" id3_ucs4_t const id3_ucs4_empty[] = { 0 }; /* * NAME: ucs4->length() * DESCRIPTION: return the number of ucs4 chars represented by a ucs4 string */ id3_length_t id3_ucs4_length(id3_ucs4_t const *ucs4) { if (!ucs4) return 0; id3_ucs4_t const *ptr = ucs4; while (*ptr) ++ptr; return ptr - ucs4; } /* * NAME: ucs4->size() * DESCRIPTION: return the encoding size of a ucs4 string */ id3_length_t id3_ucs4_size(id3_ucs4_t const *ucs4) { return id3_ucs4_length(ucs4) + 1; } /* * NAME: ucs4->latin1size() * DESCRIPTION: return the encoding size of a latin1-encoded ucs4 string */ id3_length_t id3_ucs4_latin1size(id3_ucs4_t const *ucs4) { return id3_ucs4_size(ucs4); } /* * NAME: ucs4->utf16size() * DESCRIPTION: return the encoding size of a utf16-encoded ucs4 string */ id3_length_t id3_ucs4_utf16size(id3_ucs4_t const *ucs4) { id3_length_t size = 0; while (*ucs4) { ++size; if (*ucs4 >= 0x00010000L && *ucs4 <= 0x0010ffffL) ++size; ++ucs4; } return size + 1; } /* * NAME: ucs4->utf8size() * DESCRIPTION: return the encoding size of a utf8-encoded ucs4 string */ id3_length_t id3_ucs4_utf8size(id3_ucs4_t const *ucs4) { id3_length_t size = 0; while (*ucs4) { if (*ucs4 <= 0x0000007fL) size += 1; else if (*ucs4 <= 0x000007ffL) size += 2; else if (*ucs4 <= 0x0000ffffL) size += 3; else if (*ucs4 <= 0x001fffffL) size += 4; else if (*ucs4 <= 0x03ffffffL) size += 5; else if (*ucs4 <= 0x7fffffffL) size += 6; else size += 2; /* based on U+00B7 replacement char */ ++ucs4; } return size + 1; } /* * NAME: ucs4->latin1duplicate() * DESCRIPTION: duplicate and encode a ucs4 string into latin1 */ id3_latin1_t *id3_ucs4_latin1duplicate(id3_ucs4_t const *ucs4) { id3_latin1_t *latin1; latin1 = malloc(id3_ucs4_latin1size(ucs4) * sizeof(*latin1)); if (latin1) id3_latin1_encode(latin1, ucs4); return release(latin1); } /* * NAME: ucs4->utf16duplicate() * DESCRIPTION: duplicate and encode a ucs4 string into utf16 */ id3_utf16_t *id3_ucs4_utf16duplicate(id3_ucs4_t const *ucs4) { id3_utf16_t *utf16; utf16 = malloc(id3_ucs4_utf16size(ucs4) * sizeof(*utf16)); if (utf16) id3_utf16_encode(utf16, ucs4); return release(utf16); } /* * NAME: ucs4->utf8duplicate() * DESCRIPTION: duplicate and encode a ucs4 string into utf8 */ id3_utf8_t *id3_ucs4_utf8duplicate(id3_ucs4_t const *ucs4) { id3_utf8_t *utf8; utf8 = malloc(id3_ucs4_utf8size(ucs4) * sizeof(*utf8)); if (utf8) id3_utf8_encode(utf8, ucs4); return release(utf8); } /* * NAME: ucs4->copy() * DESCRIPTION: copy a ucs4 string */ void id3_ucs4_copy(id3_ucs4_t *dest, id3_ucs4_t const *src) { while ((*dest++ = *src++)) ; } /* * NAME: ucs4->duplicate() * DESCRIPTION: duplicate a ucs4 string */ id3_ucs4_t *id3_ucs4_duplicate(id3_ucs4_t const *src) { id3_ucs4_t *ucs4; ucs4 = malloc(id3_ucs4_size(src) * sizeof(*ucs4)); if (ucs4) id3_ucs4_copy(ucs4, src); return ucs4; } /* * NAME: ucs4->putnumber() * DESCRIPTION: write a ucs4 string containing a (positive) decimal number */ void id3_ucs4_putnumber(id3_ucs4_t *ucs4, unsigned long number) { int digits[10], *digit; digit = digits; do { *digit++ = number % 10; number /= 10; } while (number); while (digit != digits) *ucs4++ = '0' + *--digit; *ucs4 = 0; } /* * NAME: ucs4->getnumber() * DESCRIPTION: read a ucs4 string containing a (positive) decimal number */ unsigned long id3_ucs4_getnumber(id3_ucs4_t const *ucs4) { unsigned long number = 0; while (*ucs4 >= '0' && *ucs4 <= '9') number = 10 * number + (*ucs4++ - '0'); return number; } libid3tag-0.16.3/ucs4.h000066400000000000000000000026341470022143500144750ustar00rootroot00000000000000/* * libid3tag - ID3 tag manipulation library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: ucs4.h,v 1.11 2004/01/23 09:41:32 rob Exp $ */ # ifndef LIBID3TAG_UCS4_H # define LIBID3TAG_UCS4_H # include "id3tag.h" # define ID3_UCS4_REPLACEMENTCHAR 0x000000b7L /* middle dot */ extern id3_ucs4_t const id3_ucs4_empty[]; id3_length_t id3_ucs4_length(id3_ucs4_t const *); id3_length_t id3_ucs4_size(id3_ucs4_t const *); id3_length_t id3_ucs4_latin1size(id3_ucs4_t const *); id3_length_t id3_ucs4_utf16size(id3_ucs4_t const *); id3_length_t id3_ucs4_utf8size(id3_ucs4_t const *); void id3_ucs4_copy(id3_ucs4_t *, id3_ucs4_t const *); id3_ucs4_t *id3_ucs4_duplicate(id3_ucs4_t const *); # endif libid3tag-0.16.3/utf16.c000066400000000000000000000152211470022143500145530ustar00rootroot00000000000000/* * libid3tag - ID3 tag manipulation library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: utf16.c,v 1.9 2004/01/23 09:41:32 rob Exp $ */ # include "global.h" # include # include "id3tag.h" # include "utf16.h" # include "ucs4.h" /* * NAME: utf16->length() * DESCRIPTION: return the number of ucs4 chars represented by a utf16 string */ id3_length_t id3_utf16_length(id3_utf16_t const *utf16) { id3_length_t length = 0; while (*utf16) { if (utf16[0] < 0xd800 || utf16[0] > 0xdfff) ++length; else if (utf16[0] >= 0xd800 && utf16[0] <= 0xdbff && utf16[1] >= 0xdc00 && utf16[1] <= 0xdfff) { ++length; ++utf16; } ++utf16; } return length; } /* * NAME: utf16->size() * DESCRIPTION: return the encoding size of a utf16 string */ id3_length_t id3_utf16_size(id3_utf16_t const *utf16) { id3_utf16_t const *ptr = utf16; while (*ptr) ++ptr; return ptr - utf16 + 1; } /* * NAME: utf16->ucs4duplicate() * DESCRIPTION: duplicate and decode a utf16 string into ucs4 */ id3_ucs4_t *id3_utf16_ucs4duplicate(id3_utf16_t const *utf16) { id3_ucs4_t *ucs4; ucs4 = malloc((id3_utf16_length(utf16) + 1) * sizeof(*ucs4)); if (ucs4) id3_utf16_decode(utf16, ucs4); return release(ucs4); } /* * NAME: utf16->decodechar() * DESCRIPTION: decode a series of utf16 chars into a single ucs4 char */ id3_length_t id3_utf16_decodechar(id3_utf16_t const *utf16, id3_ucs4_t *ucs4) { id3_utf16_t const *start = utf16; while (1) { if (utf16[0] < 0xd800 || utf16[0] > 0xdfff) { *ucs4 = utf16[0]; return utf16 - start + 1; } else if (utf16[0] >= 0xd800 && utf16[0] <= 0xdbff && utf16[1] >= 0xdc00 && utf16[1] <= 0xdfff) { *ucs4 = (((utf16[0] & 0x03ffL) << 10) | ((utf16[1] & 0x03ffL) << 0)) + 0x00010000L; return utf16 - start + 2; } ++utf16; } } /* * NAME: utf16->encodechar() * DESCRIPTION: encode a single ucs4 char into a series of up to 2 utf16 chars */ id3_length_t id3_utf16_encodechar(id3_utf16_t *utf16, id3_ucs4_t ucs4) { if (ucs4 < 0x00010000L) { utf16[0] = ucs4; return 1; } else if (ucs4 < 0x00110000L) { ucs4 -= 0x00010000L; utf16[0] = ((ucs4 >> 10) & 0x3ff) | 0xd800; utf16[1] = ((ucs4 >> 0) & 0x3ff) | 0xdc00; return 2; } /* default */ return id3_utf16_encodechar(utf16, ID3_UCS4_REPLACEMENTCHAR); } /* * NAME: utf16->decode() * DESCRIPTION: decode a complete utf16 string into a ucs4 string */ void id3_utf16_decode(id3_utf16_t const *utf16, id3_ucs4_t *ucs4) { do utf16 += id3_utf16_decodechar(utf16, ucs4); while (*ucs4++); } /* * NAME: utf16->encode() * DESCRIPTION: encode a complete ucs4 string into a utf16 string */ void id3_utf16_encode(id3_utf16_t *utf16, id3_ucs4_t const *ucs4) { do utf16 += id3_utf16_encodechar(utf16, *ucs4); while (*ucs4++); } /* * NAME: utf16->put() * DESCRIPTION: serialize a single utf16 character */ id3_length_t id3_utf16_put(id3_byte_t **ptr, id3_utf16_t utf16, enum id3_utf16_byteorder byteorder) { if (ptr) { switch (byteorder) { default: case ID3_UTF16_BYTEORDER_BE: (*ptr)[0] = (utf16 >> 8) & 0xff; (*ptr)[1] = (utf16 >> 0) & 0xff; break; case ID3_UTF16_BYTEORDER_LE: (*ptr)[0] = (utf16 >> 0) & 0xff; (*ptr)[1] = (utf16 >> 8) & 0xff; break; } *ptr += 2; } return 2; } /* * NAME: utf16->get() * DESCRIPTION: deserialize a single utf16 character */ id3_utf16_t id3_utf16_get(id3_byte_t const **ptr, enum id3_utf16_byteorder byteorder) { id3_utf16_t utf16; switch (byteorder) { default: case ID3_UTF16_BYTEORDER_BE: utf16 = ((*ptr)[0] << 8) | ((*ptr)[1] << 0); break; case ID3_UTF16_BYTEORDER_LE: utf16 = ((*ptr)[0] << 0) | ((*ptr)[1] << 8); break; } *ptr += 2; return utf16; } /* * NAME: utf16->serialize() * DESCRIPTION: serialize a ucs4 string using utf16 encoding */ id3_length_t id3_utf16_serialize(id3_byte_t **ptr, id3_ucs4_t const *ucs4, enum id3_utf16_byteorder byteorder, int terminate) { id3_length_t size = 0; id3_utf16_t utf16[2], *out; if (byteorder == ID3_UTF16_BYTEORDER_ANY) size += id3_utf16_put(ptr, 0xfeff, byteorder); while (*ucs4) { switch (id3_utf16_encodechar(out = utf16, *ucs4++)) { case 2: size += id3_utf16_put(ptr, *out++, byteorder); case 1: size += id3_utf16_put(ptr, *out++, byteorder); case 0: break; } } if (terminate) size += id3_utf16_put(ptr, 0, byteorder); return size; } /* * NAME: utf16->deserialize() * DESCRIPTION: deserialize a ucs4 string using utf16 encoding */ id3_ucs4_t *id3_utf16_deserialize(id3_byte_t const **ptr, id3_length_t length, enum id3_utf16_byteorder byteorder) { id3_byte_t const *end; id3_utf16_t *utf16ptr, *utf16; id3_ucs4_t *ucs4; end = *ptr + (length & ~1); if (end == *ptr) return 0; utf16 = malloc((length / 2 + 1) * sizeof(*utf16)); if (utf16 == 0) return 0; if (byteorder == ID3_UTF16_BYTEORDER_ANY && end - *ptr > 0) { switch (((*ptr)[0] << 8) | ((*ptr)[1] << 0)) { case 0xfeff: byteorder = ID3_UTF16_BYTEORDER_BE; *ptr += 2; break; case 0xfffe: byteorder = ID3_UTF16_BYTEORDER_LE; *ptr += 2; break; } } utf16ptr = utf16; while (end - *ptr > 0 && (*utf16ptr = id3_utf16_get(ptr, byteorder))) ++utf16ptr; *utf16ptr = 0; ucs4 = malloc((id3_utf16_length(utf16) + 1) * sizeof(*ucs4)); if (ucs4) id3_utf16_decode(utf16, ucs4); free(utf16); if (end == *ptr && length % 2 != 0) { /* We were called with a bogus length. It should always * be an even number. We can deal with this in a few ways: * - Always give an error. * - Try and parse as much as we can and * - return an error if we're called again when we * already tried to parse everything we can. * - tell that we parsed it, which is what we do here. */ (*ptr)++; } return ucs4; } libid3tag-0.16.3/utf16.h000066400000000000000000000034041470022143500145600ustar00rootroot00000000000000/* * libid3tag - ID3 tag manipulation library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: utf16.h,v 1.8 2004/01/23 09:41:32 rob Exp $ */ # ifndef LIBID3TAG_UTF16_H # define LIBID3TAG_UTF16_H # include "id3tag.h" enum id3_utf16_byteorder { ID3_UTF16_BYTEORDER_ANY, ID3_UTF16_BYTEORDER_BE, ID3_UTF16_BYTEORDER_LE }; id3_length_t id3_utf16_length(id3_utf16_t const *); id3_length_t id3_utf16_size(id3_utf16_t const *); id3_length_t id3_utf16_decodechar(id3_utf16_t const *, id3_ucs4_t *); id3_length_t id3_utf16_encodechar(id3_utf16_t *, id3_ucs4_t); void id3_utf16_decode(id3_utf16_t const *, id3_ucs4_t *); void id3_utf16_encode(id3_utf16_t *, id3_ucs4_t const *); id3_length_t id3_utf16_put(id3_byte_t **, id3_utf16_t, enum id3_utf16_byteorder); id3_utf16_t id3_utf16_get(id3_byte_t const **, enum id3_utf16_byteorder); id3_length_t id3_utf16_serialize(id3_byte_t **, id3_ucs4_t const *, enum id3_utf16_byteorder, int); id3_ucs4_t *id3_utf16_deserialize(id3_byte_t const **, id3_length_t, enum id3_utf16_byteorder); # endif libid3tag-0.16.3/utf8.c000066400000000000000000000210531470022143500144740ustar00rootroot00000000000000/* * libid3tag - ID3 tag manipulation library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: utf8.c,v 1.9 2004/01/23 09:41:32 rob Exp $ */ # include "global.h" # include # include "id3tag.h" # include "utf8.h" # include "ucs4.h" /* * NAME: utf8->length() * DESCRIPTION: return the number of ucs4 chars represented by a utf8 string */ id3_length_t id3_utf8_length(id3_utf8_t const *utf8) { id3_length_t length = 0; while (*utf8) { if ((utf8[0] & 0x80) == 0x00) ++length; else if ((utf8[0] & 0xe0) == 0xc0 && (utf8[1] & 0xc0) == 0x80) { if (((utf8[0] & 0x1fL) << 6) >= 0x00000080L) { ++length; utf8 += 1; } } else if ((utf8[0] & 0xf0) == 0xe0 && (utf8[1] & 0xc0) == 0x80 && (utf8[2] & 0xc0) == 0x80) { if ((((utf8[0] & 0x0fL) << 12) | ((utf8[1] & 0x3fL) << 6)) >= 0x00000800L) { ++length; utf8 += 2; } } else if ((utf8[0] & 0xf8) == 0xf0 && (utf8[1] & 0xc0) == 0x80 && (utf8[2] & 0xc0) == 0x80 && (utf8[3] & 0xc0) == 0x80) { if ((((utf8[0] & 0x07L) << 18) | ((utf8[1] & 0x3fL) << 12)) >= 0x00010000L) { ++length; utf8 += 3; } } else if ((utf8[0] & 0xfc) == 0xf8 && (utf8[1] & 0xc0) == 0x80 && (utf8[2] & 0xc0) == 0x80 && (utf8[3] & 0xc0) == 0x80 && (utf8[4] & 0xc0) == 0x80) { if ((((utf8[0] & 0x03L) << 24) | ((utf8[0] & 0x3fL) << 18)) >= 0x00200000L) { ++length; utf8 += 4; } } else if ((utf8[0] & 0xfe) == 0xfc && (utf8[1] & 0xc0) == 0x80 && (utf8[2] & 0xc0) == 0x80 && (utf8[3] & 0xc0) == 0x80 && (utf8[4] & 0xc0) == 0x80 && (utf8[5] & 0xc0) == 0x80) { if ((((utf8[0] & 0x01L) << 30) | ((utf8[0] & 0x3fL) << 24)) >= 0x04000000L) { ++length; utf8 += 5; } } ++utf8; } return length; } /* * NAME: utf8->size() * DESCRIPTION: return the encoding size of a utf8 string */ id3_length_t id3_utf8_size(id3_utf8_t const *utf8) { id3_utf8_t const *ptr = utf8; while (*ptr) ++ptr; return ptr - utf8 + 1; } /* * NAME: utf8->ucs4duplicate() * DESCRIPTION: duplicate and decode a utf8 string into ucs4 */ id3_ucs4_t *id3_utf8_ucs4duplicate(id3_utf8_t const *utf8) { id3_ucs4_t *ucs4; ucs4 = malloc((id3_utf8_length(utf8) + 1) * sizeof(*ucs4)); if (ucs4) id3_utf8_decode(utf8, ucs4); return release(ucs4); } /* * NAME: utf8->decodechar() * DESCRIPTION: decode a series of utf8 chars into a single ucs4 char */ id3_length_t id3_utf8_decodechar(id3_utf8_t const *utf8, id3_ucs4_t *ucs4) { id3_utf8_t const *start = utf8; while (1) { if ((utf8[0] & 0x80) == 0x00) { *ucs4 = utf8[0]; return utf8 - start + 1; } else if ((utf8[0] & 0xe0) == 0xc0 && (utf8[1] & 0xc0) == 0x80) { *ucs4 = ((utf8[0] & 0x1fL) << 6) | ((utf8[1] & 0x3fL) << 0); if (*ucs4 >= 0x00000080L) return utf8 - start + 2; } else if ((utf8[0] & 0xf0) == 0xe0 && (utf8[1] & 0xc0) == 0x80 && (utf8[2] & 0xc0) == 0x80) { *ucs4 = ((utf8[0] & 0x0fL) << 12) | ((utf8[1] & 0x3fL) << 6) | ((utf8[2] & 0x3fL) << 0); if (*ucs4 >= 0x00000800L) return utf8 - start + 3; } else if ((utf8[0] & 0xf8) == 0xf0 && (utf8[1] & 0xc0) == 0x80 && (utf8[2] & 0xc0) == 0x80 && (utf8[3] & 0xc0) == 0x80) { *ucs4 = ((utf8[0] & 0x07L) << 18) | ((utf8[1] & 0x3fL) << 12) | ((utf8[2] & 0x3fL) << 6) | ((utf8[3] & 0x3fL) << 0); if (*ucs4 >= 0x00010000L) return utf8 - start + 4; } else if ((utf8[0] & 0xfc) == 0xf8 && (utf8[1] & 0xc0) == 0x80 && (utf8[2] & 0xc0) == 0x80 && (utf8[3] & 0xc0) == 0x80 && (utf8[4] & 0xc0) == 0x80) { *ucs4 = ((utf8[0] & 0x03L) << 24) | ((utf8[1] & 0x3fL) << 18) | ((utf8[2] & 0x3fL) << 12) | ((utf8[3] & 0x3fL) << 6) | ((utf8[4] & 0x3fL) << 0); if (*ucs4 >= 0x00200000L) return utf8 - start + 5; } else if ((utf8[0] & 0xfe) == 0xfc && (utf8[1] & 0xc0) == 0x80 && (utf8[2] & 0xc0) == 0x80 && (utf8[3] & 0xc0) == 0x80 && (utf8[4] & 0xc0) == 0x80 && (utf8[5] & 0xc0) == 0x80) { *ucs4 = ((utf8[0] & 0x01L) << 30) | ((utf8[1] & 0x3fL) << 24) | ((utf8[2] & 0x3fL) << 18) | ((utf8[3] & 0x3fL) << 12) | ((utf8[4] & 0x3fL) << 6) | ((utf8[5] & 0x3fL) << 0); if (*ucs4 >= 0x04000000L) return utf8 - start + 6; } ++utf8; } } /* * NAME: utf8->encodechar() * DESCRIPTION: encode a single ucs4 char into a series of up to 6 utf8 chars */ id3_length_t id3_utf8_encodechar(id3_utf8_t *utf8, id3_ucs4_t ucs4) { if (ucs4 <= 0x0000007fL) { utf8[0] = ucs4; return 1; } else if (ucs4 <= 0x000007ffL) { utf8[0] = 0xc0 | ((ucs4 >> 6) & 0x1f); utf8[1] = 0x80 | ((ucs4 >> 0) & 0x3f); return 2; } else if (ucs4 <= 0x0000ffffL) { utf8[0] = 0xe0 | ((ucs4 >> 12) & 0x0f); utf8[1] = 0x80 | ((ucs4 >> 6) & 0x3f); utf8[2] = 0x80 | ((ucs4 >> 0) & 0x3f); return 3; } else if (ucs4 <= 0x001fffffL) { utf8[0] = 0xf0 | ((ucs4 >> 18) & 0x07); utf8[1] = 0x80 | ((ucs4 >> 12) & 0x3f); utf8[2] = 0x80 | ((ucs4 >> 6) & 0x3f); utf8[3] = 0x80 | ((ucs4 >> 0) & 0x3f); return 4; } else if (ucs4 <= 0x03ffffffL) { utf8[0] = 0xf8 | ((ucs4 >> 24) & 0x03); utf8[1] = 0x80 | ((ucs4 >> 18) & 0x3f); utf8[2] = 0x80 | ((ucs4 >> 12) & 0x3f); utf8[3] = 0x80 | ((ucs4 >> 6) & 0x3f); utf8[4] = 0x80 | ((ucs4 >> 0) & 0x3f); return 5; } else if (ucs4 <= 0x7fffffffL) { utf8[0] = 0xfc | ((ucs4 >> 30) & 0x01); utf8[1] = 0x80 | ((ucs4 >> 24) & 0x3f); utf8[2] = 0x80 | ((ucs4 >> 18) & 0x3f); utf8[3] = 0x80 | ((ucs4 >> 12) & 0x3f); utf8[4] = 0x80 | ((ucs4 >> 6) & 0x3f); utf8[5] = 0x80 | ((ucs4 >> 0) & 0x3f); return 6; } /* default */ return id3_utf8_encodechar(utf8, ID3_UCS4_REPLACEMENTCHAR); } /* * NAME: utf8->decode() * DESCRIPTION: decode a complete utf8 string into a ucs4 string */ void id3_utf8_decode(id3_utf8_t const *utf8, id3_ucs4_t *ucs4) { do utf8 += id3_utf8_decodechar(utf8, ucs4); while (*ucs4++); } /* * NAME: utf8->encode() * DESCRIPTION: encode a complete ucs4 string into a utf8 string */ void id3_utf8_encode(id3_utf8_t *utf8, id3_ucs4_t const *ucs4) { do utf8 += id3_utf8_encodechar(utf8, *ucs4); while (*ucs4++); } /* * NAME: utf8->put() * DESCRIPTION: serialize a single utf8 character */ id3_length_t id3_utf8_put(id3_byte_t **ptr, id3_utf8_t utf8) { if (ptr) *(*ptr)++ = utf8; return 1; } /* * NAME: utf8->get() * DESCRIPTION: deserialize a single utf8 character */ id3_utf8_t id3_utf8_get(id3_byte_t const **ptr) { return *(*ptr)++; } /* * NAME: utf8->serialize() * DESCRIPTION: serialize a ucs4 string using utf8 encoding */ id3_length_t id3_utf8_serialize(id3_byte_t **ptr, id3_ucs4_t const *ucs4, int terminate) { id3_length_t size = 0; id3_utf8_t utf8[6], *out; while (*ucs4) { switch (id3_utf8_encodechar(out = utf8, *ucs4++)) { case 6: size += id3_utf8_put(ptr, *out++); case 5: size += id3_utf8_put(ptr, *out++); case 4: size += id3_utf8_put(ptr, *out++); case 3: size += id3_utf8_put(ptr, *out++); case 2: size += id3_utf8_put(ptr, *out++); case 1: size += id3_utf8_put(ptr, *out++); case 0: break; } } if (terminate) size += id3_utf8_put(ptr, 0); return size; } /* * NAME: utf8->deserialize() * DESCRIPTION: deserialize a ucs4 string using utf8 encoding */ id3_ucs4_t *id3_utf8_deserialize(id3_byte_t const **ptr, id3_length_t length) { id3_byte_t const *end; id3_utf8_t *utf8ptr, *utf8; id3_ucs4_t *ucs4; end = *ptr + length; utf8 = malloc((length + 1) * sizeof(*utf8)); if (utf8 == 0) return 0; utf8ptr = utf8; while (end - *ptr > 0 && (*utf8ptr = id3_utf8_get(ptr))) ++utf8ptr; *utf8ptr = 0; ucs4 = malloc((id3_utf8_length(utf8) + 1) * sizeof(*ucs4)); if (ucs4) id3_utf8_decode(utf8, ucs4); free(utf8); return ucs4; } libid3tag-0.16.3/utf8.h000066400000000000000000000030111470022143500144730ustar00rootroot00000000000000/* * libid3tag - ID3 tag manipulation library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: utf8.h,v 1.7 2004/01/23 09:41:32 rob Exp $ */ # ifndef LIBID3TAG_UTF8_H # define LIBID3TAG_UTF8_H # include "id3tag.h" id3_length_t id3_utf8_length(id3_utf8_t const *); id3_length_t id3_utf8_size(id3_utf8_t const *); id3_length_t id3_utf8_decodechar(id3_utf8_t const *, id3_ucs4_t *); id3_length_t id3_utf8_encodechar(id3_utf8_t *, id3_ucs4_t); void id3_utf8_decode(id3_utf8_t const *, id3_ucs4_t *); void id3_utf8_encode(id3_utf8_t *, id3_ucs4_t const *); id3_length_t id3_utf8_put(id3_byte_t **, id3_utf8_t); id3_utf8_t id3_utf8_get(id3_byte_t const **); id3_length_t id3_utf8_serialize(id3_byte_t **, id3_ucs4_t const *, int); id3_ucs4_t *id3_utf8_deserialize(id3_byte_t const **, id3_length_t); # endif libid3tag-0.16.3/util.c000066400000000000000000000064101470022143500145630ustar00rootroot00000000000000/* * libid3tag - ID3 tag manipulation library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: util.c,v 1.9 2004/01/23 09:41:32 rob Exp $ */ # include "global.h" # include # include # include "id3tag.h" # include "util.h" /* * NAME: util->unsynchronise() * DESCRIPTION: perform (in-place) unsynchronisation */ id3_length_t id3_util_unsynchronise(id3_byte_t *data, id3_length_t length) { id3_length_t bytes = 0, count; id3_byte_t *end = data + length; id3_byte_t const *ptr; if (length == 0) return 0; for (ptr = data; ptr < end - 1; ++ptr) { if (ptr[0] == 0xff && (ptr[1] == 0x00 || (ptr[1] & 0xe0) == 0xe0)) ++bytes; } if (bytes) { ptr = end; end += bytes; *--end = *--ptr; for (count = bytes; count; *--end = *--ptr) { if (ptr[-1] == 0xff && (ptr[0] == 0x00 || (ptr[0] & 0xe0) == 0xe0)) { *--end = 0x00; --count; } } } return length + bytes; } /* * NAME: util->deunsynchronise() * DESCRIPTION: undo unsynchronisation (in-place) */ id3_length_t id3_util_deunsynchronise(id3_byte_t *data, id3_length_t length) { id3_byte_t const *old, *end = data + length; id3_byte_t *new; if (length == 0) return 0; for (old = new = data; old < end - 1; ++old) { *new++ = *old; if (old[0] == 0xff && old[1] == 0x00) ++old; } *new++ = *old; return new - data; } /* * NAME: util->compress() * DESCRIPTION: perform zlib deflate method compression */ id3_byte_t *id3_util_compress(id3_byte_t const *data, id3_length_t length, id3_length_t *newlength) { id3_byte_t *compressed; *newlength = length + 12; *newlength += *newlength / 1000; compressed = malloc(*newlength); if (compressed) { if (compress2(compressed, newlength, data, length, Z_BEST_COMPRESSION) != Z_OK || *newlength >= length) { free(compressed); compressed = 0; } else { id3_byte_t *resized; resized = realloc(compressed, *newlength ? *newlength : 1); if (resized) compressed = resized; } } return compressed; } /* * NAME: util->decompress() * DESCRIPTION: undo zlib deflate method compression */ id3_byte_t *id3_util_decompress(id3_byte_t const *data, id3_length_t length, id3_length_t newlength) { id3_byte_t *decompressed; decompressed = malloc(newlength ? newlength : 1); if (decompressed) { id3_length_t size; size = newlength; if (uncompress(decompressed, &size, data, length) != Z_OK || size != newlength) { free(decompressed); decompressed = 0; } } return decompressed; } libid3tag-0.16.3/util.h000066400000000000000000000023651470022143500145750ustar00rootroot00000000000000/* * libid3tag - ID3 tag manipulation library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: util.h,v 1.6 2004/01/23 09:41:32 rob Exp $ */ # ifndef LIBID3TAG_UTIL_H # define LIBID3TAG_UTIL_H # include "id3tag.h" id3_length_t id3_util_unsynchronise(id3_byte_t *, id3_length_t); id3_length_t id3_util_deunsynchronise(id3_byte_t *, id3_length_t); id3_byte_t *id3_util_compress(id3_byte_t const *, id3_length_t, id3_length_t *); id3_byte_t *id3_util_decompress(id3_byte_t const *, id3_length_t, id3_length_t); # endif libid3tag-0.16.3/version.c000066400000000000000000000024301470022143500152710ustar00rootroot00000000000000/* * libid3tag - ID3 tag manipulation library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: version.c,v 1.7 2004/01/23 09:41:32 rob Exp $ */ # include "global.h" # include "id3tag.h" # include "version.h" char const id3_version[] = "ID3 Tag Library " ID3_VERSION; char const id3_copyright[] = "Copyright (C) " ID3_PUBLISHYEAR " " ID3_AUTHOR; char const id3_author[] = ID3_AUTHOR " <" ID3_EMAIL ">"; char const id3_build[] = "" # if defined(DEBUG) "DEBUG " # elif defined(NDEBUG) "NDEBUG " # endif # if defined(EXPERIMENTAL) "EXPERIMENTAL " # endif ; libid3tag-0.16.3/version.h000066400000000000000000000016631470022143500153050ustar00rootroot00000000000000/* * libid3tag - ID3 tag manipulation library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: version.h,v 1.7 2004/01/23 09:41:32 rob Exp $ */ # ifndef LIBID3TAG_VERSION_H # define LIBID3TAG_VERSION_H # endif