Initial revision

v0.27.3
Andreas Huggel 22 years ago
commit e0f20339a2

1078
Doxyfile

File diff suppressed because it is too large Load Diff

@ -0,0 +1,26 @@
# ***************************************************** -*- Makefile -*-
#
# AUTHOR(S): Andreas Huggel (ahu)
#
# RCS information
# $Name: $
# $Revision: 1.1 $
#
# Description:
# This makefile just forwards to src/Makefile.
#
# Restrictions:
# Requires GNU make.
#
.PHONY: all maintainer-clean doc
all maintainer-clean:
cd src && $(MAKE) $(MAKECMDGOALS)
cd doc && $(MAKE) $(MAKECMDGOALS)
doc:
cd doc && $(MAKE) $(MAKECMDGOALS)
%:
cd src && $(MAKE) $(MAKECMDGOALS)

@ -0,0 +1,88 @@
/* config.h. Generated by configure. */
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define to 1 if you have the `alarm' function. */
#define HAVE_ALARM 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the `localtime_r' function. */
#define HAVE_LOCALTIME_R 1
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define to 1 if you have the `memset' function. */
#define HAVE_MEMSET 1
/* Define to 1 if `stat' has the bug that it succeeds when given the
zero-length file name argument. */
/* #undef HAVE_STAT_EMPTY_STRING_BUG */
/* Define to 1 if stdbool.h conforms to C99. */
/* #undef HAVE_STDBOOL_H */
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the `strerror' function. */
#define HAVE_STRERROR 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the `strtol' function. */
#define HAVE_STRTOL 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/time.h> header file. */
#define HAVE_SYS_TIME_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to 1 if the system has the type `_Bool'. */
/* #undef HAVE__BOOL */
/* Define to 1 if `lstat' dereferences a symlink specified with a trailing
slash. */
#define LSTAT_FOLLOWS_SLASHED_SYMLINK 1
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "ahuggel@gmx.net"
/* Define to the full name of this package. */
#define PACKAGE_NAME "exiv"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "exiv 0.2"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "exiv"
/* Define to the version of this package. */
#define PACKAGE_VERSION "0.1 beta"
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
#define TIME_WITH_SYS_TIME 1
/* Define to 1 if your <sys/time.h> declares `struct tm'. */
/* #undef TM_IN_SYS_TIME */
/* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */

@ -0,0 +1,102 @@
# ***************************************************** -*- Makefile -*-
#
# Copyright (c) 2003, 2004 Andreas Huggel
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Common Public License v1.0
# which accompanies this distribution, and is available at
# http://www.ibm.com/developerworks/oss/CPLv1.0.htm
#
# Author(s): Andreas Huggel (ahu)
#
# RCS information
# $Name: $
# $Revision: 1.1 $
#
# Description: System configuration file for GNU/Linux:
# gcc 3.x on Debian GNU/Linux running Linux kernel 2.2.x or higher
#
# **********************************************************************
# Define which libraries (shared and/or static) to build
SHARED_LIBS =
STATIC_LIBS = 1
# **********************************************************************
# C++ Compiler and precompiler
CXX = g++
# Common compiler flags (warnings, symbols, optimization, etc)
CXXFLAGS := -Wall -g
# Compiler flags to compile static objects
CXXFLAGS_STATIC := $(CXXFLAGS)
# Compiler flags for shared objects
CXXFLAGS_SHARED := $(CXXFLAGS) -fPIC
# Command to run only the preprocessor
CXXCPP = $(CXX) -E -dD
# Preprocessor flags
CPPFLAGS =
# Command to run the compiler or preprocessor to produce dependencies
CXXDEP = $(CXX) -MM
# Flag to $(CXXDEP) to treat all subsequent file names as C++ source
# files, regardless of their suffixes
CXXLANGCXX = -x c++
# Linker flags
LDFLAGS =
# Linker flags to link applications
LDFLAGS_APP = $(LDFLAGS)
# Linker flags used to link shared libraries
LDFLAGS_SHARED = $(LDFLAGS) -shared -fPIC
# Repository for object files of templates (e.g., Compaq Tru64 cxx)
CXX_REPOSITORY =
# Library filename suffixes
SHAREDLIB_SUFFIX = .so
ARCHIVE_SUFFIX = .a
# **********************************************************************
# Global includes, libraries and defines
INCS = -I. -I$(incdir) -I/usr/local/include
LIBS = -L. -L$(libdir) -L/usr/local/lib
DEFS =
# **********************************************************************
# Archive management
RANLIB = ranlib
AR = ar
ARFLAGS = rcuv
# **********************************************************************
# Installation programs
INSTALL_EXE = /usr/bin/install
INSTALL_PROGRAM = $(INSTALL_EXE) -c -p
INSTALL_DATA = $(INSTALL_EXE) -c -m 644 -p
# **********************************************************************
# Other programs
RM = @rm -vf
# **********************************************************************
# Directories
prefix = ..
#exec_prefix = ${prefix}
exec_prefix = ~
# Source directory
srcdir = .
# Installation directories
bindir = ${exec_prefix}/bin
incdir = ${exec_prefix}/include
idldir = ${exec_prefix}/idl
libdir = ${exec_prefix}/lib
mandir = ${prefix}/man
man1dir = $(mandir)/man1
man1ext = 1
man3dir = $(mandir)/man3
man3ext = 3
datadir = ${prefix}/share

@ -0,0 +1,57 @@
# ***************************************************** -*- Makefile -*-
#
# Copyright (c) 2003, 2004 Andreas Huggel
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Common Public License v1.0
# which accompanies this distribution, and is available at
# http://www.ibm.com/developerworks/oss/CPLv1.0.htm
#
# Author(s): Andreas Huggel (ahu)
#
# RCS information
# $Name: $
# $Revision: 1.1 $
#
# Description:
# Do NOT change this file! All system specific settings and configs
# go into config.mk.
#
# This makefile contains (supposedly) generic build rules to build a
# library and applications. It includes all system specific settings
# from config.mk. The idea is that configuring and porting the
# software to a new platform should only require changes in config.mk.
#
# Adding new source files or applications: Just add an entry with the
# name of the new file in the section 'Source files' below.
#
# Restrictions:
# Requires GNU make.
#
# Default make target
all: doc
# Include system configuration
top_srcdir = ..
include $(top_srcdir)/config.mk
# **********************************************************************
# ======================================================================
# **********************************************************************
# Initialisations
SHELL = /bin/sh
.SUFFIXES:
# **********************************************************************
# Targets
.PHONY: all doc maintainer-clean
doc:
doxygen $(top_srcdir)/Doxyfile
# This command is intended for maintainers to use; it deletes files
# that may need special tools to rebuild.
maintainer-clean:
rm -rf $(top_srcdir)/doc/html/*

@ -0,0 +1,258 @@
<html><head>
<meta content="Lotus Word Pro" name="Generator"><title>Body</title></head>
<body vlink="#800000" bgcolor="#ffffff">
<p align="center"><b>Common Public License - v 1.0</b>
</p><p><b></b><font size="3"></font>
</p><p><font size="3"></font><font size="2">THE ACCOMPANYING PROGRAM IS
PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT").
ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES
RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.</font>
</p><p><font size="2"></font>
</p><p><font size="2"><b>1. DEFINITIONS</b></font>
</p><p><font size="2">"Contribution" means:</font>
</p><ul><font size="2">a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and<br clear="left">
b) in the case of each subsequent Contributor:</font></ul>
<ul><font size="2">i) changes to the Program, and</font></ul>
<ul><font size="2">ii) additions to the Program;</font></ul>
<ul><font size="2">where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. </font><font size="2">A
Contribution 'originates' from a Contributor if it was added to the
Program by such Contributor itself or anyone acting on such
Contributor's behalf. </font><font size="2">Contributions do not
include additions to the Program which: (i) are separate modules of
software distributed in conjunction with the Program under their own
license agreement, and (ii) are not derivative works of the Program. </font></ul>
<p><font size="2"></font>
</p><p><font size="2">"Contributor" means any person or entity that distributes the Program.</font>
</p><p><font size="2"></font><font size="2"></font>
</p><p><font size="2">"Licensed Patents " mean patent claims licensable
by a Contributor which are necessarily infringed by the use or sale of
its Contribution alone or when combined with the Program. </font>
</p><p><font size="2"></font><font size="2"></font>
</p><p><font size="2"></font><font size="2">"Program" means the Contributions distributed in accordance with this Agreement.</font>
</p><p><font size="2"></font>
</p><p><font size="2">"Recipient" means anyone who receives the Program under this Agreement, including all Contributors.</font>
</p><p><font size="2"><b></b></font>
</p><p><font size="2"><b>2. GRANT OF RIGHTS</b></font>
</p><ul><font size="2"></font><font size="2">a) </font><font size="2">Subject to the terms of this Agreement, each Contributor hereby grants</font><font size="2"> Recipient a non-exclusive, worldwide, royalty-free copyright license to</font><font color="#ff0000" size="2"> </font><font size="2">reproduce,
prepare derivative works of, publicly display, publicly perform,
distribute and sublicense the Contribution of such Contributor, if any,
and such derivative works, in source code and object code form.</font></ul>
<ul><font size="2"></font></ul>
<ul><font size="2"></font><font size="2">b) Subject to the terms of this Agreement, each Contributor hereby grants </font><font size="2">Recipient a non-exclusive, worldwide,</font><font color="#008000" size="2"> </font><font size="2">royalty-free
patent license under Licensed Patents to make, use, sell, offer to
sell, import and otherwise transfer the Contribution of such
Contributor, if any, in source code and object code form. This patent
license shall apply to the combination of the Contribution and the
Program if, at the time the Contribution is added by the Contributor,
such addition of the Contribution causes such combination to be covered
by the Licensed Patents. The patent license shall not apply to any
other combinations which include the Contribution. No hardware per se
is licensed hereunder. </font></ul>
<ul><font size="2"></font></ul>
<ul><font size="2">c) Recipient understands that although each
Contributor grants the licenses to its Contributions set forth herein,
no assurances are provided by any Contributor that the Program does not
infringe the patent or other intellectual property rights of any other
entity. Each Contributor disclaims any liability to Recipient for
claims brought by any other entity based on infringement of
intellectual property rights or otherwise. As a condition to exercising
the rights and licenses granted hereunder, each Recipient hereby
assumes sole responsibility to secure any other intellectual property
rights needed, if any. For example, if a third party patent license is
required to allow Recipient to distribute the Program, it is
Recipient's responsibility to acquire that license before distributing
the Program.</font></ul>
<ul><font size="2"></font></ul>
<ul><font size="2">d) Each Contributor represents that to its knowledge
it has sufficient copyright rights in its Contribution, if any, to
grant the copyright license set forth in this Agreement. </font></ul>
<ul><font size="2"></font></ul>
<p><font size="2"><b>3. REQUIREMENTS</b></font>
</p><p><font size="2"><b></b>A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that:</font>
</p><ul><font size="2">a) it complies with the terms and conditions of this Agreement; and</font></ul>
<ul><font size="2">b) its license agreement:</font></ul>
<ul><font size="2">i) effectively disclaims</font><font face="Times New Roman" size="2">
on behalf of all Contributors all warranties and conditions, express
and implied, including warranties or conditions of title and
non-infringement, and implied warranties or conditions of
merchantability and fitness for a particular purpose; </font></ul>
<ul><font face="Times New Roman" size="2">ii) effectively excludes on
behalf of all Contributors all liability for damages, including direct,
indirect, special, incidental and consequential damages, such as lost
profits; </font></ul>
<ul><font face="Times New Roman" size="2">iii)</font><font size="2">
states that any provisions which differ from this Agreement are offered
by that Contributor alone and not by any other party; and</font></ul>
<ul><font size="2">iv) states that source code for the Program is
available from such Contributor, and informs licensees how to obtain it
in a reasonable manner on or through a medium customarily used for
software exchange.</font><font color="#0000ff" size="2"> </font><font color="#ff0000" size="2"></font></ul>
<ul><font color="#ff0000" size="2"></font><font size="2"></font></ul>
<p><font size="2">When the Program is made available in source code form:</font>
</p><ul><font size="2">a) it must be made available under this Agreement; and </font></ul>
<ul><font size="2">b) a copy of this Agreement must be included with each copy of the Program. </font></ul>
<p><font size="2"></font><font color="#0000ff" size="2"><strike></strike></font>
</p><p><font color="#0000ff" size="2"><strike></strike></font><font size="2">Contributors may not remove or alter any copyright notices contained within the Program. </font>
</p><p><font size="2"></font>
</p><p><font size="2">Each Contributor must identify itself as the
originator of its Contribution, if any, in a manner that reasonably
allows subsequent Recipients to identify the originator of the
Contribution. </font>
</p><p><font size="2"></font>
</p><p><font size="2"><b>4. COMMERCIAL DISTRIBUTION</b></font>
</p><p><font size="2">Commercial distributors of software may accept
certain responsibilities with respect to end users, business partners
and the like. While this license is intended to facilitate the
commercial use of the Program, the Contributor who includes the Program
in a commercial product offering should do so in a manner which does
not create potential liability for other Contributors. Therefore, if a
Contributor includes the Program in a commercial product offering, such
Contributor ("Commercial Contributor") hereby agrees to defend and
indemnify every other Contributor ("Indemnified Contributor") against
any losses, damages and costs (collectively "Losses") arising from
claims, lawsuits and other legal actions brought by a third party
against the Indemnified Contributor to the extent caused by the acts or
omissions of such Commercial Contributor in connection with its
distribution of the Program in a commercial product offering. The
obligations in this section do not apply to any claims or Losses
relating to any actual or alleged intellectual property infringement.
In order to qualify, an Indemnified Contributor must: a) promptly
notify the Commercial Contributor in writing of such claim, and b)
allow the Commercial Contributor to control, and cooperate with the
Commercial Contributor in, the defense and any related settlement
negotiations. The Indemnified Contributor may participate in any such
claim at its own expense.</font>
</p><p><font size="2"></font>
</p><p><font size="2">For example, a Contributor might include the
Program in a commercial product offering, Product X. That Contributor
is then a Commercial Contributor. If that Commercial Contributor then
makes performance claims, or offers warranties related to Product X,
those performance claims and warranties are such Commercial
Contributor's responsibility alone. Under this section, the Commercial
Contributor would have to defend claims against the other Contributors
related to those performance claims and warranties, and if a court
requires any other Contributor to pay any damages as a result, the
Commercial Contributor must pay those damages.</font>
</p><p><font size="2"></font><font color="#0000ff" size="2"></font>
</p><p><font color="#0000ff" size="2"></font><font size="2"><b>5. NO WARRANTY</b></font>
</p><p><font size="2">EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT,
THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is</font><font size="2"> solely responsible for determining the appropriateness of using and distributing </font><font size="2">the Program</font><font size="2"> and assumes all risks associated with its exercise of rights under this Agreement</font><font size="2">,
including but not limited to the risks and costs of program errors,
compliance with applicable laws, damage to or loss of data, </font><font size="2">programs or equipment, and unavailability or interruption of operations</font><font size="2">. </font><font size="2"></font>
</p><p><font size="2"></font>
</p><p><font size="2"></font><font size="2"><b>6. DISCLAIMER OF LIABILITY</b></font>
</p><p><font size="2"></font><font size="2">EXCEPT AS EXPRESSLY SET
FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL
HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES </font><font face="Times New Roman" size="2">(INCLUDING WITHOUT LIMITATION LOST PROFITS),</font><font size="2">
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE
EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.</font>
</p><p><font size="2"></font><font size="2"></font>
</p><p><font size="2"><b>7. GENERAL</b></font>
</p><p><font size="2"></font><font size="2">If any provision of this
Agreement is invalid or unenforceable under applicable law, it shall
not affect the validity or enforceability of the remainder of the terms
of this Agreement, and without further action by the parties hereto,
such provision shall be reformed to the minimum extent necessary to
make such provision valid and enforceable.</font>
</p><p><font size="2"></font>
</p><p><font size="2">If Recipient institutes patent litigation against
a Contributor with respect to a patent applicable to software
(including a cross-claim or counterclaim in a lawsuit), then any patent
licenses granted by that Contributor to such Recipient under this
Agreement shall terminate as of the date such litigation is filed. In
addition, if Recipient institutes patent litigation against any entity
(including a cross-claim or counterclaim in a lawsuit) alleging that
the Program itself (excluding combinations of the Program with other
software or hardware) infringes such Recipient's patent(s), then such
Recipient's rights granted under Section 2(b) shall terminate as of the
date such litigation is filed. </font><font size="2"></font>
</p><p><font size="2"></font>
</p><p><font size="2">All Recipient's rights under this Agreement shall
terminate if it fails to comply with any of the material terms or
conditions of this Agreement and does not cure such failure in a
reasonable period of time after becoming aware of such noncompliance.
If all Recipient's rights under this Agreement terminate, Recipient
agrees to cease use and distribution of the Program as soon as
reasonably practicable. However, Recipient's obligations under this
Agreement and any licenses granted by Recipient relating to the Program
shall continue and survive. </font><font size="2"></font>
</p><p><font size="2"></font>
</p><p><font size="2"></font><font face="Times New Roman" size="2">Everyone
is permitted to copy and distribute copies of this Agreement, but in
order to avoid inconsistency the Agreement is copyrighted and may only
be modified in the following manner. The Agreement Steward reserves the
right to </font><font size="2">publish new versions (including revisions) of this Agreement from time to </font><font face="Times New Roman" size="2">time.
No one other than the Agreement Steward has the right to modify this
Agreement. IBM is the initial Agreement Steward. IBM may assign the
responsibility to serve as the Agreement Steward to a suitable separate
entity. </font><font size="2">Each new version of the Agreement will
be given a distinguishing version number. The Program (including
Contributions) may always be distributed subject to the version of the
Agreement under which it was received. In addition, after a new version
of the Agreement is published, Contributor may elect to distribute the
Program (including its Contributions) under the new </font><font face="Times New Roman" size="2">version. </font><font size="2">Except
as expressly stated in Sections 2(a) and 2(b) above, Recipient receives
no rights or licenses to the intellectual property of any Contributor
under this Agreement, whether expressly, </font><font size="2">by implication, estoppel or otherwise</font><font size="2">.</font><font size="2"> All rights in the Program not expressly granted under this Agreement are reserved.</font>
</p><p><font size="2"></font>
</p><p><font size="2">This Agreement is governed by the laws of the
State of New York and the intellectual property laws of the United
States of America. No party to this Agreement will bring a legal action
under this Agreement more than one year after the cause of action
arose. Each party waives its rights to a jury trial in any resulting
litigation.</font>
</p><p><font size="2"></font><font size="2"></font>
</p><p><font size="2"></font>
</p></body></html>

@ -0,0 +1,238 @@
Common Public License - v 1.0
THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON
PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF
THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
1. DEFINITIONS
"Contribution" means:
a) in the case of the initial Contributor, the initial code and
documentation distributed under this Agreement, and
b) in the case of each subsequent Contributor:
i) changes to the Program, and
ii) additions to the Program;
where such changes and/or additions to the Program originate
from and are distributed by that particular Contributor. A
Contribution 'originates' from a Contributor if it was added to the
Program by such Contributor itself or anyone acting on such
Contributor's behalf. Contributions do not include additions to the
Program which: (i) are separate modules of software distributed in
conjunction with the Program under their own license agreement, and
(ii) are not derivative works of the Program.
"Contributor" means any person or entity that distributes the Program.
"Licensed Patents " mean patent claims licensable by a Contributor
which are necessarily infringed by the use or sale of its Contribution
alone or when combined with the Program.
"Program" means the Contributions distributed in accordance with this
Agreement.
"Recipient" means anyone who receives the Program under this
Agreement, including all Contributors.
2. GRANT OF RIGHTS
a) Subject to the terms of this Agreement, each Contributor
hereby grants Recipient a non-exclusive, worldwide, royalty-free
copyright license to reproduce, prepare derivative works of,
publicly display, publicly perform, distribute and sublicense
the Contribution of such Contributor, if any, and such
derivative works, in source code and object code form.
b) Subject to the terms of this Agreement, each Contributor
hereby grants Recipient a non-exclusive, worldwide, royalty-free
patent license under Licensed Patents to make, use, sell, offer
to sell, import and otherwise transfer the Contribution of such
Contributor, if any, in source code and object code form. This
patent license shall apply to the combination of the
Contribution and the Program if, at the time the Contribution is
added by the Contributor, such addition of the Contribution
causes such combination to be covered by the Licensed
Patents. The patent license shall not apply to any other
combinations which include the Contribution. No hardware per se
is licensed hereunder.
c) Recipient understands that although each Contributor grants
the licenses to its Contributions set forth herein, no
assurances are provided by any Contributor that the Program does
not infringe the patent or other intellectual property rights of
any other entity. Each Contributor disclaims any liability to
Recipient for claims brought by any other entity based on
infringement of intellectual property rights or otherwise. As a
condition to exercising the rights and licenses granted
hereunder, each Recipient hereby assumes sole responsibility to
secure any other intellectual property rights needed, if
any. For example, if a third party patent license is required to
allow Recipient to distribute the Program, it is Recipient's
responsibility to acquire that license before distributing the
Program.
d) Each Contributor represents that to its knowledge it has
sufficient copyright rights in its Contribution, if any, to
grant the copyright license set forth in this Agreement.
3. REQUIREMENTS
A Contributor may choose to distribute the Program in object code form
under its own license agreement, provided that:
a) it complies with the terms and conditions of this Agreement;
and
b) its license agreement:
i) effectively disclaims on behalf of all Contributors all
warranties and conditions, express and implied, including
warranties or conditions of title and non-infringement, and
implied warranties or conditions of merchantability and fitness
for a particular purpose;
ii) effectively excludes on behalf of all Contributors all
liability for damages, including direct, indirect, special,
incidental and consequential damages, such as lost profits;
iii) states that any provisions which differ from this Agreement
are offered by that Contributor alone and not by any other
party; and
iv) states that source code for the Program is available from
such Contributor, and informs licensees how to obtain it in a
reasonable manner on or through a medium customarily used for
software exchange.
When the Program is made available in source code form:
a) it must be made available under this Agreement; and
b) a copy of this Agreement must be included with each copy of
the Program.
Contributors may not remove or alter any copyright notices contained
within the Program.
Each Contributor must identify itself as the originator of its
Contribution, if any, in a manner that reasonably allows subsequent
Recipients to identify the originator of the Contribution.
4. COMMERCIAL DISTRIBUTION
Commercial distributors of software may accept certain
responsibilities with respect to end users, business partners and the
like. While this license is intended to facilitate the commercial use
of the Program, the Contributor who includes the Program in a
commercial product offering should do so in a manner which does not
create potential liability for other Contributors. Therefore, if a
Contributor includes the Program in a commercial product offering,
such Contributor ("Commercial Contributor") hereby agrees to defend
and indemnify every other Contributor ("Indemnified Contributor")
against any losses, damages and costs (collectively "Losses") arising
from claims, lawsuits and other legal actions brought by a third party
against the Indemnified Contributor to the extent caused by the acts
or omissions of such Commercial Contributor in connection with its
distribution of the Program in a commercial product offering. The
obligations in this section do not apply to any claims or Losses
relating to any actual or alleged intellectual property
infringement. In order to qualify, an Indemnified Contributor must: a)
promptly notify the Commercial Contributor in writing of such claim,
and b) allow the Commercial Contributor to control, and cooperate with
the Commercial Contributor in, the defense and any related settlement
negotiations. The Indemnified Contributor may participate in any such
claim at its own expense.
For example, a Contributor might include the Program in a commercial
product offering, Product X. That Contributor is then a Commercial
Contributor. If that Commercial Contributor then makes performance
claims, or offers warranties related to Product X, those performance
claims and warranties are such Commercial Contributor's responsibility
alone. Under this section, the Commercial Contributor would have to
defend claims against the other Contributors related to those
performance claims and warranties, and if a court requires any other
Contributor to pay any damages as a result, the Commercial Contributor
must pay those damages.
5. NO WARRANTY
EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS
PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY
OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely
responsible for determining the appropriateness of using and
distributing the Program and assumes all risks associated with its
exercise of rights under this Agreement, including but not limited to
the risks and costs of program errors, compliance with applicable
laws, damage to or loss of data, programs or equipment, and
unavailability or interruption of operations.
6. DISCLAIMER OF LIABILITY
EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR
ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING
WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR
DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
7. GENERAL
If any provision of this Agreement is invalid or unenforceable under
applicable law, it shall not affect the validity or enforceability of
the remainder of the terms of this Agreement, and without further
action by the parties hereto, such provision shall be reformed to the
minimum extent necessary to make such provision valid and enforceable.
If Recipient institutes patent litigation against a Contributor with
respect to a patent applicable to software (including a cross-claim or
counterclaim in a lawsuit), then any patent licenses granted by that
Contributor to such Recipient under this Agreement shall terminate as
of the date such litigation is filed. In addition, if Recipient
institutes patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Program
itself (excluding combinations of the Program with other software or
hardware) infringes such Recipient's patent(s), then such Recipient's
rights granted under Section 2(b) shall terminate as of the date such
litigation is filed.
All Recipient's rights under this Agreement shall terminate if it
fails to comply with any of the material terms or conditions of this
Agreement and does not cure such failure in a reasonable period of
time after becoming aware of such noncompliance. If all Recipient's
rights under this Agreement terminate, Recipient agrees to cease use
and distribution of the Program as soon as reasonably
practicable. However, Recipient's obligations under this Agreement and
any licenses granted by Recipient relating to the Program shall
continue and survive.
Everyone is permitted to copy and distribute copies of this Agreement,
but in order to avoid inconsistency the Agreement is copyrighted and
may only be modified in the following manner. The Agreement Steward
reserves the right to publish new versions (including revisions) of
this Agreement from time to time. No one other than the Agreement
Steward has the right to modify this Agreement. IBM is the initial
Agreement Steward. IBM may assign the responsibility to serve as the
Agreement Steward to a suitable separate entity. Each new version of
the Agreement will be given a distinguishing version number. The
Program (including Contributions) may always be distributed subject to
the version of the Agreement under which it was received. In addition,
after a new version of the Agreement is published, Contributor may
elect to distribute the Program (including its Contributions) under
the new version. Except as expressly stated in Sections 2(a) and 2(b)
above, Recipient receives no rights or licenses to the intellectual
property of any Contributor under this Agreement, whether expressly,
by implication, estoppel or otherwise. All rights in the Program not
expressly granted under this Agreement are reserved.
This Agreement is governed by the laws of the State of New York and
the intellectual property laws of the United States of America. No
party to this Agreement will bring a legal action under this Agreement
more than one year after the cause of action arose. Each party waives
its rights to a jury trial in any resulting litigation.

@ -0,0 +1,381 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html40/strict.dtd">
<HTML LANG="en-US">
<HEAD>
<TITLE>GNU General Public License</TITLE>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=us-ascii">
<META HTTP-EQUIV="Content-Language" CONTENT="en-US">
<META NAME="description" CONTENT="GNU general public license (for inclusion in distributions)">
<META NAME="keywords" CONTENT="gnu, Gnu, GNU, license, licence, software, free software, software license, software licence, GNU general public license, GNU General Public License">
<META NAME="robots" CONTENT="none">
<META HTTP-EQUIV="Content-Style-Type" CONTENT="text/css">
<LINK REL="stylesheet" HREF="kde-default.css" TYPE="text/css">
</HEAD>
<BODY CLASS="license">
<H1>GNU General Public License</H1>
<P>Version 2, June 1991</P>
<P>Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA<BR>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.</P>
<H2>Preamble</H2>
<P>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.</P>
<P>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.</P>
<P>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.</P>
<P>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.</P>
<P>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.</P>
<P>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.</P>
<P>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.</P>
<P>The precise terms and conditions for copying, distribution and
modification follow.</P>
<H2><A NAME="show-c">GNU General Public License<BR>
Terms And Conditions For Copying, Distribution And Modification</A></H2>
<P>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".</P>
<P>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.</P>
<P>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.</P>
<P>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.</P>
<P>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:</P>
<OL STYLE="list-style-type: lower-alpha;">
<LI>
<P>You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.</P>
</LI>
<LI>
<P>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.</P>
</LI>
<LI>
<P>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.)</P>
</LI>
</OL>
<P>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.</P>
<P>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.</P>
<P>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.</P>
<P>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:</P>
<OL STYLE="list-style-type: lower-alpha;">
<LI>
<P>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,</P>
</LI>
<LI>
<P>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,</P>
</LI>
<LI>
<P>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.)</P>
</LI>
</OL>
<P>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.</P>
<P>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.</P>
<P>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.</P>
<P>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.</P>
<P>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.</P>
<P>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.</P>
<P>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.</P>
<P>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.</P>
<P>This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.</P>
<P>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.</P>
<P>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.</P>
<P>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.</P>
<P>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.</P>
<H2><A NAME="show-w">No Warranty</A></H2>
<P>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.</P>
<P>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.</P>
<DIV STYLE="text-align: center;">END OF TERMS AND CONDITIONS</DIV>
<hr>
<h2>How to Apply These Terms to Your New Programs</h2>
<p>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.</p>
<p>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.</p>
<pre> &lt;one line to give the program's name and a brief idea of what it does.&gt;
Copyright (C) 19yy &lt;name of author&gt;
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</pre>
<p>Also add information on how to contact you by electronic and paper
mail.</p>
<p>If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:</p>
<pre> Gnomovision version 69, Copyright (C) 19yy 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.</pre>
<p>The hypothetical commands &quot;show w&quot; and &quot;show c&quot; should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than &quot;show w&quot; and &quot;show c&quot;; they could even be
mouse-clicks or menu items--whatever suits your program.</p>
<p>You should also get your employer (if you work as a programmer) or your
school, if any, to sign a &quot;copyright disclaimer&quot; for the program, if
necessary. Here is a sample; alter the names:</p>
<pre> Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
&lt;signature of Ty Coon&gt;, 1 April 1989
Ty Coon, President of Vice</pre>
<p>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.</p>
</BODY>
</HTML>

@ -0,0 +1,340 @@
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.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
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) 19yy 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.
<signature of Ty Coon>, 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.

@ -0,0 +1,254 @@
# ***************************************************** -*- Makefile -*-
#
# Copyright (c) 2004 Andreas Huggel
#
# Todo: Insert the license blabla here
#
# Author(s): Andreas Huggel (ahu)
#
# RCS information
# $Name: $
# $Revision: 1.1 $
#
# Description:
# Do NOT change this file! All system specific settings and configs
# go into config.mk.
#
# This makefile contains (supposedly) generic build rules to build a
# library and applications. It includes all system specific settings
# from config.mk. The idea is that configuring and porting the
# software to a new platform should only require changes in config.mk.
#
# Adding new source files or applications: Just add an entry with the
# name of the new file in the section 'Source files' below.
#
# Restrictions:
# Requires GNU make.
#
# Default make target
all: lib bin
# Include system configuration
top_srcdir = ..
include $(top_srcdir)/config.mk
# **********************************************************************
# Source files
# Add standalone C++ header files to this list
CCHDR =
# Add library C++ source files to this list
CCSRC = exif.cc utils.cc
# Add source files of applications to this list
BINSRC = exiftest.cc
# **********************************************************************
# Library
LIBNAME = exiv2
# **********************************************************************
# Defines, Includes and Libraries
CXXDEFS = $(DEFS)
CXXINCS = $(INCS)
LDLIBS = $(LIBS) -l$(LIBNAME)
# **********************************************************************
# ======================================================================
# **********************************************************************
# Initialisations
SHELL = /bin/sh
.SUFFIXES:
.SUFFIXES: .cc .o .so
.PRECIOUS: %.cc
# Generic variables
CCHDR := $(CCHDR) $(CCSRC:.cc=.h)
CCOBJ = $(CCSRC:.cc=.o)
CCSOBJ = $(CCSRC:.cc=.so)
SRC = $(CCSRC)
HDR = $(CCHDR)
OBJ = $(CCOBJ)
SOBJ = $(CCSOBJ)
DEP = $(CCSRC:%.cc=.%.d) $(BINSRC:%.cc=.%.d)
BINOBJ = $(BINSRC:.cc=.o)
BINARY = $(BINSRC:.cc=)
ARCHIVE = lib$(LIBNAME)$(ARCHIVE_SUFFIX)
SHAREDLIB = lib$(LIBNAME)$(SHAREDLIB_SUFFIX)
# **********************************************************************
# Assemble the dependencies for the 'lib' target and corresponding
# (un)install targets. If neither STATIC_LIBS nor SHARED_LIBS is
# defined, 'lib' does nothing.
ifdef STATIC_LIBS
LIBRARY = archive
INSTALL = bin
INSTALL_LIB = install-archive
UNINSTALL_LIB = uninstall-archive
endif
ifdef SHARED_LIBS
LIBRARY := $(LIBRARY) sharedlib
INSTALL = bin install-sharedlib
INSTALL_LIB := $(INSTALL_LIB) install-sharedlib
UNINSTALL_LIB := $(UNINSTALL_LIB) uninstall-sharedlib
endif
# **********************************************************************
# Include `.*.d' files, but only if we need them,
# i.e., if no target was given...
ifeq ($(strip $(MAKECMDGOALS)),)
-include $(DEP)
else
# ...or the target is _not_ one in the list of targets below.
NOINCLUDE = uninstall uninstall-lib check doc mostlyclean clean \
install-header uninstall-header distclean maintainer-clean \
uninstall-archive uninstall-sharedlib
ifneq ($(MAKECMDGOALS), $(filter $(MAKECMDGOALS), $(NOINCLUDE)))
-include $(DEP)
endif
endif
# **********************************************************************
# Rules
%.o: %.cc
$(CXX) $(CXXFLAGS_STATIC) $(CXXDEFS) $(CXXINCS) -c $< -o $@
%.so: %.cc
$(CXX) $(CXXFLAGS_SHARED) $(CXXDEFS) $(CXXINCS) -c $< -o $@
%.ii: %.cc
set -e; \
$(CXXCPP) $(CPPFLAGS) $(CXXDEFS) $(CXXINCS) $< \
| sed '/^[ ]*$$/d' > $@
# generate a makefile with the prerequisites for each source file
# (see `info make' for details)
.%.d: %.cc
@echo generating $@
@set -e; \
$(CXXDEP) $(CPPFLAGS) $(CXXDEFS) $(CXXINCS) $< \
| sed 's/\($*\)\.o[ :]*/\1.o \1.so $@ : /' > $@; \
[ -s $@ ] || rm -f $@
$(BINARY): %: %.o
$(CXX) $(CXXFLAGS) $< $(LDLIBS) $(LDFLAGS_BIN) -o $@
# **********************************************************************
# Targets
.PHONY: all archive sharedlib bin check doc \
clean mostlyclean distclean maintainer-clean \
install install-archive install-header \
install-sharedlib install-lib \
uninstall uninstall-archive uninstall-header \
uninstall-sharedlib uninstall-lib \
$(ARCHIVE)($(OBJ)): $(OBJ)
@$(AR) $(ARFLAGS) $@ $%
$(ARCHIVE): $(ARCHIVE)($(OBJ))
@if test -n "$(CXX_REPOSITORY)"; then \
find $(CXX_REPOSITORY) -name "*.o" -type f | \
xargs $(AR) $(ARFLAGS) $@; \
fi
$(RANLIB) $@
archive: $(ARCHIVE)
$(SHAREDLIB): $(SOBJ)
$(CXX) $^ $(PMTLIBS) $(LDFLAGS_SHARED) -o $@
sharedlib: $(SHAREDLIB)
lib: $(LIBRARY)
# Re-link executables whenever the static library changes
ifdef STATIC_LIBS
$(BINARY): $(ARCHIVE)
endif
bin: lib $(BINARY)
install install-bin: $(INSTALL)
mkinstalldirs $(bindir)
@list='$(BINARY)'; for p in $$list; do \
if test -f $$p; then \
echo "$(INSTALL_PROGRAM) $$p $(bindir)/$$p"; \
$(INSTALL_PROGRAM) $$p $(bindir)/$$p; \
else :; fi; \
done
install-header:
mkinstalldirs $(incdir)
@list='$(HDR)'; for p in $$list; do \
if test -f $$p; then \
echo "$(INSTALL_DATA) $$p $(incdir)/$$p"; \
$(INSTALL_DATA) $$p $(incdir)/$$p; \
else :; fi; \
done
install-archive: archive
mkinstalldirs $(libdir)
$(INSTALL_DATA) $(ARCHIVE) $(libdir)/$(ARCHIVE)
install-sharedlib: sharedlib
mkinstalldirs $(libdir)
$(INSTALL_DATA) $(SHAREDLIB) $(libdir)/$(SHAREDLIB)
install-lib: $(INSTALL_LIB) install-header
uninstall:
@list='$(BINARY)'; for p in $$list; do \
echo "rm -f $(bindir)/$$p"; \
rm -f $(bindir)/$$p; \
done
uninstall-header:
@list='$(HDR)'; for p in $$list; do \
echo "rm -f $(incdir)/$$p"; \
rm -f $(incdir)/$$p; \
done
uninstall-archive:
$(RM) $(libdir)/$(ARCHIVE)
uninstall-sharedlib:
$(RM) $(libdir)/$(SHAREDLIB)
uninstall-lib: $(UNINSTALL_LIB) uninstall-header
check:
@echo "No checks available for this library."
mostlyclean:
$(RM) core
$(RM) $(CCSRC:.cc=.ii)
$(RM) $(OBJ) $(SOBJ) $(BINOBJ)
@if test -n "$(CXX_REPOSITORY)"; then \
echo "rm -rf $(CXX_REPOSITORY)"; \
rm -rf $(CXX_REPOSITORY); \
fi
clean: mostlyclean
$(RM) $(ARCHIVE) $(SHAREDLIB)
$(RM) $(BINARY)
# Run `make distclean' from the top source directory to also remove
# files created by configuring the program.
distclean: clean
$(RM) tags TAGS
$(RM) $(DEP)
$(RM) *~ *#
# This command is intended for maintainers to use; it deletes files
# that may need special tools to rebuild.
maintainer-clean: uninstall uninstall-lib distclean
rm -rf $(top_srcdir)/html/*

@ -0,0 +1,659 @@
// ***************************************************************** -*- C++ -*-
/*
* Copyright (c) 2004 Andreas Huggel
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.ibm.com/developerworks/oss/CPLv1.0.htm
*/
/*
Author(s): Andreas Huggel (ahu)
History:
13-Jan-04, ahu: created
RCS information
$Name: $
$Revision: 1.1 $
*/
// *****************************************************************************
// included header files
#include "exif.h"
// + PMT includes
// + standard includes
#include <iostream>
#include <iomanip>
#include <sstream>
#include <fstream>
#include <cstring>
// *****************************************************************************
// local declarations
namespace {
// Compare two IFD entries by offset, taking care of special cases
// where one or both of the entries don't have an offset.
bool cmpOffset(const Exif::Metadatum& lhs, const Exif::Metadatum& rhs);
}
// *****************************************************************************
// class member definitions
namespace Exif {
JpegImage::JpegImage()
: sizeExifData_(0), offsetExifData_(0), exifData_(0)
{
}
JpegImage::~JpegImage()
{
delete exifData_;
}
const uint16 JpegImage::soi_ = 0xffd8;
const uint16 JpegImage::app1_ = 0xffe1;
const char JpegImage::exifId_[] = "Exif\0\0";
bool JpegImage::isJpeg(std::istream& is)
{
char c;
is.get(c);
if (!is.good()) return false;
if (static_cast<char>((soi_ & 0xff00) >> 8) != c) {
is.unget();
return false;
}
is.get(c);
if (!is.good()) return false;
if (static_cast<char>(soi_ & 0x00ff) != c) {
is.unget();
return false;
}
return true;
}
int JpegImage::readExifData(const std::string& path)
{
std::ifstream file(path.c_str());
if (!file) return -1;
return readExifData(file);
}
int JpegImage::readExifData(std::istream& is)
{
// Check if this is a JPEG image in the first place
if (!isJpeg(is)) {
if (!is.good()) return 1;
return 2;
}
// Todo: implement this properly: the APP1 segment may not follow
// immediately after SOI.
char marker[2];
marker[0] = '\0';
marker[1] = '\0';
long offsetApp1 = 2;
// Read the APP1 marker
is.read(marker, 2);
if (!is.good()) return 1;
// Check the APP1 marker
if (getUShort(marker, bigEndian) != app1_) return 3;
// Read the length of the APP1 field and the Exif identifier
char buf[8];
::memset(buf, 0x0, 8);
is.read(buf, 8);
if (!is.good()) return 1;
// Get the length of the APP1 field and do a plausibility check
long app1Length = getUShort(buf, bigEndian);
if (app1Length < 8) return 4;
// Check the Exif identifier
if (::memcmp(buf+2, exifId_, 6) != 0) return 4;
// Read the rest of the APP1 field (Exif data)
long sizeExifData = app1Length - 8;
exifData_ = new char[sizeExifData];
::memset(exifData_, 0x0, sizeExifData);
is.read(exifData_, sizeExifData);
if (!is.good()) {
delete[] exifData_;
exifData_ = 0;
return 1;
}
// Finally, set the size and offset of the Exif data buffer
sizeExifData_ = sizeExifData;
offsetExifData_ = offsetApp1 + 10;
return 0;
} // JpegImage::readExifData
TiffHeader::TiffHeader()
: byteOrder_(littleEndian), tag_(0x002a), offset_(0x00000008)
{
}
int TiffHeader::read(const char* buf)
{
if (buf[0] == 0x49 && buf[1] == 0x49) {
byteOrder_ = littleEndian;
}
else if (buf[0] == 0x4d && buf[1] == 0x4d) {
byteOrder_ = bigEndian;
}
else {
return 1;
}
tag_ = getUShort(buf+2, byteOrder_);
offset_ = getULong(buf+4, byteOrder_);
return 0;
}
void TiffHeader::data(char* buf) const
{
switch (byteOrder_) {
case littleEndian:
buf[0] = 0x49;
buf[1] = 0x49;
break;
case bigEndian:
buf[0] = 0x4d;
buf[1] = 0x4d;
break;
}
us2Data(buf+2, tag_, byteOrder_);
ul2Data(buf+4, offset_, byteOrder_);
}
Format::Format(uint16 type, const std::string& name, long size)
: type_(type), name_(name), size_(size)
{
}
//! Lookup list of IFD tag data formats and their properties
static const Format tagDataFormat[] = {
Format( 0, "invalid", 0),
Format( 1, "unsigned byte", 1),
Format( 2, "ascii strings", 1),
Format( 3, "unsigned short", 2),
Format( 4, "unsigned long", 4),
Format( 5, "unsigned rational", 8),
Format( 6, "signed byte", 1),
Format( 7, "undefined", 1),
Format( 8, "signed short", 2),
Format( 9, "signed long", 4),
Format(10, "signed rational", 8),
Format(11, "single float", 4),
Format(12, "double float", 8)
};
TagInfo::TagInfo(
uint16 tag,
const std::string& fieldName,
const std::string& tagName,
IfdId ifdId,
TagSection tagSection
)
: tag_(tag), fieldName_(fieldName), tagName_(tagName),
ifdId_(ifdId), tagSection_(tagSection)
{
}
//! Lookup list with tags, their names and where they belong to
static const TagInfo tagInfo[] = {
TagInfo(0x0100, "ImageWidth", "Image width", ifd0, ifd0Tiff),
TagInfo(0x0101, "ImageLength", "Image height", ifd0, ifd0Tiff),
TagInfo(0x0102, "BitsPerSample", "Number of bits per component", ifd0, ifd0Tiff),
TagInfo(0x0103, "Compression", "Compression scheme", ifd0, ifd0Tiff),
TagInfo(0x0106, "PhotometricInterpretation", "Pixel composition", ifd0, ifd0Tiff),
TagInfo(0x010e, "ImageDescription", "Image title", ifd0, ifd0Tiff),
TagInfo(0x010f, "Make", "Manufacturer of image input equipment", ifd0, ifd0Tiff),
TagInfo(0x0110, "Model", "Model of image input equipment", ifd0, ifd0Tiff),
TagInfo(0x0111, "StripOffsets", "Image data location", ifd0, ifd0Tiff),
TagInfo(0x0112, "Orientation", "Orientation of image", ifd0, ifd0Tiff),
TagInfo(0x0115, "SamplesPerPixel", "Number of components", ifd0, ifd0Tiff),
TagInfo(0x0116, "RowsPerStrip", "Number of rows per strip", ifd0, ifd0Tiff),
TagInfo(0x0117, "StripByteCounts", "Bytes per compressed strip", ifd0, ifd0Tiff),
TagInfo(0x011a, "XResolution", "Image resolution in width direction", ifd0, ifd0Tiff),
TagInfo(0x011b, "YResolution", "Image resolution in height direction", ifd0, ifd0Tiff),
TagInfo(0x011c, "PlanarConfiguration", "Image data arrangement", ifd0, ifd0Tiff),
TagInfo(0x0128, "ResolutionUnit", "Unit of X and Y resolution", ifd0, ifd0Tiff),
TagInfo(0x012d, "TransferFunction", "Transfer function", ifd0, ifd0Tiff),
TagInfo(0x0131, "Software", "Software used", ifd0, ifd0Tiff),
TagInfo(0x0132, "DateTime", "File change date and time", ifd0, ifd0Tiff),
TagInfo(0x013b, "Artist", "Person who created the image", ifd0, ifd0Tiff),
TagInfo(0x013e, "WhitePoint", "White point chromaticity", ifd0, ifd0Tiff),
TagInfo(0x013f, "PrimaryChromaticities", "Chromaticities of primaries", ifd0, ifd0Tiff),
TagInfo(0x0201, "JPEGInterchangeFormat", "Offset to JPEG SOI", ifd0, ifd0Tiff),
TagInfo(0x0202, "JPEGInterchangeFormatLength", "Bytes of JPEG data", ifd0, ifd0Tiff),
TagInfo(0x0211, "YCbCrCoefficients", "Color space transformation matrix coefficients", ifd0, ifd0Tiff),
TagInfo(0x0212, "YCbCrSubSampling", "Subsampling ratio of Y to C", ifd0, ifd0Tiff),
TagInfo(0x0213, "YCbCrPositioning", "Y and C positioning", ifd0, ifd0Tiff),
TagInfo(0x0214, "ReferenceBlackWhite", "Pair of black and white reference values", ifd0, ifd0Tiff),
TagInfo(0x8298, "Copyright", "Copyright holder", ifd0, ifd0Tiff),
TagInfo(0x8769, "ExifTag", "Exif IFD Pointer", ifd0, ifd0Tiff),
TagInfo(0x8825, "GPSTag", "GPSInfo IFD Pointer", ifd0, ifd0Tiff)
};
Metadatum::Metadatum()
: tag_(0), type_(0), count_(0), offset_(0), size_(0),
ifdId_(unknown), ifdIdx_(-1), data_(0)
{
}
Metadatum::~Metadatum()
{
delete[] data_;
}
Metadatum::Metadatum(const Metadatum& rhs)
{
tag_ = rhs.tag_;
type_ = rhs.type_;
count_ = rhs.count_;
offset_ = rhs.offset_;
size_ = rhs.size_;
ifdId_ = rhs.ifdId_;
ifdIdx_ = rhs.ifdIdx_;
// deep copy
data_ = 0;
if (rhs.data_ != 0) {
data_ = new char[rhs.size_];
::memcpy(data_, rhs.data_, rhs.size_);
}
}
Metadatum& Metadatum::operator=(const Metadatum& rhs)
{
tag_ = rhs.tag_;
type_ = rhs.type_;
count_ = rhs.count_;
offset_ = rhs.offset_;
size_ = rhs.size_;
ifdId_ = rhs.ifdId_;
ifdIdx_ = rhs.ifdIdx_;
delete[] data_;
if (rhs.data_ != 0) {
data_ = new char[rhs.size_];
::memcpy(data_, rhs.data_, rhs.size_);
}
return *this;
}
Ifd::Ifd(IfdId ifdId)
: ifdId_(ifdId), offset_(0), next_(0), size_(0)
{
}
int Ifd::read(const char* buf, ByteOrder byteOrder, long offset)
{
offset_ = offset;
int n = getUShort(buf, byteOrder);
long o = 2;
for (int i=0; i<n; ++i) {
Metadatum e;
e.ifdId_ = ifdId_;
e.ifdIdx_ = i;
e.tag_ = getUShort(buf+o, byteOrder);
e.type_ = getUShort(buf+o+2, byteOrder);
e.count_ = getULong(buf+o+4, byteOrder);
// offset will be converted to a relative offset below
e.offset_ = getULong(buf+o+8, byteOrder);
e.size_ = e.count_ * tagDataFormat[e.type_].size_;
// data_ is set later, see below
entries_.push_back(e);
o += 12;
}
next_ = getULong(buf+o, byteOrder);
size_ = 2 + 12 * entries_.size() + 4;
// Guess the offset if it was not given. The guess is based
// on the assumption that the smallest offset points to a data
// buffer directly following the IFD.
// Subsequently all offsets of IFD entries need to be recalculated.
const Metadata::iterator eb = entries_.begin();
const Metadata::iterator ee = entries_.end();
Metadata::iterator i = eb;
if (offset_ == 0 && i != ee) {
// Find the entry with the smallest offset
i = std::min_element(eb, ee, cmpOffset);
// Set the guessed IFD offset
if (i->size_ > 4) {
offset_ = i->offset_ - size_;
}
}
// Assign the data to each IFD entry and
// calculate offsets relative to the start of the IFD
for (i = eb; i != ee; ++i) {
delete[] i->data_;
i->data_ = 0;
if (i->size_ > 4) {
i->offset_ = i->offset_ - offset_;
i->data_ = new char[i->size_];
::memcpy(i->data_, buf + i->offset_, i->size_);
}
else {
i->data_ = new char[4];
ul2Data(i->data_, i->offset_, byteOrder);
}
}
return 0;
} // Ifd::read
int Ifd::readSubIfd(
Ifd& dest, const char* buf, ByteOrder byteOrder, uint16 tag
) const
{
int rc = 0;
Metadata::const_iterator pos;
Metadata::const_iterator end = entries_.end();
pos = std::find_if(entries_.begin(), end, matchTag(tag));
if (pos != end) {
rc = dest.read(buf + pos->offset_, byteOrder, pos->offset_);
}
return rc;
} // Ifd::readSubIfd
char* Ifd::data(char* buf, ByteOrder byteOrder, long offset) const
{
if (offset == 0) offset = offset_;
// Add the number of entries to the data buffer
us2Data(buf, entries_.size(), byteOrder);
long o = 2;
// Add all directory entries to the data buffer
long dataSize = 0;
const Metadata::const_iterator b = entries_.begin();
const Metadata::const_iterator e = entries_.end();
Metadata::const_iterator i = b;
for (; i != e; ++i) {
us2Data(buf+o, i->tag_, byteOrder);
us2Data(buf+o+2, i->type_, byteOrder);
ul2Data(buf+o+4, i->count_, byteOrder);
if (i->size_ > 4) {
ul2Data(buf+o+8, offset + size_ + dataSize, byteOrder);
dataSize += i->size_;
}
else {
ul2Data(buf+o+8, i->offset_, byteOrder);
}
o += 12;
}
// Add the offset to the next IFD to the data buffer pointing
// directly behind this IFD and its data
if (next_ != 0) {
ul2Data(buf+o, offset + size_ + dataSize, byteOrder);
}
else {
ul2Data(buf+o, 0, byteOrder);
}
o += 4;
// Add the data of all IFD entries to the data buffer
for (i = b; i != e; ++i) {
if (i->size_ > 4) {
::memcpy(buf+o, i->data_, i->size_);
o += i->size_;
}
}
return buf;
} // Ifd::data
void Ifd::print(std::ostream& os, const std::string& prefix) const
{
if (entries_.size() == 0) return;
os << prefix << "IFD Offset: 0x"
<< std::setw(8) << std::setfill('0') << std::hex << std::right
<< offset_
<< ", IFD Entries: "
<< std::setfill(' ') << std::dec << std::right
<< entries_.size() << "\n"
<< prefix << "Entry Tag Format (Bytes each) Number Offset/Data\n"
<< prefix << "----- ------ --------------------- ------ -----------\n";
const Metadata::const_iterator b = entries_.begin();
const Metadata::const_iterator e = entries_.end();
Metadata::const_iterator i = b;
for (; i != e; ++i) {
std::ostringstream offset;
if (tagDataFormat[i->type_].size_ * i->count_ <= 4) {
// Minor cheat here: we use data_ instead of offset_ to avoid
// having to invoke ul2Data() which would require byte order.
offset << std::setw(2) << std::setfill('0') << std::hex
<< (int)*(unsigned char*)i->data_ << " "
<< std::setw(2) << std::setfill('0') << std::hex
<< (int)*(unsigned char*)(i->data_+1) << " "
<< std::setw(2) << std::setfill('0') << std::hex
<< (int)*(unsigned char*)(i->data_+2) << " "
<< std::setw(2) << std::setfill('0') << std::hex
<< (int)*(unsigned char*)(i->data_+3) << " ";
}
else {
offset << " 0x" << std::setw(8) << std::setfill('0') << std::hex
<< std::right << i->offset_;
}
os << prefix << std::setw(5) << std::setfill(' ') << std::dec
<< std::right << i - b
<< " 0x" << std::setw(4) << std::setfill('0') << std::hex
<< std::right << i->tag_
<< " " << std::setw(17) << std::setfill(' ')
<< std::left << tagDataFormat[i->type_].name_
<< " (" << std::dec << tagDataFormat[i->type_].size_ << ")"
<< " " << std::setw(6) << std::setfill(' ') << std::dec
<< std::right << i->count_
<< " " << offset.str()
<< "\n";
}
os << prefix << "Next IFD: 0x"
<< std::setw(8) << std::setfill('0') << std::hex
<< std::right << next_ << "\n";
for (i = b; i != e; ++i) {
if (i->size_ > 4) {
os << "Data of entry " << i-b << ":\n";
hexdump(os, i->data_, i->size_);
}
}
} // Ifd::print
int ExifData::read(const std::string& path)
{
JpegImage img;
int rc = img.readExifData(path);
if (rc) return rc;
offset_ = img.offsetExifData();
return read(img.exifData(), img.sizeExifData());
}
int ExifData::read(const char* buf, long len)
{
int rc = tiffHeader_.read(buf);
if (rc) return rc;
const ByteOrder byteOrder = tiffHeader_.byteOrder(); // shortcut
// Read IFD0
Ifd ifd0(ifd0);
rc = ifd0.read(buf + tiffHeader_.offset(), byteOrder, tiffHeader_.offset());
if (rc) return rc;
// Find and read ExifIFD sub-IFD of IFD0
Ifd exifIfd(exifIfd);
rc = ifd0.readSubIfd(exifIfd, buf, byteOrder, 0x8769);
if (rc) return rc;
// Find and read Interoperability IFD in ExifIFD
Ifd exifIopIfd(exifIopIfd);
rc = exifIfd.readSubIfd(exifIopIfd, buf, byteOrder, 0xa005);
if (rc) return rc;
// Find and read GPSInfo sub-IFD in IFD0
Ifd gpsIfd(gpsIfd);
rc = ifd0.readSubIfd(gpsIfd, buf, byteOrder, 0x8825);
if (rc) return rc;
// Read IFD1
Ifd ifd1(ifd1);
if (ifd0.next()) {
rc = ifd1.read(buf + ifd0.next(), byteOrder, ifd0.next());
if (rc) return rc;
}
// Find and read Interoperability IFD in IFD1
Ifd ifd1IopIfd(ifd1IopIfd);
rc = ifd1.readSubIfd(ifd1IopIfd, buf, byteOrder, 0xa005);
if (rc) return rc;
// Finally, copy all metadata from the IFDs to the internal metadata
metadata_.clear();
add(ifd0.entries());
add(exifIfd.entries());
add(exifIopIfd.entries());
add(gpsIfd.entries());
add(ifd1.entries());
add(ifd1IopIfd.entries());
return 0;
} // ExifData::read
void ExifData::data(char* buf) const
{
// Todo: implement me!
}
long ExifData::size() const
{
// Todo: implement me!
return 0;
}
void ExifData::add(const Metadata& src)
{
metadata_.insert(metadata_.end(), src.begin(), src.end());
}
void ExifData::add(const Metadatum& src)
{
metadata_.push_back(src);
}
// *************************************************************************
// free functions
uint16 getUShort(const char* buf, ByteOrder byteOrder)
{
if (byteOrder == littleEndian) {
return (unsigned char)buf[1] << 8 | (unsigned char)buf[0];
}
else {
return (unsigned char)buf[0] << 8 | (unsigned char)buf[1];
}
}
uint32 getULong(const char* buf, ByteOrder byteOrder)
{
if (byteOrder == littleEndian) {
return (unsigned char)buf[3] << 24 | (unsigned char)buf[2] << 16
| (unsigned char)buf[1] << 8 | (unsigned char)buf[0];
}
else {
return (unsigned char)buf[0] << 24 | (unsigned char)buf[1] << 16
| (unsigned char)buf[2] << 8 | (unsigned char)buf[3];
}
}
std::string getString(const char* buf, long len)
{
std::string txt(buf, len);
return txt;
}
char* us2Data(char* buf, uint16 s, ByteOrder byteOrder)
{
if (byteOrder == littleEndian) {
buf[0] = s & 0x00ff;
buf[1] = (s & 0xff00) >> 8;
}
else {
buf[0] = (s & 0xff00) >> 8;
buf[1] = s & 0x00ff;
}
return buf;
}
char* ul2Data(char* buf, uint32 l, ByteOrder byteOrder)
{
if (byteOrder == littleEndian) {
buf[0] = l & 0x000000ff;
buf[1] = (l & 0x0000ff00) >> 8;
buf[2] = (l & 0x00ff0000) >> 16;
buf[3] = (l & 0xff000000) >> 24;
}
else {
buf[0] = (l & 0xff000000) >> 24;
buf[1] = (l & 0x00ff0000) >> 16;
buf[2] = (l & 0x0000ff00) >> 8;
buf[3] = l & 0x000000ff;
}
return buf;
}
void hexdump(std::ostream& os, const char* buf, long len)
{
const std::string::size_type pos = 9 + 16 * 3;
const std::string align(pos, ' ');
long i = 0;
while (i < len) {
os << " "
<< std::setw(4) << std::setfill('0') << std::hex
<< i << " ";
std::ostringstream ss;
do {
unsigned char c = buf[i];
os << std::setw(2) << std::setfill('0')
<< std::hex << (int)c << " ";
ss << ((int)c >= 31 && (int)c < 127 ? buf[i] : '.');
} while (++i < len && i%16 != 0);
std::string::size_type width = 9 + ((i-1)%16 + 1) * 3;
os << (width > pos ? "" : align.substr(width)) << ss.str() << "\n";
}
os << std::dec << std::setfill(' ');
}
} // namespace Exif
// *****************************************************************************
// local definitions
namespace {
bool cmpOffset(const Exif::Metadatum& lhs, const Exif::Metadatum& rhs)
{
// We need to ignore entries with size <= 4, so by definition,
// entries with size <= 4 are greater than those with size > 4
// when compared by their offset.
if (lhs.size_ <= 4) {
return false; // lhs is greater by definition, or they are equal
}
if (rhs.size_ <= 4) {
return true; // rhs is greater by definition (they cannot be equal)
}
return lhs.offset_ < rhs.offset_;
}
}

@ -0,0 +1,368 @@
// ***************************************************************** -*- C++ -*-
/*
* Copyright (c) 2004 Andreas Huggel. All rights reserved.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free Software
* Foundation and appearing in the file license-gpl.txt included in the
* packaging of this file.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
* WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
/*!
@file exif.h
@brief Encoding and decoding of %Exif data
@version $Name: $ $Revision: 1.1 $
@author Andreas Huggel (ahu)
@date 09-Jan-03, ahu: created
*/
#ifndef _EXIF_H_
#define _EXIF_H_
// *****************************************************************************
// included header files
// + standard includes
#include <string>
#include <vector>
#include <iostream>
// *****************************************************************************
// namespace extensions
//! Provides classes and functions to encode and decode %Exif data.
namespace Exif {
// *****************************************************************************
// type definitions
//! 2 byte unsigned integer type.
typedef unsigned short uint16;
//! 4 byte unsigned integer type.
typedef unsigned long uint32;
//! 2 byte signed integer type.
typedef short int16;
//! 4 byte signed integer type.
typedef long int32;
// *****************************************************************************
// class definitions
/*!
@brief Helper class to access JPEG images
Todo: define and implement write support
*/
class JpegImage {
// Copying not allowed
JpegImage(const JpegImage& rhs);
// Assignment not allowed
JpegImage& operator=(const JpegImage& rhs);
public:
//! Default constructor
JpegImage();
//! Default destructor
~JpegImage();
/*!
@brief Checks if the stream is the beginning of a JPEG image
@param is Input stream to test
@return true if the input stream starts the JPEG SOI marker.
The stream is advanced by two characters in this case.<br>
false if the input stream does not begin with the JPEG SOI
marker. The stream is not advanced in this case.<br>
false if reading the first two bytes from the stream fails.
Consult the stream state for more information. In this case,
the stream may or may not have been advanced by 1 or 2
characters.
*/
static bool isJpeg(std::istream& is);
/*!
@brief Reads the %Exif data from the file path into the internal
data buffer.
@param path Path to the file
@return 0 if successful<br>
-1 if the file cannot be opened or<br>
the return code of readExifData(std::istream& is)
if the call to this function fails
*/
int readExifData(const std::string& path);
/*!
@brief Reads the %Exif data from the stream into the internal
data buffer.
@param is Input stream to read from
@return 0 if successful<br>
1 if reading from the stream failed. Consult the stream state
for more information.<br>
2 if the stream does not contain a JPEG image<br>
3 if the APP1 marker was not found<br>
4 if the APP1 field does not contain %Exif data
*/
int readExifData(std::istream& is);
//! @name Accessors
//@{
//! Returns the size of the %Exif data buffer
long sizeExifData() { return sizeExifData_; }
//! Returns the offset of the %Exif data buffer from SOI
long offsetExifData() { return offsetExifData_; }
//! Returns a read-only pointer to the %Exif data buffer
const char* exifData() { return exifData_; }
//@}
private:
static const uint16 soi_; // SOI marker
static const uint16 app1_; // APP1 marker
static const char exifId_[]; // Exif identifier
long sizeExifData_; // Size of the Exif data buffer
long offsetExifData_; // Offset from SOI
char* exifData_; // Exif data buffer
}; // class JpegImage
//! Type to express the byte order (little or big endian)
enum ByteOrder { littleEndian, bigEndian };
//! Helper class modelling the Tiff header structure.
class TiffHeader {
public:
//! Default constructor.
TiffHeader();
//! Reads the Tiff header from a data buffer. Returns 0 if successful.
int read(const char* buf);
//! Writes the Tiff header into buf as a data string.
void data(char* buf) const;
//! Returns the lengths of the Tiff header in bytes.
long size() const { return 8; }
//! @name Accessors
//@{
//! Returns the byte order (little or big endian).
ByteOrder byteOrder() const { return byteOrder_; }
//! Returns the tag value.
uint16 tag() const { return tag_; }
/*!
@brief Returns the offset to IFD0 from the start of the Tiff header.
The offset is 0x00000008 if IFD0 begins immediately after the
Tiff header.
*/
uint32 offset() const { return offset_; }
//@}
private:
ByteOrder byteOrder_;
uint16 tag_;
uint32 offset_;
}; // class TiffHeader
//! Description of a format for a metadatum
struct Format {
//! Constructor
Format(uint16 type, const std::string& name, long size);
uint16 type_; //!< Format type id
std::string name_; //!< Name of the format
long size_; //!< Bytes per data entry
}; // struct Format
//! Type to specify the IFD to which a metadata belongs
enum IfdId { unknown, ifd0, ifd1, exifIfd, gpsIfd, makerNoteIfd, exifIopIfd, ifd1IopIfd };
enum TagSection { ifd0Tiff };
struct TagInfo {
//! Constructor
TagInfo(
uint16 tag,
const std::string& fieldName,
const std::string& tagName,
IfdId ifdId,
TagSection tagSection
);
uint16 tag_;
std::string fieldName_;
std::string tagName_;
IfdId ifdId_;
TagSection tagSection_;
};
/*!
@brief Information related to one %Exif tag.
*/
struct Metadatum {
Metadatum(); //!< Constructor
~Metadatum(); //!< Destructor
Metadatum(const Metadatum& rhs); //!< Copy constructor
Metadatum& operator=(const Metadatum& rhs); //!< Assignment operator
uint16 tag_; //!< Tag value
uint16 type_; //!< Type of the data
uint32 count_; //!< Number of components
uint32 offset_; //!< Offset of the data from start of IFD
long size_; //!< Size of the data in bytes
IfdId ifdId_; //!< The IFD associated with this tag
int ifdIdx_; //!< Position in the IFD (-1: not set)
char* data_; //!< Pointer to the data
}; // struct Metadatum
//! Container type to hold all metadata
typedef std::vector<Metadatum> Metadata;
/*!
@brief Models an IFD (Image File Directory)
Todo:
- make the data handling more intelligent
- should we return the size and do away with size() ?
*/
class Ifd {
public:
//! Constructor. Allows to set the IFD identifier.
Ifd(IfdId ifdId =unknown);
/*!
@brief Read a complete IFD and its data from a data buffer
@param buf Pointer to the data to decode. The buffer must start with the
IFD data (as opposed to readSubIfd).
@param byteOrder Applicable byte order (little or big endian).
@param offset (Optional) offset of the IFD from the start of the Tiff
header, if known. If not given, the offset will be guessed
using the assumption that the smallest offset of all IFD
directory entries points to a data buffer immediately follwing
the IFD.
@return 0 if successful
*/
int read(const char* buf, ByteOrder byteOrder, long offset =0);
/*!
@brief Read a sub-IFD from the location pointed to by the directory entry
with the given tag.
@param dest References the destination IFD.
@param buf The data buffer to read from. The buffer must contain all Exif
data starting from the Tiff header (as opposed to read).
@param byteOrder Applicable byte order (little or big endian).
@param tag Tag to look for.
@return 0 if successful
*/
int readSubIfd(
Ifd& dest, const char* buf, ByteOrder byteOrder, uint16 tag
) const;
/*!
@brief Convert the IFD to a data array, returns a reference to the
data buffer. The pointer to the next IFD will be adjusted to an
offset from the start of the Tiff header to the position
immediately following the converted IFD.
@param buf Pointer to the data buffer.
@param byteOrder Applicable byte order (little or big endian).
@param offset Target offset from the start of the Tiff header of the
data array. The IFD offsets will be adjusted as
necessary. If not given, then it is assumed that the IFD
will remain at its original position.
@return Returns buf
*/
char* data(char* buf, ByteOrder byteOrder, long offset =0) const;
/*!
@brief Print the IFD in human readable format to the given stream;
begin each line with prefix.
*/
void print(std::ostream& os =std::cout, const std::string& prefix ="") const;
//! @name Accessors
//@{
//! Offset of the IFD from SOI
long offset() const { return offset_; }
//! Get the IFD entries
const Metadata& entries() const { return entries_; }
//! Get the offset to the next IFD from the start of the Tiff header
long next() const { return next_; }
//! Get the size of this IFD in bytes (IFD only, without data)
long size() const { return size_; }
//@}
private:
IfdId ifdId_; // IFD Id
long offset_; // offset of the IFD from the start of
// Tiff header
Metadata entries_; // IFD metadata entries
long next_; // offset of next IFD from the start of
// the Tiff header
long size_; // size of the IFD in bytes
}; // class Ifd
/*!
@brief A container for %Exif data
Contains the %Exif data of a JPEG image
- read and write access to all tags and data
- iterators to access the %Exif data
- decoding and encoding through the stream interface
- human readable
- XML input and output
Todo:
- A constructor which creates a minimal valid set of %Exif data
- Support to add, delete, edit, read data (maybe also in Metadata)
*/
class ExifData {
public:
/*!
@brief Read the %Exif data from file path.
@param path Path to the file
@return 0 if successful<br>
the return code of readExifData(std::istream& is)
if the call to this function fails<br>
the return code of read(const char* buf, long len)
if the call to this function fails<br>
*/
int read(const std::string& path);
/*!
@brief Read the %Exif data from a character buffer. Assumes that
the original abs offset of the Exif data is set.
@param buf Pointer to the data buffer to read from
@param len Number of bytes in the data buffer
@return 0 if successful
*/
int read(const char* buf, long len);
//! Write %Exif data to a data buffer
void data(char* buf) const;
//! Returns the size of all %Exif data (Tiff Header plus metadata)
long size() const;
//! Add all entries of src to the Exif metadata
void add(const Metadata& src);
//! Add Metadatum src to the Exif metadata
void add(const Metadatum& src);
private:
long offset_; // Original abs offset of the Exif data
TiffHeader tiffHeader_;
Metadata metadata_;
}; // class ExifData
// *****************************************************************************
// free functions
//! Read a 2 byte unsigned short value from the data buffer
uint16 getUShort(const char* buf, ByteOrder byteOrder);
//! Read a 4 byte unsigned long value from the data buffer
uint32 getULong(const char* buf, ByteOrder byteOrder);
//! Convert len bytes from the data buffer into a string
std::string getString(const char* buf, long len);
//! Write an unsigned short to the data buffer
char* us2Data(char* buf, uint16 s, ByteOrder byteOrder);
//! Convert an unsigned long to data, write the data to the buffer
char* ul2Data(char* buf, uint32 l, ByteOrder byteOrder);
//! Print len bytes from buf in hex and ASCII format to the given stream
void hexdump(std::ostream& os, const char* buf, long len);
} // namespace Exif
#endif // #ifndef _EXIF_H_

@ -0,0 +1,13 @@
#include "exif.h"
#include <iostream>
int main(int argc, char* const argv[])
{
if (argc != 2) {
std::cout << "Usage: exiftest path\n";
return 1;
}
Exif::ExifData exifData;
return exifData.read(argv[1]);
}

@ -0,0 +1,139 @@
// ********************************************************** -*- C++ -*-
/*
* Copyright (c) 2003, 2004 Andreas Huggel. All rights reserved.
*
* This file is part of the Exiv distribution.
*
* This file may be distributed and/or modified under the terms of the
* Common Public License version 1.0 as published by IBM and appearing
* in the file license-cpl.txt included in the packaging of this file.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free Software
* Foundation and appearing in the file license-gpl.txt included in the
* packaging of this file.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
* WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
/*
Author(s): Andreas Huggel (ahu)
History:
08-Dec-03, ahu: created
RCS information
$Name: $
$Revision: 1.1 $
*/
// *********************************************************************
// included header files
#include "utils.h"
// + standard includes
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h> // for getopt(), stat()
#include <errno.h>
#include <cstdlib>
#include <cstring>
#include <string>
#include <iostream>
#include <sstream>
namespace Util {
// *********************************************************************
// class Getopt
int Getopt::getopt(int argc, char* const argv[], const std::string& optstring)
{
progname_ = Util::basename(argv[0]);
while (true) {
int c = ::getopt(argc, argv, optstring.c_str());
if (c == -1) break;
errcnt_ += option(c, ::optarg == 0 ? "" : ::optarg, ::optopt);
}
for (int i = ::optind; i < argc; i++) {
errcnt_ += nonoption(argv[i]);
}
return errcnt_;
}
// *********************************************************************
// free functions
bool fileExists(const std::string& path, bool ct)
{
struct stat buf;
int ret = ::stat(path.c_str(), &buf);
if (0 != ret) return false;
if (ct && !S_ISREG(buf.st_mode)) return false;
return true;
}
std::string strError()
{
int error = errno;
std::ostringstream os;
os << ::strerror(error) << " (errno = " << error << ")";
return os.str();
}
std::string dirname(const std::string& path)
{
if (path == "") return ".";
// Strip trailing slashes
std::string p = path;
while (p.length() > 1 && p[p.length()-1] == '/') {
p = p.substr(0, p.length()-1);
}
if (p == "/") return "/";
std::string::size_type idx = p.rfind('/');
if (idx == std::string::npos) return ".";
if (idx == 0) return "/";
p = p.substr(0, idx);
while (p.length() > 1 && p[p.length()-1] == '/') {
p = p.substr(0, p.length()-1);
}
return p;
}
std::string basename(const std::string& path, bool delsuffix)
{
if (path == "") return ".";
// Strip trailing slashes
std::string p = path;
while (p.length() > 1 && p[p.length()-1] == '/') {
p = p.substr(0, p.length()-1);
}
if (p == "/") return p;
std::string::size_type idx = p.rfind('/');
if (idx != std::string::npos) p = p.substr(idx+1);
if (delsuffix) p = p.substr(0, p.length() - suffix(p).length());
return p;
}
std::string suffix(const std::string& path)
{
std::string b = basename(path);
std::string::size_type idx = b.rfind('.');
if (idx == std::string::npos || idx == 0 || idx == b.length()-1) {
return "";
}
return b.substr(idx);
}
bool strtol(const char* nptr, long& n)
{
if (!nptr || *nptr == '\0') return false;
char* endptr = 0;
long tmp = ::strtol(nptr, &endptr, 10);
if (*endptr != '\0') return false;
if (tmp == LONG_MAX || tmp == LONG_MIN) return false;
n = tmp;
return true;
}
} // namespace Util

@ -0,0 +1,169 @@
// ********************************************************* -*- C++ -*-
/*
* Copyright (c) 2003, 2004 Andreas Huggel. All rights reserved.
*
* This file is part of the Exiv distribution.
*
* This file may be distributed and/or modified under the terms of the
* Common Public License version 1.0 as published by IBM and appearing
* in the file license-cpl.txt included in the packaging of this file.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free Software
* Foundation and appearing in the file license-gpl.txt included in the
* packaging of this file.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
* WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
/*!
@file utils.h
@brief A collection of utility functions
@version $Name: $ $Revision: 1.1 $
@author Andreas Huggel (ahu)
@date 12-Dec-03, ahu: created
*/
#ifndef _UTILS_H_
#define _UTILS_H_
// *********************************************************************
// included header files
// + standard includes
#include <string>
// *********************************************************************
// namespace extensions
/*!
@brief Contains utility classes and functions. Most of these are
wrappers for common C functions that do not require pointers
and memory considerations.
*/
namespace Util {
// *********************************************************************
// class definitions
/*!
@brief Parse the command line options of a program.
A wrapper around the POSIX %getopt(3) function. Parses the command line
options and passes each option to virtual option(). A derived class
implements this method to handle options as needed. Similarly,
remaining non-option parameters are passed to the virtual nonoption()
method.
*/
class Getopt {
public:
//! Default constructor.
Getopt() : errcnt_(0) {}
//! Destructor.
virtual ~Getopt() {}
/*!
@brief Parse command line arguments.
Parses the command line arguments. Calls option() with the
character value of the option and its argument (if any) for each
recognized option and with ':' or '?' for unrecognized options.
See the manual pages for %getopt(3) for details. In addition,
nonoption() is invoked for each remaining non-option parameter on
the command line.
@param argc Argument count as passed to main() on program invocation.
@param argv Argument array as passed to main() on program invocation.
@param optstring String containing the legitimate option characters.
@return Number of errors (the sum of the return values from option()
and nonoption()).
*/
int getopt(int argc, char* const argv[], const std::string& optstring);
/*!
@brief Callback used by getopt() to pass on each option and its
argument (if any).
Implement this method in a derived class to handle the options as
needed. See the manual pages for %getopt(3) for further details, in
particular, the semantics of optarg and optopt.
@param opt Value of the option character as returned by %getopt(3).
@param optarg The corresponding option argument.
@param optopt The actual option character in case of an unrecognized
option or a missing option argument (opt is '?' or ':').
@return 0 if successful, 1 in case of an error.
*/
virtual int option(int opt, const std::string& optarg, int optopt) = 0;
/*!
@brief Callback used by getopt() to pass on each non-option parameter
found on the command line.
Implement this method in a derived class to handle the non-option
parameters as needed. The default implementation ignores all non-option
parameters.
@param argv The non-option parameter from the command line.
@return 0 if successful, 1 in case of an error.
*/
virtual int nonoption(const std::string& argv) { return 0; }
//! Program name (argv[0])
const std::string& progname() const { return progname_; }
//! Total number of errors returned by calls to option()
int errcnt() const { return errcnt_; }
private:
std::string progname_;
int errcnt_;
};
// *********************************************************************
// free functions
/*!
@brief Test if a file exists.
@param path Name of file to verify.
@param ct Flag to check if <i>path</i> is a regular file.
@return true if <i>path</i> exists and, if <i>ct</i> is set,
is a regular file, else false.
@note The function calls <b>stat()</b> test for <i>path</i>
and its type, see stat(2). <b>errno</b>
is left unchanged in case of an error.
*/
bool fileExists(const std::string& path, bool ct =false);
//! Get a system error message and the error code. See %strerror(2).
std::string strError();
//! Get the directory component from the path string. See %dirname(3).
std::string dirname(const std::string& path);
/*!
@brief Get the filename component from the path string. See %basename(3).
If the delsuffix parameter is true, the suffix will be removed.
*/
std::string basename(const std::string& path, bool delsuffix =false);
/*!
@brief Get the suffix from the path string. Normally, the suffix
is the substring of the basename of path from the last '.'
to the end of the string.
*/
std::string suffix(const std::string& path);
/*!
@brief Convert a C string to a long value, which is returned in n.
Returns true if the conversion is successful, else false.
n is not modified if the conversion is unsuccessful. See strtol(2).
*/
bool strtol(const char* nptr, long& n);
} // namespace Util
#endif // #ifndef _UTILS_H_

@ -0,0 +1,91 @@
// ********************************************************* -*- C++ -*-
/*
AUTHOR(S): Andreas Huggel (ahu)
HISTORY:
10-Dec-03, ahu: created
RCS information
$Name: $
$Revision: 1.1 $
*/
// *********************************************************************
// included header files
#include "utils.h"
#include <iostream>
#include <iomanip>
// *********************************************************************
// Main
int main(int argc, char* const argv[])
{
bool rc;
long n(0);
std::string s;
s = "22"; rc = Util::strtol(s.c_str(), n);
std::cout << "s = `" << s << "' rc = " << rc << " n = " << n << "\n";
s = "1"; rc = Util::strtol(s.c_str(), n);
std::cout << "s = `" << s << "' rc = " << rc << " n = " << n << "\n";
s = "-22222222222222222"; rc = Util::strtol(s.c_str(), n);
std::cout << "s = `" << s << "' rc = " << rc << " n = " << n << "\n";
s = "0x0"; rc = Util::strtol(0, n);
std::cout << "s = `" << s << "' rc = " << rc << " n = " << n << "\n";
s = ""; rc = Util::strtol(s.c_str(), n);
std::cout << "s = `" << s << "' rc = " << rc << " n = " << n << "\n";
s = "abc"; rc = Util::strtol(s.c_str(), n);
std::cout << "s = `" << s << "' rc = " << rc << " n = " << n << "\n";
s = "1.2"; rc = Util::strtol(s.c_str(), n);
std::cout << "s = `" << s << "' rc = " << rc << " n = " << n << "\n";
s = "12p"; rc = Util::strtol(s.c_str(), n);
std::cout << "s = `" << s << "' rc = " << rc << " n = " << n << "\n";
return 0;
}
void testStrError()
{
std::string oldname = "/tmp/foo";
std::string newname = "/tmp/bar";
if (::rename(oldname.c_str(), newname.c_str()) == -1) {
std::cerr << "failed to rename "
<< oldname << " to " << newname << ": ";
std::cerr << Util::strError() << "\n";
}
}
void testPaths()
{
std::string path;
void testPath(const std::string path);
path = "/usr/lib"; testPath(path);
path = "/usr/"; testPath(path);
path = "usr"; testPath(path);
path = "/"; testPath(path);
path = "."; testPath(path);
path = ".."; testPath(path);
path = "///"; testPath(path);
path = "/usr/.emacs"; testPath(path);
path = "/usr/.emacs/"; testPath(path);
path = "/usr/.emacs//"; testPath(path);
path = "usr/.emacs"; testPath(path);
path = ".emacs"; testPath(path);
path = "/tmp/image.jpg"; testPath(path);
path = "/tmp/.image.jpg"; testPath(path);
path = "/image.jpg"; testPath(path);
path = "image.jpg"; testPath(path);
path = "image.jpg//"; testPath(path);
path = "/////image.jpg"; testPath(path);
path = "/foo.bar/image"; testPath(path);
path = "/foo.bar/images.tar.gz"; testPath(path);
}
void testPath(const std::string path)
{
std::cout << std::setw(15) << path << " "
<< std::setw(15) << Util::dirname(path) << " "
<< std::setw(15) << Util::basename(path) << " "
<< std::setw(15) << Util::suffix(path) << "\n";
}
Loading…
Cancel
Save