metacam-1.2/0000755000076500007650000000000010111706356012332 5ustar daniel00000000000000metacam-1.2/LICENSE.TXT0000644000076500007650000004312710111706345014022 0ustar daniel00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy 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. , 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. metacam-1.2/BUGS0000644000076500007650000000111310111706345013007 0ustar daniel00000000000000$Id: BUGS,v 1.1 2002/09/02 19:27:56 daniel Exp $ The following are known bugs/weaknesses in metacam: * The mixed-endianness support is weak and I know it, it probably fails horribly on some systems. On the bright side the endianness detection and compensation is fairly localized so it'll be easy to fix. * Error handling when reading corrupt IFD's is mostly non-existant. * Support for construction of custom IFD's is partially but not completely implemented. * I haven't finished library-ifying the guts of metacam so they can be used in other contexts (such as DeNEF) metacam-1.2/Makefile0000644000076500007650000000524510111706345013776 0ustar daniel00000000000000# ----------------------------------------------------------------------------- # MetaCam - Extract EXIF information from digital camera files, with # support for Vendor specific blocks. # Copyright (C) 2000 Daniel Stephens (daniel@cheeseplant.org) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # ----------------------------------------------------------------------------- # # $Id: Makefile,v 1.12 2002/09/02 20:28:46 daniel Exp $ # Some operating-system dependent choices for compile-time flags. Uncomment # whichever is most appropriate # -- g++ on linux OSCXXFLAGS=-ansi -pedantic # -- Cygwin under Windows 2000 #OSCXXFLAGS= CXX=g++ INCLUDES= CXXFLAGS=-Wall $(OSCXXFLAGS) -D_GNU_SOURCE -O2 $(INCLUDES) LIBOBJS=rationals.o exiftags.o \ nikontags.o olympustags.o canontags.o casiotags.o dpyfuncs.o \ metatiff.o filetiff.o tiffdata.o dataifd.o dataifdentry.o editifd.o \ ocontext.o lookups.o EXEOBJS=metacam.o HDRS=metacam.h dpyfuncs.h metatiff.h filetiff.h datatiff.h edittiff.h \ odrivers.h DEPS=$(LIBOBJS:.o=.dep) $(EXEOBJS:.o=.dep) ##### TARGETS ###### default: metacam clean: -rm -f *.o *~ *- tags: etags *.cc *.h realclean: -rm -f metacam -rm -f *.o *~ *- -rm -f *.dep -rm -f dependencies -rm -f TAGS libmetacam.a: $(LIBOBJS) rm -f libmetacam.a ar rsc libmetacam.a- $(LIBOBJS) mv -f libmetacam.a- libmetacam.a metacam: $(EXEOBJS) libmetacam.a $(CXX) $(CXXFLAGS) $(EXEOBJS) -o metacam -lm -L. -lmetacam # Dependency rules dependencies: Makefile $(DEPS) cat $(DEPS) > dependencies- mv -f dependencies- dependencies # Each .dep file will hold dependencies for both the .o file, and an identical # list to determine when the .dep file needs rebuilding. Clever eh? %.dep: %.cc $(HDRS) $(CXX) $(CFLAGS) $(INCS) -M -E -c $*.cc > $*.dep- sed -e 's/[.]o:/.dep:/' $*.dep- > $*.dep-- cat $*.dep-- >> $*.dep- rm -f $*.dep-- mv -f $*.dep- $*.dep tar: -rm -f files.tar tar -cvf files.tar $(LIBOBJS:.o=.cc) $(EXEOBJS:.o=.cc) $(HDRS) Makefile THANKS $(wildcard README.*) LICENSE.TXT BUGS include dependencies metacam-1.2/README.canon0000644000076500007650000000142610111706345014310 0ustar daniel00000000000000Implementation notes by Jan Brittenson (bson@rockgarden.net) This is notes on the implementation and against http://www.burren.cx/david/canon.html. The Canon makenote implementation has been tested against S100 and G1. The S100 doesn't output focal length information; it leaves the fields zero. Tag 0x8 (Image Number): the value 1000 should be 10000. Tag 0x4 AF point isn't implemented since it's not really understood. I'll take a stab at it. Both the S100 and G1 output tags: TAG 0x2-3:2,672,285,214, TAG 0x10-4:67371008, The latter appears to be a long broken into two shorts. The high-end short is a large number, the low-end short a small number or zero. Tag 0xc (Camera Serial Number) has been implemented but is untested since neither my S100 or G1 creates this. metacam-1.2/README.casio0000644000076500007650000000123010111706345014301 0ustar daniel00000000000000Implementation notes by Pat Tullmann (pat@tullmann.org) I used the data from http://www.ba.wakwak.com/~tsuruzoh/Computer/Digicams/exif-e.html#APP3 and http://www.dicasoft.de/dicainfo.htm in late July 2001 to write casiotags.cc. I based all the code I wrote on the canontags.cc and they dpy* code in metacam proper. I tested the casiotags on pictures generated from a Casio QV2000-UX. The http://www.dicasoft.de/dicainfo.htm source indicates that a some Casio cameras use a software revision that doesn't generate EXIF makerinfo tags. Also, the "Object Distance" field is probably bogus. There are also several fields that are not yet reverse engineered. metacam-1.2/THANKS0000644000076500007650000000076710111706345013255 0ustar daniel00000000000000I'd like to thank the following contributors and supporters of MetaCam for their help during its ongoing development. Jan Brittenson David C. Hansen Geoff Kuenning Pat Tullmann Jan Niehusmann Holm Sieber Jeremie Rostand Vladimir Kondratiev Fred Albrecht Doug Larrick Till Kamppeter Ro Ro Also, many thanks to all of the contributors to the various free software projects which I use on a daily basis, and without which this project (and many others) would likely never have started! Daniel Stephens. metacam-1.2/canontags.cc0000644000076500007650000000374610111706345014626 0ustar daniel00000000000000/* ------------------------------------------------------------------------------ MetaCam - Extract EXIF information from digital camera files, with support for Vendor specific blocks. Copyright (C) 2000 Daniel Stephens (daniel@cheeseplant.org) Copyright (C) 2001, Jan Brittenson (bson@rockgarden.net) 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. ------------------------------------------------------------------------------ */ #include "dpyfuncs.h" static const char *rcsid __attribute__((unused))="$Id: canontags.cc,v 1.4 2002/09/02 19:20:01 daniel Exp $"; // Initial Canon tag references from // http://www.butaman.ne.jp/~tsuruzoh/Computer/Digicams/exif-e.html knowntag canon_known[] = { { 0x1, tSHORT, 0, "" , dpyCanonBlock1, 0}, // 0x2 is unknown // 0x3 is unknown { 0x4, tSHORT, 0, "" , dpyCanonBlock4, 0}, { 0x8, tLONG, 0, "Image Number" , dpyCanonImageNumber, 0}, { 0x6, tASCII, 0, "Image Type" , dpyString, 0}, { 0x7, tASCII, 0, "Firmware Version" , dpyString, 0}, { 0x9, tASCII, 0, "Owner Name" , dpyString, 0}, { 0xc, tLONG, 0, "Camera Serial Number" , dpyCanonSerialNumber, 0}, // { 0xf, tSHORT, 0, "" , dpyCanonCustomTags, 0}, // 0x10 is unknown {0,0,0,0,0} }; metacam-1.2/casiotags.cc0000644000076500007650000000516210111706345014620 0ustar daniel00000000000000/* ------------------------------------------------------------------------------ MetaCam - Extract EXIF information from digital camera files, with support for Vendor specific blocks. Copyright (C) 2000 Daniel Stephens (daniel@cheeseplant.org) Copyright (C) 2001, Jan Brittenson (bson@rockgarden.net) Copyright (C) 2001, Patrick Tullmann (pat@tullmann.org) 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. ------------------------------------------------------------------------------ */ #include "dpyfuncs.h" static const char *rcsid __attribute__((unused))="$Id: casiotags.cc,v 1.4 2002/09/02 19:20:01 daniel Exp $"; // Initial Casio tag references from // http://www.ba.wakwak.com/~tsuruzoh/Computer/Digicams/exif-e.html // and // http://www.dicasoft.de/dicainfo.htm knowntag casio_known[] = { { 0x1, tSHORT, 0, "Recording Mode" , dpyUnsignedLookup, lookCasioRecMode}, { 0x2, tSHORT, 0, "Quality" , dpyUnsignedLookup, lookCasioQuality}, { 0x3, tSHORT, 0, "Focusing Mode" , dpyUnsignedLookup, lookCasioFocusMode}, { 0x4, tSHORT, 0, "Flash Mode" , dpyUnsignedLookup, lookCasioFlashMode}, { 0x5, tSHORT, 0, "Flash Intensity" , dpyUnsignedLookup, lookCasioFlashInten}, { 0x6, tLONG, 0, "Object Distance ~" , dpyCasioDistance, 0}, { 0x7, tSHORT, 0, "White Balance" , dpyUnsignedLookup, lookCasioWhiteBalance}, // 0x8 is unknown tSHORT // 0x9 is unknown tSHORT { 0xa, tLONG, 0, "Digital Zoom" , dpyUnsignedLookup, lookCasioDigitalZoom}, { 0xb, tSHORT, 0, "Sharpness" , dpyUnsignedLookup, lookCasioSharpness}, { 0xc, tSHORT, 0, "Contrast" , dpyUnsignedLookup, lookCasioContrast}, { 0xd, tSHORT, 0, "Saturation" , dpyUnsignedLookup, lookCasioSaturation}, // 0xe through 0x013 are unknown tSHORT { 0x14,tSHORT, 0, "CCD Sensitivity" , dpyUnsignedLookup, lookCasioSensitivity}, {0,0,0,0,0} }; metacam-1.2/dataifd.cc0000644000076500007650000000574710111706345014250 0ustar daniel00000000000000/* ------------------------------------------------------------------------------ MetaCam - Extract EXIF information from digital camera files, with support for Vendor specific blocks. Copyright (C) 2000 Daniel Stephens (daniel@cheeseplant.org) 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. ------------------------------------------------------------------------------ */ #include #include "datatiff.h" static const char *rcsid __attribute__((unused))="$Id: dataifd.cc,v 1.2 2002/09/02 19:20:01 daniel Exp $"; _DataIFD::~_DataIFD() { if (entry_count) { for (int i=0; idelRef(); delete [] table; } table = 0; } _DataIFD::_DataIFD(const TIFFDataSource &src, unsigned long o, unsigned long tagofs) : _IFD(), source(src), ofs(o), table(0) { source.seek(ofs); entry_count = source.getUShort(); table = new _DataIFDEntry *[entry_count]; int i; unsigned long expofs = source.tell(); for (i=0; iaddRef(); // Stop it from deleting itself later! expofs += 12; source.seek(expofs); } next_ifd_ofs = source.getULong(); } unsigned short _DataIFD::entries() const { return entry_count; } IFD _DataIFD::nextIFD() const { if (next_ifd_ofs == 0) return IFD(); return IFD(new _DataIFD(source, next_ifd_ofs, 0)); } bool _DataIFD::isDynamic() const { return false; } IFDEntry _DataIFD::operator[](int n) const { if ((n<0) || (n>=entry_count)) { cerr << "_DataIFD Array Bounds Violated" << endl; exit(2); } return IFDEntry(table[n]); } IFDEntry _DataIFD::findEntry(unsigned long tag, _IFDEntry *after) const { bool ready_to_return = (after == 0); for (int i=0; igetTag() != tag) continue; if (ready_to_return) return IFDEntry(table[i]); if (table[i] == after) ready_to_return = true; } return IFDEntry(); } TIFFDataSource _DataIFD::getSource() const { return source; } unsigned long _DataIFD::getSourceOffset() const { return ofs; } metacam-1.2/dataifdentry.cc0000644000076500007650000001257010111706345015322 0ustar daniel00000000000000/* ------------------------------------------------------------------------------ MetaCam - Extract EXIF information from digital camera files, with support for Vendor specific blocks. Copyright (C) 2000 Daniel Stephens (daniel@cheeseplant.org) 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. ------------------------------------------------------------------------------ */ #include #include "datatiff.h" static const char *rcsid __attribute__((unused))="$Id: dataifdentry.cc,v 1.3 2002/09/02 19:20:01 daniel Exp $"; _DataIFDEntry::_DataIFDEntry(const TIFFDataSource &src, long ofs, long t, short typ, long vals) : _IFDEntry(t, typ), source(src), value_count(vals), offset(ofs) { } _DataIFDEntry::~_DataIFDEntry() { } unsigned long _DataIFDEntry::values() const { return value_count; } vector _DataIFDEntry::getUVALUE() const { vector v; if (getRawType() == tBYTE) { source.seek(offset); for (unsigned int i=0; i _DataIFDEntry::getSVALUE() const { vector v; if (getRawType() == tSBYTE) { source.seek(offset); for (unsigned int i=0; i _DataIFDEntry::getRATIONAL() const { vector v; if (getRawType() != tRATIONAL) {return v;} source.seek(offset); for (unsigned int i=0; i _DataIFDEntry::getSRATIONAL() const { vector v; if (getRawType() != tSRATIONAL) {return v;} source.seek(offset); for (unsigned int i=0; i _DataIFDEntry::getSTRING() const { vector v; if (getRawType() != tASCII) {return v;} char tmpbuf[1024]; source.seek(offset); source.getData((unsigned char *)tmpbuf, value_count); tmpbuf[value_count] = 0; v.push_back(string(tmpbuf)); return v; } vector _DataIFDEntry::getOPAQUE() const { vector v; if (getRawType() != tUNDEFINED) {return v;} int toget=value_count; source.seek(offset); while (toget > 0) { unsigned char tmpbuf[1024]; int g = toget; if (g>1024) g=1024; source.getData((unsigned char *)tmpbuf, g); for (int i=0; i v = getSTRING(); vector::iterator iter; for (iter=v.begin(); iter != v.end(); ++iter) { os << "\"" << (*iter) << "\","; } return; } case 1: case 3: case 4: { vector v = getUVALUE(); vector::iterator iter; for (iter=v.begin(); iter != v.end(); ++iter) { os << (*iter) << ","; } return; } case 5: { vector v = getRATIONAL(); vector::iterator iter; for (iter=v.begin(); iter != v.end(); ++iter) { os << (*iter) << ","; } return; } case 7: { vector v = getOPAQUE(); vector::iterator iter; for (iter=v.begin(); iter != v.end(); ++iter) { unsigned char c=(*iter); os << hexdigit[(c >> 4) & 0x0f] << hexdigit[c&0x0F] << " "; } return; } case 6: case 8: case 9: { vector v = getSVALUE(); vector::iterator iter; for (iter=v.begin(); iter != v.end(); ++iter) { os << (*iter) << ","; } return; } case 10: { vector v = getSRATIONAL(); vector::iterator iter; for (iter=v.begin(); iter != v.end(); ++iter) { os << (*iter) << ","; } return; } } // 11 FLOAT // 12 DOUBLE } metacam-1.2/datatiff.h0000644000076500007650000000521610111706345014267 0ustar daniel00000000000000/* ------------------------------------------------------------------------------ MetaCam - Extract EXIF information from digital camera files, with support for Vendor specific blocks. Copyright (C) 2000 Daniel Stephens (daniel@cheeseplant.org) 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. ------------------------------------------------------------------------------ */ #ifndef DATATIFF_H_INCLUDED #define DATATIFF_H_INCLUDED #include "metatiff.h" class _DataIFD; class _DataIFDEntry; class _DataIFD : public _IFD { private: TIFFDataSource source; unsigned long ofs; unsigned short entry_count; unsigned long next_ifd_ofs; _DataIFDEntry **table; _DataIFD(const _DataIFD &) { abort(); } _DataIFD &operator=(const _DataIFD &) { abort(); return *this; } public: _DataIFD(const TIFFDataSource &src, unsigned long o, unsigned long tagofs = 0) ; ~_DataIFD(); virtual unsigned short entries() const; virtual IFD nextIFD() const; virtual bool isDynamic() const; virtual IFDEntry operator[](int n) const; virtual IFDEntry findEntry(unsigned long tag, _IFDEntry *after=0) const; virtual TIFFDataSource getSource() const; virtual unsigned long getSourceOffset() const; }; class _DataIFDEntry : public _IFDEntry { private: TIFFDataSource source; unsigned long value_count; unsigned long offset; public: _DataIFDEntry(const TIFFDataSource &src, long ofs, long t, short typ, long vals); virtual ~_DataIFDEntry(); virtual unsigned long values() const; virtual void outputValue(ostream &os) const; virtual vector getUVALUE() const; virtual vector getSVALUE() const; virtual vector getRATIONAL() const; virtual vector getSRATIONAL() const; virtual vector getSTRING() const; virtual vector getOPAQUE() const; virtual TIFFDataSource getSource() const; virtual unsigned long getSourceOffset() const; }; #endif /* DATATIFF_H_INCLUDED */ metacam-1.2/dpyfuncs.cc0000644000076500007650000005510610111706345014501 0ustar daniel00000000000000/* ------------------------------------------------------------------------------ MetaCam - Extract EXIF information from digital camera files, with support for Vendor specific blocks. Copyright (C) 2000 Daniel Stephens (daniel@cheeseplant.org) 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. ------------------------------------------------------------------------------ */ #include #include #include #include #include "metacam.h" #include "dpyfuncs.h" static const char *rcsid __attribute__((unused))="$Id: dpyfuncs.cc,v 1.14 2004/08/21 17:54:20 daniel Exp $"; void dpyISO(OutputContext &ctx, const char *name, const IFDEntry &e, const void*) { vector v = e.getUVALUE(); ctx.startBlock(name) << v[1] << " (" << v[0] << ")"; ctx.endBlock(); } void dpyString(OutputContext &ctx, const char *name, const IFDEntry &e, const void*) { vector v = e.getSTRING(); ctx.startBlock(name) << v[0]; ctx.endBlock(); } void displayRational(OutputContext &ctx, const tiffRATIONAL &r) { if (r.getNumerator() == 0) { ctx.os() << "0"; } else if (r.getDenominator() == 1) { ctx.os() << r.getNumerator(); } else { ctx.os() << r; } } void displayRational(OutputContext &ctx, const tiffSRATIONAL &r) { if (r.getNumerator() == 0) { ctx.os() << "0"; } else if (r.getDenominator() == 1) { ctx.os() << r.getNumerator(); } else { ctx.os() << r; } } void dpyLens(OutputContext &ctx, const char *name, const IFDEntry &e, const void*) { vector v = e.getRATIONAL(); v[0] = v[0].normalize(); v[1] = v[1].normalize(); v[2] = v[2].normalize(); v[3] = v[3].normalize(); ctx.startBlock(name); if (v[0] == v[1]) { displayRational(ctx,v[0]); ctx.os() << "mm "; } else { displayRational(ctx,v[0]); ctx.os() << "-"; displayRational(ctx,v[1]); ctx.os() << "mm "; } if (v[2] == v[3]) { ctx.os() << "f" << (double)v[2]; } else { ctx.os() << "f" << (double)v[2]; ctx.os() << "-"; ctx.os() << "f" << (double)v[3]; } ctx.endBlock(); } void dpyZoom(OutputContext &ctx, const char *name, const IFDEntry &e, const void*) { vector v = e.getRATIONAL(); v[0] = v[0].normalize(); ctx.startBlock(name); // displayRational(ctx,v[0]); double d = v[0]; d *= 100.0; d = floor(d); d /= 100.0; ctx.os() << d << "mm"; ctx.endBlock(); } void dpyExpAdjust(OutputContext &ctx, const char *name, const IFDEntry &e, const void*) { vector v = e.getSRATIONAL(); v[0] = v[0].normalize(); ctx.startBlock(name); double d = v[0]; d *= 1000.0; d = floor(d); d /= 1000.0; if (d > 0.0) {ctx.os() << "+";} ctx.os() << d << " EV"; ctx.endBlock(); } void dpyShutter(OutputContext &ctx, const char *name, const IFDEntry &e, const void*) { vector v = e.getRATIONAL(); v[0]=v[0].normalize(); ctx.startBlock(name); displayRational(ctx,v[0]); ctx.os() << " Sec."; ctx.endBlock(); } void dpyAperture(OutputContext &ctx, const char *name, const IFDEntry &e, const void*) { vector v = e.getRATIONAL(); ctx.startBlock(name) << "f" << (double)v[0]; ctx.endBlock(); } void dpyPixels(OutputContext &ctx, const char *name, const IFDEntry &e, const void*) { vector v = e.getUVALUE(); ctx.startBlock(name) << v[0] << " pixels"; ctx.endBlock(); } void dpySigned(OutputContext &ctx, const char *name, const IFDEntry &e, const void*) { vector v = e.getSVALUE(); ctx.startBlock(name); if (v[0] > 0) { ctx.os() << "+" << v[0]; } else { ctx.os() << v[0]; } ctx.endBlock(); } void dpyUnsigned(OutputContext &ctx, const char *name, const IFDEntry &e, const void*) { vector v = e.getUVALUE(); ctx.startBlock(name) << v[0]; ctx.endBlock(); } void dpyResolution(OutputContext &ctx, const char *name, const IFDEntry &e, const void*) { vector v = e.getRATIONAL(); v[0]=v[0].normalize(); ctx.startBlock(name); displayRational(ctx,v[0]); ctx.os() << " Pixels/" << ctx.getContextValue("resolutionUnit"); ctx.endBlock(); } void dpyNULL(OutputContext &ctx, const char *name, const IFDEntry &e, const void*) {} void dpyYes(OutputContext &ctx, const char *name, const IFDEntry &e, const void*) { ctx.startBlock(name) << "Yes"; ctx.endBlock(); } void dpyResolutionType(OutputContext &ctx, const char *name, const IFDEntry &e, const void*) { vector v = e.getUVALUE(); const char *resolution_unit = "???"; switch (v[0]) { case 1: resolution_unit = "???"; break; case 2: resolution_unit = "Inch"; break; case 3: resolution_unit = "Centimeter"; break; } ctx.setContextValue("resolutionUnit", resolution_unit); } void dpyBitsPerSample(OutputContext &ctx, const char *name, const IFDEntry &e, const void*) { vector v = e.getUVALUE(); ctx.startBlock(name) << "("; vector::iterator iter; bool first=true; for (iter = v.begin(); iter != v.end(); ++iter) { if (first) { first=false; } else { ctx.os() << ","; } ctx.os() << (*iter); } ctx.os() << ")"; ctx.endBlock(); } const char *findLookup(int key, const void *table) { if (table == 0) return 0; const lookupValue *ltable = static_cast(table); /* Simplified test (Prohibits use of explicitly unknown values in lookups, but those would have been confusing anyway. */ for (;ltable->value; ++ltable) { if (ltable->key == key) return ltable->value; } return 0; } void dpyUnsignedLookup(OutputContext &ctx, const char *name, const IFDEntry &e, const void*tbl) { vector v = e.getUVALUE(); ctx.startBlock(name); const char *val = findLookup((int)v[0], tbl); if (val) { ctx.os() << val; } else { ctx.os() << "Unknown (" << v[0] << ")"; } ctx.endBlock(); } void dpyUndefinedLookup(OutputContext &ctx, const char *name, const IFDEntry &e, const void*tbl) { vector v = e.getOPAQUE(); ctx.startBlock(name); const char *val = findLookup((int)v[0], tbl); if (val) { ctx.os() << val; } else { ctx.os() << "Unknown (" << v[0] << ")"; } ctx.endBlock(); } void dpyExifVersion(OutputContext &ctx, const char *name, const IFDEntry &e, const void*) { vector v = e.getOPAQUE(); ctx.startBlock(name); vector::iterator iter; for (iter=v.begin(); iter!=v.end(); ++iter) { unsigned char c = (*iter); if ((c < 32) || (c>126)) {c = ' ';} ctx.os() << c; } ctx.endBlock(); } void dpyExifAperture(OutputContext &ctx, const char *name, const IFDEntry &e, const void*) { vector v = e.getRATIONAL(); ctx.startBlock(name); double a = v[0]; double f = pow(M_SQRT2, a); f = f * 10.0; f = floor(f); f = f / 10.0; ctx.os() << "f" << f; ctx.endBlock(); } void dpyExifShutter(OutputContext &ctx, const char *name, const IFDEntry &e, const void*) { vector v = e.getSRATIONAL(); ctx.startBlock(name); double a = v[0]; if (a > 0.0) { double f = pow(2.0, a); ctx.os() << "1/" << f << " Sec."; } else { double f = pow(2.0, -a); ctx.os() << f << " Sec."; } ctx.endBlock(); } void dpyRationalAsDouble(OutputContext &ctx, const char *name, const IFDEntry &e, const void *units) { ctx.startBlock(name); if (e.getType() == tSRATIONAL) { vector v = e.getSRATIONAL(); if (v[0].getDenominator() == 0) { ctx.os() << "Infinity"; } else { double a = v[0]; ctx.os() << a; if (units) { ctx.os() << (const char *) units; } } } else { vector v = e.getRATIONAL(); if (v[0].getDenominator() == 0) { ctx.os() << "Infinity"; } else { double a = v[0]; ctx.os() << a; if (units) { ctx.os() << (const char *) units; } } } ctx.endBlock(); } void dpyOlymSpecialMode(OutputContext &ctx, const char *name, const IFDEntry &e, const void*) { vector v = e.getUVALUE(); ctx.startBlock(name); switch (v[0]) { case 0: ctx.os() << "Normal"; break; case 1: ctx.os() << "Unknown"; break; case 2: ctx.os() << "Fast"; break; case 3: ctx.os() << "Panorama"; break; default: ctx.os() << "Unknown (" << v[0] << ")"; break; } ctx.os() << "; Seq " << v[1]; if (v[0] == 3) { switch(v[2]) { case 1: ctx.os() << " Left -> Right"; break; case 2: ctx.os() << " Right -> Left"; break; case 3: ctx.os() << " Bottom -> Top"; break; case 4: ctx.os() << " Top -> Bottom"; break; default: ctx.os() << " Unknown (" << v[2] << ")"; break; } } ctx.endBlock(); } void dpyOlymZoom(OutputContext &ctx, const char *name, const IFDEntry &e, const void*) { vector v = e.getRATIONAL(); ctx.startBlock(name); double a = v[0]; if (a == 0.0) { ctx.os() << "Normal"; ctx.endBlock(); return; } a = a * 100.0; a = floor(a); a = a / 100.0; ctx.os() << "x" << a; ctx.endBlock(); } static void fmt(OutputContext &ctx, const char *prefix, const char *value) { ctx.startBlock(prefix); ctx.os() << value; ctx.endBlock(); } void dpyCanonBlock1(OutputContext &ctx, const char *name, const IFDEntry &e, const void*) { vector v = e.getUVALUE(); try { int n = v[0] / 2; if (v[1]) fmt(ctx, "Macro Mode", v[1] == 1 ? "Macro" : "No Macro"); if (v[2]) { char tl[32]; snprintf(tl, sizeof tl, "%.1g", (double)v[2] / 10.0); fmt(ctx, "Self Timer", tl); } if (v[4]) { static char *flashmodes[] = { "Auto", "On", "Red-Eye Reduction", "Slow Synchro", "Auto + Red-Eye Reduction", "On + Red-Eye Reduction" }; if (v[4] <= 6) fmt(ctx, "Flash Mode", flashmodes[v[4]]); else if (v[4] == 16) fmt(ctx, "Flash Mode", "External"); } else fmt(ctx, "Flash Mode", "No Flash"); fmt(ctx, "Drive Mode", v[5] ? "Continuous" : (v[2] ? "Timer" : "Normal")); if (n >= 32 && v[32]) { fmt(ctx, "Focus Mode", "Continuous"); } else if (v[7] <= 6) { static char *focusModes[] = { "One-Shot", "AI Servo", "AI Focus", "Manual Focus", "Single Focus", "Continuous Focus", "Manual Focus" }; fmt(ctx, "Focus Mode", focusModes[v[7]]); } if (v[10] <= 2) { static char *imageSizes[] = { "Large", "Medium", "Small" }; fmt(ctx, "Image Size", imageSizes[v[10]]); } { static char *adjustment[] = { "Low", "Normal", "High", "unknown" }; fmt(ctx, "Contrast", adjustment[((short)v[13] + 1) & 0x3]); fmt(ctx, "Saturation", adjustment[((short)v[14] + 1) & 0x3]); fmt(ctx, "Sharpness", adjustment[((short)v[15] + 1) & 0x3]); } if (v[16] >= 15 && v[16] <= 19) { static char *speeds[] = { "auto", "50", "100", "200", "400" }; fmt(ctx, "ISO Speed", speeds[v[16] - 15]); } if (v[17] >= 3 && v[17] <= 5) { static char *meterModes[] = { "Evaluative", "Partial", "Center-weighted" }; fmt(ctx, "Metering Mode", meterModes[v[17] - 3]); } if (v[18] >= 0x3000 && v[18] <= 0x3004) { static char *afPoints[] = { "Manual Focus", "Auto-Select", "Right", "Center", "Left" }; fmt(ctx, "Autofocus Point", afPoints[v[18] - 0x3000]); } if (v[20] <= 5) { static char *exposureModes[] = { "Preprogrammed", "Program", "Tv-priority", "Av-priority", "Manual", "A-DEP" }; fmt(ctx, "Exposure Mode", exposureModes[v[20]]); } if (v[20] == 0 && v[11] <= 11) { static char *shootModes[] = { "Full Auto", "Manual", "Landscape", "Fast Shutter", "Slow Shutter", "Night", "B&W", "Sepia", "Portrait", "Sports", "Macro / Close-Up", "Pan Focus" }; fmt(ctx, "Preprogrammed Mode", shootModes[v[11]]); } // printf("%d, %d, %d\n", v[23], v[24], v[25]); // DEBUG if (v[25] && v[23] && v[24]) { double maxFocalLen = v[23]; double minFocalLen = v[24]; double focalFactor = (double)v[25]; char zoom[32]; if (maxFocalLen == minFocalLen) { snprintf(zoom, sizeof zoom, "%.1gmm", maxFocalLen / focalFactor); } else { snprintf(zoom, sizeof zoom, "%g-%gmm", minFocalLen / focalFactor, maxFocalLen / focalFactor); } fmt(ctx, "Focal Length", zoom); } if (v[29]) { #define V29BIT(N) (v[29] & (1 << (N))) string flashDetails; if (V29BIT(14)) flashDetails += ", External E-TTL"; if (V29BIT(13)) flashDetails += ", Internal"; if (V29BIT(11)) flashDetails += ", FP Sync"; if (V29BIT(4)) flashDetails += ", FP Sync Enabled"; if (flashDetails != "") fmt(ctx, "Flash Details", flashDetails.data() + 2); } } catch (...) { return; } } extern void dpyCanonBlock4(OutputContext &ctx, const char *name, const IFDEntry &e, const void*) { vector v = e.getUVALUE(); try { // int n = v[0] / 2; if (v[7] <= 6) { static char *whiteBalances[] = { "Auto", "Sunny", "Cloudy", "Tungsten", "Fluorescent", "Flash", "Custom" }; fmt(ctx, "White Balance", whiteBalances[v[7]]); } if (v[9] > 1) { char n[32]; snprintf(n, sizeof n, "%u", (unsigned int)v[9]); fmt(ctx, "Burst Sequence Number", n); } { struct { unsigned short value; char *bias; } flashBias[] = { {0xffc0, "-2 EV"}, {0xffcc, "-1.67 EV"}, {0xffd0, "-1.50 EV"}, {0xffd4, "-1.33 EV"}, {0xffe0, "-1 EV"}, {0xffec, "-0.67 EV"}, {0xfff0, "-0.50 EV"}, {0xfff4, "-0.33 EV"}, {0x0000, "0 EV"}, {0x000c, "0.33 EV"}, {0x0010, "0.50 EV"}, {0x0014, "0.67 EV"}, {0x0020, "1 EV"}, {0x002c, "1.33 EV"}, {0x0030, "1.50 EV"}, {0x0034, "1.67 EV"}, {0x0040, "2 EV"}, {0, NULL} }; for (int fb = 0; flashBias[fb].bias != NULL; fb++) { if (v[15] == flashBias[fb].value) { fmt(ctx, "Flash Exposure Bias", flashBias[fb].bias); break; } } } } catch (...) { return; } } extern void dpyCanonImageNumber(OutputContext &ctx, const char *name, const IFDEntry &e, const void*) { vector v = e.getUVALUE(); try { unsigned long n = v[0]; char img[32]; snprintf(img, sizeof img, "%03lu-%04lu", n / 10000, n % 10000); ctx.startBlock(name) << img; ctx.endBlock(); } catch (...) { return; } } extern void dpyCanonSerialNumber(OutputContext &ctx, const char *name, const IFDEntry &e, const void*) { vector v = e.getUVALUE(); try { unsigned long n = v[0]; char sn[32]; snprintf(sn, sizeof sn, "%04lX%05lu", n >> 16, n & 0xffff); fmt(ctx, "Camera Serial Number", sn); } catch (...) { return; } } extern void dpyCasioDistance(OutputContext &ctx, const char *name, const IFDEntry &e, const void*) { vector v = e.getUVALUE(); const char* units = "mm"; double dist = double(v[0]); if (dist > 1000.0) { dist /= 1000.0; units = "m"; } else if (dist > 10) { dist /= 10; units = "cm"; } ctx.startBlock(name) << dist << units; ctx.endBlock(); } extern void dpyExifFlash(OutputContext &ctx, const char *name, const IFDEntry &e, const void*) { ctx.startBlock(name); vector v = e.getUVALUE(); if (v[0] & 0x01) { ctx.os() << "Flash Fired; "; } else { ctx.os() << "Flash Not Fired; "; } if (v[0] & 0x04) { if (v[0] & 0x02) { ctx.os() << "Return Light Not Detected; "; } else { ctx.os() << "Return Light Detected; "; } } switch (v[0] & 0x18) { case 0x00: break; case 0x08: ctx.os() << "Compulsory Flash Firing; "; break; case 0x10: ctx.os() << "Compulsory Flash Suppression; "; break; case 0x18: ctx.os() << "Auto Mode; "; break; } if (v[0] & 0x20) { ctx.os() << "No Flash Function; "; } if (v[0] & 0x40) { ctx.os() << "Red-Eye Reduction Supported; "; } ctx.endBlock(); } extern void dpyExifComponentConfiguration(OutputContext &ctx, const char *name, const IFDEntry &e, const void*) { ctx.startBlock(name); vector v = e.getOPAQUE(); for (unsigned int i=0; i v = e.getSRATIONAL(); if (v[0].getNumerator() == 0) { ctx.os() << "None"; } else { displayRational(ctx, v[0]); ctx.os() << "x"; } } else { vector v = e.getRATIONAL(); if (v[0].getNumerator() == 0) { ctx.os() << "None"; } else { displayRational(ctx, v[0]); ctx.os() << "x"; } } ctx.endBlock(); } extern void dpyRationalDistance(OutputContext &ctx, const char *name, const IFDEntry &e, const void * units) { ctx.startBlock(name); if (e.getType() == tSRATIONAL) { vector v = e.getSRATIONAL(); if (v[0].getNumerator() == 0) { ctx.os() << "Unknown"; } else if (v[0].getDenominator() == 0) { ctx.os() << "Infinity"; } else { ctx.os() << (double)v[0]; if (units) { ctx.os() << (const char *) units; } } } else { vector v = e.getRATIONAL(); if (v[0].getNumerator() == 0) { ctx.os() << "Unknown"; } else if (v[0].getDenominator() == 0) { ctx.os() << "Infinity"; } else { ctx.os() << (double)v[0]; if (units) { ctx.os() << (const char *) units; } } } ctx.endBlock(); } extern void dpy35mmFocal(OutputContext &ctx, const char *name, const IFDEntry &e, const void*) { ctx.startBlock(name); vector v = e.getUVALUE(); if (v[0] == 0) { ctx.os() << "Unknown"; } else { ctx.os() << v[0] << "mm"; } ctx.endBlock(); } void dpyNikonFocusPosition(OutputContext &ctx, const char *name, const IFDEntry &e, const void*) { vector v = e.getOPAQUE(); ctx.startBlock(name); const char *val = findLookup((int)v[1], lookFocusPosition); if (val) { ctx.os() << val; } else { ctx.os() << "Unknown (" << v[1] << ")"; } ctx.endBlock(); } void dpyTypedComment(OutputContext &ctx, const char *name, const IFDEntry &e, const void*) { vector v = e.getOPAQUE(); ctx.startBlock(name); // The first 8 bytes specify the type char typecode[9]; for (unsigned int i = 0; i < 8; ++i) { if (i < v.size()) { typecode[i] = v[i]; } else { typecode[i] = 0; } } typecode[8]=0; if ((strcmp(typecode,"ASCII") == 0) || (typecode[0] == 0)) { for (unsigned int i = 8; i < v.size(); ++i) { if (isprint(v[i])) { ctx.os() << v[i]; } else { ctx.os() << "."; } } } else { ctx.os() << "Unknown encoding (" << typecode << ")"; } ctx.endBlock(); } void dpyUndefinedString(OutputContext &ctx, const char *name, const IFDEntry &e, const void*) { vector v = e.getOPAQUE(); ctx.startBlock(name); for (unsigned int i = 0; i < v.size(); ++i) { if (v[i] == 0) { ctx.os() << ' '; } else if (isprint(v[i])) { ctx.os() << v[i]; } else { ctx.os() << "."; } } ctx.endBlock(); } // Nikkor Lens display method provided by Ro Ro // Updates for consistency with other modules by Daniel void dpyNikkorLensInfo(OutputContext &ctx, const char *name, const IFDEntry &e, const void*) { vector v = e.getOPAQUE(); ctx.startBlock(name); double d; if ((v[0x13] + v[0x14] + v[0x15] + v[0x16] + v[0x17])!=0) { // should be 'D' d = v[0x09]; // cm = 10^(x/40) d /= 40.0; d = pow(10,d); ctx.os() << "Distance: " << d << "cm; "; } d = v[0x12]; // calc k value - better use the tables from Ken Hancock d /= 24.0; d = pow(2,d); ctx.os() << "Effective Aperture Open: " << d << "; "; d = v[0x12]+v[0x0C]; d /= 24.0; d = pow(2,d); ctx.os() << "Effective Aperture Stopped Down: " << d << "; "; unsigned int c; c = v[0x0B]; if (c<16){ ctx.os() << "Lens ID = 0x0" << hex << c << dec << "; "; } else { ctx.os() << "Lens ID = 0x" << hex << c << dec << "; "; } c = v[0x11]; if (c<16) { ctx.os() << "Matrix Chip ID = 0x0" << hex << c<< dec << "; "; } else { ctx.os() << "Matrix Chip ID = 0x" << hex << c << dec << ";"; } // 76 - 0B - Lens ID // 7A - 11 - Lens Chip Number ctx.endBlock(); /* --------------------------------------------------------------------------------------- **** following documents by * Copyright (c) 1997 Ken Hancock * This document resides at http://members.aol.com/khancock/pilot/nbuddy/ **** provide infos about nikkor lenses - N90s-memory-map.txt 0xFE29 Aperature (zoomed setting ?) 0xFE2D Focus distance cm = 10^(x/40) 0xFE2E Zoom Position (SEE TABLES) 0xFE2F Lens Focal Length Range(Lo) (SEE kFocalTable) 0xFE30 Lens Focal Length Range(Hi) (SEE kFocalTable) 0xFE31 Lens Apperature Range(Lo) (SEE kCameraApertureTable) 0xFE32 Lens Apperature Range(Hi) (SEE kCameraApertureTable) 0xFE33 Lens ID 0xFE51 Effective Aperture (SEE kApertureTable) - NikonStringTables.c.txt const char * kFocalTable[] = { const char * kCameraApertureTable[] = { --------------------------------------------------------------------------------------- * a N90s is useful for comparing data * the Chip Number was guessed through luck: the AF 20mm/2.8 and the AF 35-70mm/3.3-4.5 use the same chip (NEC uPD7554G577) which is different wirded * sample data for Nikkor 50mm/1.8D [0x98-7]: 30 31 30 31 - "0101" ?? Revision 1.01 ?? 25 13 08 03 01 - ?? don't know 85 - 09 - Distance info if D-lens, but how to know? 50 - 0A - Zoom Position 76 - 0B - Lens ID 58 - 0C - Lens Apperature Stops 50 - 0D - Lens Focal Length Short 50 - 0E - Lens Focal Length Long 14 - 0F - Lens Apperature Short 14 - 10 - Lens Apperature Long 7A - 11 - Lens Chip Number 14 - 12 - Effective Aperture 17 42 33 43 06 - ?? only on D ?? 00 00 00 00 00 02 02 - ?? don't know ?? constant */ } metacam-1.2/dpyfuncs.h0000644000076500007650000001424510111706345014342 0ustar daniel00000000000000/* This file is -*-C++-*- ------------------------------------------------------------------------------ MetaCam - Extract EXIF information from digital camera files, with support for Vendor specific blocks. Copyright (C) 2000 Daniel Stephens (daniel@cheeseplant.org) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ------------------------------------------------------------------------------ $Id: dpyfuncs.h,v 1.9 2004/08/21 17:54:20 daniel Exp $ */ #ifndef DPYFUNCS_H_INCLUDED #define DPYFUNCS_H_INCLUDED #include "metacam.h" // Display functions extern void dpyISO(OutputContext &ctx, const char *, const IFDEntry &e, const void*); extern void dpyString(OutputContext &ctx, const char *, const IFDEntry &e, const void*); extern void dpyLens(OutputContext &ctx, const char *, const IFDEntry &e, const void*); extern void dpyZoom(OutputContext &ctx, const char *, const IFDEntry &e, const void*); extern void dpyExpAdjust(OutputContext &ctx, const char *, const IFDEntry &e, const void*); extern void dpyShutter(OutputContext &ctx, const char *, const IFDEntry &e, const void*); extern void dpyAperture(OutputContext &ctx, const char *, const IFDEntry &e, const void*); extern void dpyPixels(OutputContext &ctx, const char *, const IFDEntry &e, const void*); extern void dpySigned(OutputContext &ctx, const char *, const IFDEntry &e, const void*); extern void dpyUnsigned(OutputContext &ctx, const char *, const IFDEntry &e, const void*); extern void dpyResolution(OutputContext &ctx, const char *, const IFDEntry &e, const void*); extern void dpyNULL(OutputContext &ctx, const char *, const IFDEntry &e, const void*); extern void dpyYes(OutputContext &ctx, const char *, const IFDEntry &e, const void*); extern void dpyResolutionType(OutputContext &ctx, const char *, const IFDEntry &e, const void*); extern void dpyBitsPerSample(OutputContext &ctx, const char *, const IFDEntry &e, const void*); extern void dpyUnsignedLookup(OutputContext &ctx, const char *, const IFDEntry &e, const void*); extern void dpyUndefinedLookup(OutputContext &ctx, const char *, const IFDEntry &e, const void*); extern void dpyExifVersion(OutputContext &ctx, const char *, const IFDEntry &e, const void*); extern void dpyExifAperture(OutputContext &ctx, const char *, const IFDEntry &e, const void*); extern void dpyExifShutter(OutputContext &ctx, const char *, const IFDEntry &e, const void*); extern void dpyRationalAsDouble(OutputContext &ctx, const char *, const IFDEntry &e, const void*units); extern void dpyRationalDistance(OutputContext &ctx, const char *, const IFDEntry &e, const void*units); extern void dpyExifFlash(OutputContext &ctx, const char *, const IFDEntry &e, const void*); extern void dpyZoomRatio(OutputContext &ctx, const char *, const IFDEntry &e, const void*); extern void dpy35mmFocal(OutputContext &ctx, const char *, const IFDEntry &e, const void*); extern void dpyExifComponentConfiguration(OutputContext &ctx, const char *, const IFDEntry &e, const void*); extern void dpyNikonFocusPosition(OutputContext &ctx, const char *, const IFDEntry &e, const void*); extern void dpyUndefinedString(OutputContext &ctx, const char *, const IFDEntry &e, const void*); extern void dpyTypedComment(OutputContext &ctx, const char *, const IFDEntry &e, const void*); extern void dpyNikkorLensInfo(OutputContext &ctx, const char *, const IFDEntry &e, const void*); extern void dpyOlymSpecialMode(OutputContext &ctx, const char *, const IFDEntry &e, const void*); extern void dpyOlymZoom(OutputContext &ctx, const char *name, const IFDEntry &e, const void*); extern void dpyCanonBlock1(OutputContext &ctx, const char *name, const IFDEntry &e, const void*); extern void dpyCanonBlock4(OutputContext &ctx, const char *name, const IFDEntry &e, const void*); extern void dpyCanonImageNumber(OutputContext &ctx, const char *name, const IFDEntry &e, const void*); extern void dpyCanonSerialNumber(OutputContext &ctx, const char *name, const IFDEntry &e, const void*); extern void dpyCasioDistance(OutputContext &ctx, const char *name, const IFDEntry &e, const void*); // Lookup lists extern lookupValue lookEmpty[]; extern lookupValue lookYesNo[]; extern lookupValue lookPhotometric[]; extern lookupValue lookCompression[]; extern lookupValue lookYCbCrPositioning[]; extern lookupValue lookExposureProgram[]; extern lookupValue lookMeteringMode[]; extern lookupValue lookLightSource[]; extern lookupValue lookSensingMethod[]; extern lookupValue lookOlymJPEGQuality[]; extern lookupValue lookCasioRecMode[]; extern lookupValue lookCasioQuality[]; extern lookupValue lookCasioFocusMode[]; extern lookupValue lookCasioFlashMode[]; extern lookupValue lookCasioFlashInten[]; extern lookupValue lookCasioWhiteBalance[]; extern lookupValue lookCasioDigitalZoom[]; extern lookupValue lookCasioSharpness[]; extern lookupValue lookCasioContrast[]; extern lookupValue lookCasioSaturation[]; extern lookupValue lookCasioSensitivity[]; extern lookupValue lookExifColorSpace[]; extern lookupValue lookExposureMode[]; extern lookupValue lookWhiteBalance[]; extern lookupValue lookSceneCaptureType[]; extern lookupValue lookGainControl[]; extern lookupValue lookContrast[]; extern lookupValue lookSaturation[]; extern lookupValue lookSubjectDistanceRange[]; extern lookupValue lookFocusPosition[]; extern lookupValue lookSceneType[]; extern lookupValue lookFileSource[]; extern lookupValue lookCustomRendered[]; // Tag Format Lists extern knowntag main_known[]; extern knowntag exif_known[]; extern knowntag empty_known[]; extern knowntag nikon_known[]; extern knowntag olympus_known[]; extern knowntag canon_known[]; extern knowntag casio_known[]; #endif /* DPYFUNCS_H_INCLUDED */ metacam-1.2/editifd.cc0000644000076500007650000000472210111706345014254 0ustar daniel00000000000000/* ------------------------------------------------------------------------------ MetaCam - Extract EXIF information from digital camera files, with support for Vendor specific blocks. Copyright (C) 2000 Daniel Stephens (daniel@cheeseplant.org) 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. ------------------------------------------------------------------------------ */ #include #include "edittiff.h" static const char *rcsid __attribute__((unused))="$Id: editifd.cc,v 1.3 2004/08/21 17:41:35 daniel Exp $"; _EditIFD::_EditIFD(const IFD &src) : source(src) { cerr << "Created new EditIFD()" << endl; if (source) { for (int i=0; i < source.entries(); ++i) table.push_back(source[i]); } } _EditIFD::_EditIFD() { // Nothing to do } _EditIFD::~_EditIFD() { for (unsigned int i=0; i< table.size(); ++i) table[i] = IFDEntry(); table.clear(); } unsigned short _EditIFD::entries() const { return table.size(); } IFD _EditIFD::nextIFD() const { if (next) return next; if (source) { // Copy source next IFD snext = source.nextIFD(); if (!snext) return next; next = IFD(new _EditIFD(snext)); } return next; } bool _EditIFD::isDynamic() const { return true; } IFDEntry _EditIFD::operator[](int n) const { if ((n < 0) || (n >= (int)table.size())) { cerr << "_DataIFD Array Bounds Violated" << endl; exit(2); } return table[n]; } IFDEntry _EditIFD::findEntry(unsigned long tag, _IFDEntry *after) const { bool ready_to_return = (after == 0); for (unsigned int i=0; i table; _EditIFD(const _EditIFD &) { abort(); } _EditIFD &operator=(const _EditIFD &) { abort(); return *this; } public: _EditIFD(const IFD &src); _EditIFD(); ~_EditIFD(); virtual unsigned short entries() const; virtual IFD nextIFD() const; virtual bool isDynamic() const; virtual IFDEntry operator[](int n) const; virtual IFDEntry findEntry(unsigned long tag, _IFDEntry *after=0) const; virtual TIFFDataSource getSource() const; virtual unsigned long getSourceOffset() const; }; /* class _EditIFDEntry : public _IFDEntry { private: TIFFDataSource source; unsigned long value_count; unsigned long offset; public: _EditIFDEntry(const TIFFDataSource &src, long ofs, long t, short typ, long vals); virtual ~_EditIFDEntry(); virtual unsigned long values() const; virtual vector getUVALUE() const; virtual vector getSVALUE() const; virtual vector getRATIONAL() const; virtual vector getSRATIONAL() const; virtual vector getSTRING() const; virtual vector getOPAQUE() const; virtual TIFFDataSource getSource() const; virtual unsigned long getSourceOffset() const; }; */ #endif /* EDITTIFF_H_INCLUDED */ metacam-1.2/exiftags.cc0000644000076500007650000002156410111706345014461 0ustar daniel00000000000000/* ------------------------------------------------------------------------------ MetaCam - Extract EXIF information from digital camera files, with support for Vendor specific blocks. Copyright (C) 2000 Daniel Stephens (daniel@cheeseplant.org) 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. ------------------------------------------------------------------------------ */ #include "dpyfuncs.h" static const char *rcsid __attribute__((unused))="$Id: exiftags.cc,v 1.5 2002/09/02 19:20:01 daniel Exp $"; // Many of these from the TIFF V6.0 Standard // Extra EXIF references from: // http://www.butaman.ne.jp/~tsuruzoh/Computer/Digicams/exif-e.html knowntag main_known[] = { {306, 2, 0, "Image Creation Date" , dpyString, 0}, {271, 2, 0, "Make" , dpyString, 0}, {272, 2, 0, "Model" , dpyString, 0}, {305, 2, 0, "Software Version" , dpyString, 0}, {296, 3, 0, "Resolution Unit" , dpyResolutionType, 0}, {282, 5, 0, "X Resolution" , dpyResolution, 0}, {283, 5, 0, "Y Resolution" , dpyResolution, 0}, {277, 3, 0, "Samples Per Pixel" , dpyUnsigned, 0}, {258, 3, 0, "Bits Per Sample" , dpyBitsPerSample, 0}, {270, 2, 0, "Image Description" , dpyString, 0}, {513, 4, 0, "Jpeg File Format" , dpyYes, 0}, {262, 3, 0, "Photometric Interpretation" , dpyUnsignedLookup, lookPhotometric}, {259, 3, 0, "Compression" , dpyUnsignedLookup, lookCompression}, {0x0213, 3, 0, "YCbCr Positioning" , dpyUnsignedLookup, lookYCbCrPositioning}, {0x0112, 3, 1, "[Orientation]" , 0, 0}, {0x013E, 5, 1, "[White Point]" , 0, 0}, {0x013F, 5, 1, "[Primary Chromacities]" , 0, 0}, {0x0211, 5, 1, "[YCbCr Coefficients]" , 0, 0}, {0x0214, 5, 1, "[Reference Black/White]" , 0, 0}, {257, 3, 1, "Image Length" , dpyNULL, 0}, {257, 4, 1, "Image Length" , dpyNULL, 0}, {256, 3, 1, "Image Width" , dpyNULL, 0}, {256, 4, 1, "Image Width" , dpyNULL, 0}, {278, 3, 2, "Rows Per Strip" , dpyNULL, 0}, {278, 4, 2, "Rows Per Strip" , dpyNULL, 0}, {273, 3, 2, "Strip Offsets" , dpyNULL, 0}, {273, 4, 2, "Strip Offsets" , dpyNULL, 0}, {279, 3, 2, "Strip Byte Counts" , dpyNULL, 0}, {279, 4, 2, "Strip Byte Counts" , dpyNULL, 0}, {284, 3, 2, "Planar Configuration" , dpyNULL, 0}, {514, 4, 2, "JPEG Interchange Fmt Length" , dpyNULL, 0}, {515, 3, 2, "JPEG Restart Interval" , dpyNULL, 0}, // Sometimes Exif tags appear here too {0x9003, 2, 0, "Image Capture Date" , dpyString, 0}, {0,0,0,0,0} }; knowntag exif_known[] = { {0x9291, 2, 0, "Sub-Second Creation Time" , dpyString, 0}, {0x9003, 2, 0, "Image Capture Date" , dpyString, 0}, {0x9290, 2, 0, "Sub-Second Capture Time" , dpyString, 0}, {0x9004, 2, 0, "Image Digitized Date" , dpyString, 0}, {0x9292, 2, 0, "Sub-Second Digitized Time" , dpyString, 0}, {0x9204, 10, 0, "Exposure Bias" , dpyExpAdjust, 0}, {0x920a, 5, 0, "Focal Length" , dpyZoom, 0}, {0x829a, 5, 0, "Exposure Time" , dpyShutter, 0}, {0x829d, 5, 0, "Aperture" , dpyAperture, 0}, {0xa002, 3, 0, "Exif Image Width" , dpyPixels, 0}, {0xa002, 4, 0, "Exif Image Width" , dpyPixels, 0}, {0xa003, 3, 0, "Exif Image Height" , dpyPixels, 0}, {0xa003, 4, 0, "Exif Image Height" , dpyPixels, 0}, {0x8822, 3, 0, "Exposure Program" , dpyUnsignedLookup, lookExposureProgram}, {0xa402, 3, 0, "Exposure Mode" , dpyUnsignedLookup, lookExposureMode}, {0xa403, 3, 0, "White Balance" , dpyUnsignedLookup, lookWhiteBalance}, {0x8827, 3, 0, "ISO Speed Rating" , dpyISO, 0}, {0x9207, 3, 0, "Metering Mode" , dpyUnsignedLookup, lookMeteringMode}, {0x8824, 2, 0, "Spectral Sensitivity" , dpyString, 0}, {0x9000, 7, 0, "EXIF Version" , dpyExifVersion, 0}, {0xa000, 7, 0, "FlashPix Version" , dpyExifVersion, 0}, {0x9208, 3, 0, "Light Source/White Balance" , dpyUnsignedLookup, lookLightSource}, {0x9209, 3, 0, "Flash" , dpyExifFlash, 0}, // Exif 2.2 p39 {0xa217, 3, 0, "Sensing Method" , dpyUnsignedLookup, lookSensingMethod}, {0x9102, 5, 0, "Compressed Bits Per Pixel" , dpyRationalAsDouble, 0}, {0x9202, 5, 0, "Aperture Value" , dpyExifAperture, 0}, {0x9203, 10,0, "Brightness Value" , dpyExpAdjust, 0}, {0x9205, 5, 0, "Max Aperture Value" , dpyExifAperture, 0}, {0xa210, 3, 0, "Focal Plane Resolution Unit" , dpyResolutionType, 0}, {0xa20e, 5, 0, "Focal Plane X Resolution" , dpyResolution, 0}, {0xa20f, 5, 0, "Focal Plane Y Resolution" , dpyResolution, 0}, {0x8298, 2, 0, "Copyright" , dpyString, 0}, {0x9201, 10,0, "Shutter Speed Value" , dpyExifShutter, 0}, {0xa001, 3, 0, "ColorSpace" , dpyUnsignedLookup, lookExifColorSpace}, {0x9101, 7, 0, "Component Configuration" , dpyExifComponentConfiguration, 0}, /** See page 28 of exif std */ {0x9206, 10,0, "Subject Distance" , dpyRationalDistance, "m"}, // Exif 2.2 p 37 {0x9206, 5,0, "Subject Distance" , dpyRationalDistance, "m"}, // Exif 2.2 p 37 {0x920a, 5, 0, "Focal Length" , dpyRationalDistance, "mm"}, // Exif 2.2 p42 {0x920a, 10, 0, "Focal Length" , dpyRationalDistance, "mm"}, // Exif 2.2 p42 {0xa20b, 5, 0, "Flash Energy" , dpyRationalAsDouble, "BCPS"}, // Exif 2.2 p42 {0xa20b, 10, 0, "Flash Energy" , dpyRationalAsDouble, "BCPS"}, // Exif 2.2 p42 {0xa215, 5, 0, "Exposure Index" , dpyRationalAsDouble, 0}, // Exif 2.2 p44 {0xa215, 10, 0, "Exposure Index" , dpyRationalAsDouble, 0}, // Exif 2.2 p44 {0xa404, 5, 0, "Digital Zoom Ratio" , dpyZoomRatio, 0}, // Exif 2.2 p 47 {0xa404, 10, 0, "Digital Zoom Ratio" , dpyZoomRatio, 0}, // Exif 2.2 p 47 {0xa405, 3, 0, "35mm Focal Length" , dpy35mmFocal, 0}, // Exif 2.2 p 47 {0xa406, 3, 0, "Scene Capture Type" , dpyUnsignedLookup, lookSceneCaptureType}, {0xa407, 3, 0, "Gain Control" , dpyUnsignedLookup, lookGainControl}, {0xa408, 3, 0, "Contrast" , dpyUnsignedLookup, lookContrast}, {0xa409, 3, 0, "Saturation" , dpyUnsignedLookup, lookSaturation}, {0xa40a, 3, 0, "Sharpness" , dpyUnsignedLookup, lookContrast}, {0xa40c, 3, 0, "Subject Distance Range" , dpyUnsignedLookup, lookSubjectDistanceRange}, {0xa420, 2, 0, "Image Unique ID" , dpyString, 0}, {0xa301, 7, 1, "Scene Type" , dpyUndefinedLookup, lookSceneType}, // Exif 2.2 p 45 {0xa300, 7, 1, "File Source" , dpyUndefinedLookup, lookFileSource}, // Exif 2.2 p 45 {0xa401, 3, 1, "Custom Rendered" , dpyUnsignedLookup, lookCustomRendered}, // Exif 2.2 p 46 {0x9286, 7, 1, "User Comment" , dpyTypedComment, 0}, // Items from Exif standard {0x8828, 7, 1, "[OECF]" , 0, 0}, // Exif 2.2 p 35 {0x9214, 3, 1, "[Subject Area]" , 0, 0}, // Exif 2.2 p 40 {0xa20c, 7, 1, "[SpatialFrequencyResponse]" , 0, 0}, // Exif 2.2 p 42 {0xa214, 3, 1, "[Subject Location]" , 0, 0}, // Exif 2.2 p 44 {0xa302, 7, 1, "[CFA Pattern]" , 0, 0}, // Exif 2.2 p 45 {0xa40b, 7, 1, "[Device Setting Description]", 0, 0}, // Exif 2.2 p 49 {0x9286, 7, 1, "[User Comment]" , 0, 0}, {0xa004, 2, 1, "[Related Sound File]" , 0, 0}, {0xa005, 4, 2, "[ExifInteroperabilityOffset]", 0, 0}, {0,0,0,0,0} }; knowntag empty_known[] = { {0,0,0,0,0} }; metacam-1.2/filetiff.cc0000644000076500007650000000641210111706345014432 0ustar daniel00000000000000/* ------------------------------------------------------------------------------ MetaCam - Extract EXIF information from digital camera files, with support for Vendor specific blocks. Copyright (C) 2000 Daniel Stephens (daniel@cheeseplant.org) 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. ------------------------------------------------------------------------------ */ #include #include #include #include #include "filetiff.h" static const char *rcsid __attribute__((unused))="$Id: filetiff.cc,v 1.3 2004/08/21 17:40:29 daniel Exp $"; _FileTIFF::_FileTIFF(istream &i, unsigned long ofs) : is(i), global_offset(ofs), good(true) { seek(0); unsigned char header[2]; getData(header,2); if ((header[0] == 'I') && (header[1] == 'I')) { bigendian = false; } else if ((header[0] == 'M') && (header[1] == 'M')) { bigendian = true; } else { good = false; // cerr << "Unknown byte ordering - aborting" << endl; // exit(2); return; } unsigned short checknum = getUShort(); if (checknum != 42) { good = false; // cerr << "Bad checknum: " << checknum << endl; // exit(2); return; } } _FileTIFF::~_FileTIFF() { // Nothing } void _FileTIFF::seek(unsigned long ofs) { is.seekg(ofs+global_offset, ios::beg); } size_t _FileTIFF::getData(unsigned char *buf, size_t bytes) { is.read((char*)buf, bytes); if (is.gcount() != bytes) { // int err = errno; // cerr << "Read failed: " << strerror(err) << endl; // exit(2); return is.gcount(); } return bytes; } unsigned char _FileTIFF::getUByte() { unsigned char b = 0; getData((unsigned char *)&b, 1); return b; } unsigned short _FileTIFF::getUShort() { unsigned short s = 0; getData((unsigned char *)&s, 2); if (bigendian) {return ntohs(s);} return s; } unsigned long _FileTIFF::getULong() { unsigned long l = 0; getData((unsigned char *)&l, 4); if (bigendian) {return ntohl(l);} return l; } signed char _FileTIFF::getSByte() { signed char b = 0; getData((unsigned char *)&b, 1); return b; } signed short _FileTIFF::getSShort() { signed short s = 0; getData((unsigned char *)&s, 2); if (bigendian) {return ntohs(s);} return s; } signed long _FileTIFF::getSLong() { signed long l = 0; getData((unsigned char *)&l, 4); if (bigendian) {return ntohl(l);} return l; } IFD _FileTIFF::getIFD() { return _TIFFDataSource::getIFD(firstIFDOffset()); } IFD _FileTIFF::getIFD(unsigned long ofs) { return _TIFFDataSource::getIFD(ofs); } bool _FileTIFF::bigEndian() const { return bigendian; } bool _FileTIFF::isGood() const { return good; } metacam-1.2/filetiff.h0000644000076500007650000000436110111706345014275 0ustar daniel00000000000000/* This file is -*-C++-*- ------------------------------------------------------------------------------ MetaCam - Extract EXIF information from digital camera files, with support for Vendor specific blocks. Copyright (C) 2000 Daniel Stephens (daniel@cheeseplant.org) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ------------------------------------------------------------------------------ $Id: filetiff.h,v 1.2 2002/09/02 19:20:01 daniel Exp $ */ #ifndef FILETIFF_H_INCLUDED #define FILETIFF_H_INCLUDED #include #include "metatiff.h" class _FileTIFF; // class _FileIFD; // class _FileIFDEntry; // class _FileTIFFDataSource; class _FileTIFF : public _TIFFDataSource { friend class _FileIFD; friend class _FileIFDEntry; friend class _FileTIFFDataSource; private: istream &is; unsigned long global_offset; bool bigendian; bool good; protected: virtual void seek(unsigned long ofs); virtual unsigned long tell() const { return streamoff(is.tellg())-global_offset; } virtual size_t getData(unsigned char *buf, size_t bytes); virtual unsigned char getUByte(); virtual unsigned short getUShort(); virtual unsigned long getULong(); virtual signed char getSByte(); virtual signed short getSShort(); virtual signed long getSLong(); virtual bool bigEndian() const; unsigned long firstIFDOffset() { seek(4); return getULong(); } public: _FileTIFF(istream &i, unsigned long ofs=0); virtual ~_FileTIFF(); virtual IFD getIFD(); virtual IFD getIFD(unsigned long ofs); virtual bool isGood() const; }; #endif /* FILETIFF_H_INCLUDED */ metacam-1.2/layout.txt0000644000076500007650000002072610111706345014415 0ustar daniel00000000000000From comparing the 12 TIF images obtained from imaging-resource, the following blocks do not vary: 0x000 00 15 82 9A 00 05 00 00 00 01 00 00 07 84 82 9D ................ JPEG 00 1A 82 9A 00 05 00 00 00 01 00 00 02 2E 82 9D == == == 0x010 00 05 00 00 00 01 00 00 07 8C 88 22 00 03 00 00 ...........".... JPEG 00 05 00 00 00 01 00 00 02 36 88 22 00 03 00 00 == == 0x020 00 01 00 ** 00 00 90 00 00 07 00 00 00 04 30 32 ...*..........02 **----------- (02,03) JPEG 00 01 00 03 00 00 90 00 00 07 00 00 00 04 30 32 0x030 31 30 90 03 00 02 00 00 00 14 00 00 07 94 90 04 10.............. JPEG 31 30 90 03 00 02 00 00 00 14 00 00 02 3E 90 04 == == 0x040 00 02 00 00 00 14 00 00 07 A8 92 04 00 0A 00 00 ................ JPEG 00 02 00 00 00 14 00 00 02 52 91 01 00 07 00 00 == == == == == 0x050 00 01 00 00 07 BC 92 05 00 05 00 00 00 01 00 00 ................ JPEG 00 04 01 02 03 00 91 02 00 05 00 00 00 01 00 00 == == == == == == == 0x060 07 C4 92 07 00 03 00 00 00 01 00 05 00 00 92 0A ................ JPEG 02 66 92 04 00 0A 00 00 00 01 00 00 02 6E 92 05 == == == == == == == == 0x070 00 05 00 00 00 01 00 00 07 CC 92 7C 00 07 00 00 ...........|.... JPEG 00 05 00 00 00 01 00 00 02 76 92 07 00 03 00 00 == == == == 0x080 01 8A 00 00 07 D4 92 86 00 07 00 00 00 30 00 00 .............0.. JPEG 00 01 00 05 00 00 92 0A 00 05 00 00 00 01 00 00 == == == == == == == == [ JPEG GETS OUT OF SYNC AGAIN 02 7E 92 7C 00 07 00 00 01 8A 00 00 02 86 92 86 00 07 00 00 00 30 00 00 ] 0x090 09 5E 92 90 00 02 00 00 00 03 ** ** 00 00 92 91 .^........**.... ***** ---- ("03","09","14","15","22", "24","34","36","43","61","64") JPEG 04 10 92 90 00 02 00 00 00 03 30 35 00 00 92 91 == == **** ----- ("05") 0x0A0 00 02 00 00 00 03 ** ** 00 00 92 92 00 02 00 00 ......**........ ***** ----- Always same as above JPEG 00 02 00 00 00 03 30 35 00 00 92 92 00 02 00 00 0x0B0 00 03 ** ** 00 00 A0 00 00 07 00 00 00 04 30 31 ..**..........01 ***** ----- Always same as above JPEG 00 03 30 35 00 00 A0 00 00 07 00 00 00 04 30 31 0x0C0 30 30 A0 01 00 03 00 00 00 01 00 01 00 00 A2 17 00.............. JPEG 30 30 A0 01 00 03 00 00 00 01 00 01 00 00 A0 02 == == 0x0D0 00 03 00 00 00 01 00 02 00 00 A3 00 00 07 00 00 ................ JPEG 00 03 00 00 00 01 07 D0 00 00 A0 03 00 03 00 00 == == == == == 0x0E0 00 01 03 00 00 00 A3 01 00 07 00 00 00 01 01 00 ................ JPEG 00 01 05 20 00 00 A0 05 00 04 00 00 00 01 00 00 == == == == == == 0x0F0 00 00 A3 02 00 07 00 00 00 08 00 00 09 8E 00 00 ................ JPEG 04 48 A2 17 00 03 00 00 00 01 00 02 00 00 A3 00 == == == == == == == == == == [ More SYNC recovery 00 07 00 00 00 01 03 00 00 00 A3 01 00 07 00 00 00 01 01 00 00 00 A3 02 00 07 00 00 00 08 00 00 04 40 00 00 ] 0x100 00 00 00 00 00 0A 00 00 ** ** 00 00 00 ** 00 00 ........**...*.. ***** --- (00 C8 [200], 01 2C [300], 01 90 [400], 1F 40 [8000]) My guess is this is the ISO speed ** --- (B,C,P) JPEG 00 00 00 00 00 0A 00 00 01 2C 00 00 00 50 00 00 0x110 00 0A .. JPEG 00 0A DATE1 274 "1999:10:06 03:29:14" DATE2 294 "1999:10:06 03:29:14" [ JPEG files are a little different and have these extra 8 bytes 00 00 00 04 00 00 00 01 ] 0x13A 00 00 00 ** 00 00 00 06 00 00 00 1E 00 00 00 0A ...*............ ** ---- (00,0A,0C) JPEG 00 00 00 00 00 00 00 06 00 00 00 1E 00 00 00 0A 0x14A 00 00 ** ** 00 00 00 0A 00 15 00 01 00 07 00 00 ..**............ ***** ---- (01 5E [350], 04 1A [1050]) Probably 35 and 105 - For lens focal lengths? That seems to match the JPG version pretty well too (0x28C in file) JPEG 00 00 04 1A 00 00 00 0A 00 15 00 01 00 07 00 00 0x15A 00 04 30 31 30 30 00 02 00 03 00 00 00 02 00 00 ..0100.......... JPEG 00 04 30 31 30 30 00 02 00 03 00 00 00 02 00 00 0x16A 00 C8 00 03 00 02 00 00 00 06 00 00 08 D6 00 04 ................ JPEG 00 C8 00 03 00 02 00 00 00 06 00 00 03 88 00 04 == == 0x17A 00 02 00 00 00 08 00 00 08 DC 00 05 00 02 00 00 ................ JPEG 00 02 00 00 00 08 00 00 03 8E 00 05 00 02 00 00 == == 0x18A 00 0D 00 00 08 E4 00 06 00 02 00 00 00 07 00 00 ................ JPEG 00 0D 00 00 03 96 00 06 00 02 00 00 00 07 00 00 == == 0x19A 08 F1 00 07 00 02 00 00 00 07 00 00 08 F8 00 08 ................ JPEG 03 A3 00 07 00 02 00 00 00 07 00 00 03 AA 00 08 == == == == 0x1AA 00 02 00 00 00 0D 00 00 08 FF 00 09 00 02 00 00 ................ JPEG 00 02 00 00 00 0D 00 00 03 B1 00 09 00 02 00 00 == == 0x1BA 00 09 00 00 09 0C 00 0B 00 08 00 00 00 01 00 00 ................ JPEG 00 09 00 00 03 BE 00 0B 00 08 00 00 00 01 00 00 == == 0x1CA 00 00 00 0C 00 05 00 00 00 04 00 00 09 15 00 0D ................ JPEG 00 00 00 0C 00 05 00 00 00 04 00 00 03 C7 00 0D == == 0x1DA 00 07 00 00 00 04 ** 01 03 00 00 0E 00 07 00 00 ......*......... ** --- (00, 04, FD) JPEG 00 07 00 00 00 04 00 01 03 00 00 0E 00 07 00 00 0x1EA 00 04 00 01 0C 00 00 81 00 02 00 00 00 09 00 00 ................ JPEG 00 04 00 01 0C 00 00 81 00 02 00 00 00 09 00 00 0x1FA 09 35 00 83 00 01 00 00 00 01 00 00 00 00 00 84 .5.............. JPEG 03 E7 00 83 00 01 00 00 00 01 00 00 00 00 00 84 == == 0x20A 00 05 00 00 00 04 00 00 09 3E 00 87 00 01 00 00 .........>...... JPEG 00 05 00 00 00 04 00 00 03 F0 00 87 00 01 00 00 == == 0x21A 00 01 00 00 00 00 00 88 00 07 00 00 00 04 ** 00 ................ ** --- (01, 00) JPEG 00 01 00 00 00 00 00 88 00 07 00 00 00 04 01 00 0x22A ** 00 00 89 00 01 00 00 00 01 ** 00 00 00 00 8A ................ ** --- (00,01) ** ----- (0A,00) JPEG 01 00 00 89 00 01 00 00 00 01 0A 00 00 00 00 8A 0x23A 00 03 00 00 00 01 00 00 00 00 00 8B 00 07 00 00 ................ JPEG 00 03 00 00 00 01 00 02 00 00 00 8B 00 07 00 00 == 0x24A 00 04 ** 01 0C 00 00 00 00 00 ..*....... ** ------- (H,T) JPEG 00 04 54 01 0C 00 00 00 00 00 STRING 596 "COLOR" *FORMAT 602 "RGB " (RGB,FINE,NORMAL) WHITEBALANCE 610 "WHITE PRESET" (WHITE PRESET,SUNNY,AUTO) *SHARPENING 623 "NORMAL" (NORMAL,LOW,HIGH,NONE) *FOCUS 630 "AF-S " (AF-S,AF-C,MANUAL) STRING 637 " " STRING 650 " " 0x293 00 00 ** ** 00 00 01 00 00 00 01 ** 00 00 01 00 ..**.......*.... ***** -- (01 DE [478], 02 0F [527], 02 1F [543]) ** --------- (83,3D,33) JPEG 00 00 01 DE 00 00 01 00 00 00 01 83 00 00 01 00 0x2A3 00 00 ** ** 00 00 01 00 00 00 01 ** 00 00 01 00 ..**.......*.... ***** -- (00 FC [252], 00 FD [253], 00 FE [254], 01 00 [256]) ** -------- (00,05,08,07,08) JPEG 00 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 STRING 691 "NORMAL " (NORMAL,LOW) 0x2BC 00 00 ** ** 00 00 00 0A 00 00 ** ** 00 00 00 0A ..**......**.... ***** ------ (00 AA [170], 04 1A [1050]) ** ** ----- (01 5E [350], 04 1A [1050]) My guess is that this pair is the high and low range of the focal length for the lens JPEG 00 00 04 1A 00 00 00 0A 00 00 04 1A 00 00 00 0A 0x2CC 00 00 00 1C 00 00 00 0A 00 00 00 1C 00 00 00 0A ................ JPEG 00 00 00 1C 00 00 00 0A 00 00 00 1C 00 00 00 0A 0x2DC 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ JPEG 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x2EC 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ JPEG 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x2FC 00 00 .. metacam-1.2/lookups.cc0000644000076500007650000001436210111706345014341 0ustar daniel00000000000000/* ------------------------------------------------------------------------------ MetaCam - Extract EXIF information from digital camera files, with support for Vendor specific blocks. Copyright (C) 2000 Daniel Stephens (daniel@cheeseplant.org) 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. ------------------------------------------------------------------------------ */ #include "dpyfuncs.h" static const char *rcsid __attribute__((unused))="$Id: lookups.cc,v 1.3 2002/09/02 19:20:01 daniel Exp $"; lookupValue lookEmpty[] = { {0,0} }; lookupValue lookYesNo[] = { {0, "No"}, {1, "Yes"}, {0,0} }; lookupValue lookPhotometric[] = { {0, "White Is Zero"}, {1, "Black Is Zero"}, {2, "RGB"}, {3, "RGB Palette"}, {4, "Transparency Mask"}, {5, "CMYK"}, {6, "YCbCr"}, {8, "CIELab"}, {0,0} }; lookupValue lookCompression[] = { {1, "Uncompressed"}, {2, "CCITT 1D"}, {3, "Group 3 FAX"}, {4, "Group 4 Fax"}, {5, "LZW"}, {6, "JPEG"}, {32773, "PackBits"}, {0,0} }; lookupValue lookYCbCrPositioning[] = { {1, "Center of Array"}, {2, "Datum Point"}, {0,0} }; lookupValue lookExposureProgram[] = { {0, "Not Defined"}, {1, "Manual Control"}, {2, "Program Normal"}, {3, "Aperture Priority"}, {4, "Shutter Priority"}, {5, "Program Creative"}, {6, "Program Action"}, {7, "Portrait Mode"}, {8, "Landscape Mode"}, {0,0} }; lookupValue lookMeteringMode[] = { {0, "Unknown"}, {1, "Average"}, {2, "Center Weighted Average"}, {3, "Spot"}, {4, "Multi-Spot"}, {5, "Multi-Segment/Pattern"}, {6, "Partial"}, {255, "Other"}, {0,0} }; lookupValue lookLightSource[] = { {0, "Automatic"}, {1, "Daylight"}, {2, "Fluorescent"}, {3, "Tungsten"}, {4, "Flash"}, {9, "Fine Weather"}, {10, "Cloudy Weather"}, {11, "Shade"}, {12, "Daylight Fluorescent (D 5700-7100K)"}, {13, "Day White Fluorescent (N 4600-5400K)"}, {14, "Cool White fluorescent (W 3900-4500K)"}, {15, "White Fluorescent (WW 3200-3700K)"}, {17, "Standard Light A"}, {18, "Standard Light B"}, {19, "Standard Light C"}, {20, "D55"}, /* Added 20 - Overcast for Olympus D-510Z Thanks to Geoff Kuenning (geoff@cs.hmc.edu) for patch Updated 2002-09-02 based on Exif 2.2 standard */ {21, "D65"}, {22, "D75"}, {23, "D50"}, {24, "ISO Studio Tungsten"}, {255, "Other Light Source"}, {0,0} }; lookupValue lookSensingMethod[] = { {1, "Not Defined"}, {2, "Single Chip Color Area Sensor"}, {3, "Two Chip Color Area Sensor"}, {4, "Three Chip Color Area Sensor"}, {5, "Color Sequential Area Sensor"}, {7, "Trilinear Sensor"}, {8, "Color Sequential Linear Sensor"}, {0,0} }; lookupValue lookOlymJPEGQuality[] = { {1, "SQ"}, {2, "HQ"}, {3, "SHQ"}, {0,0} }; lookupValue lookCasioRecMode[] = { {1, "Single Shutter"}, {2, "Panorama"}, {3, "Night Scene"}, {4, "Portrait"}, {5, "Landscape"}, {0,0} }; lookupValue lookCasioQuality[] = { {1, "Economy"}, {2, "Normal"}, {3, "Fine"}, {0,0} }; lookupValue lookCasioFocusMode[] = { {2, "Macro"}, {3, "Auto Focus"}, {4, "Manual Focus"}, {5, "Infinity"}, {0,0} }; lookupValue lookCasioFlashMode[] = { {1, "Auto"}, {2, "On"}, {3, "Off"}, {4, "Red Eye Reduction"}, {0,0} }; lookupValue lookCasioFlashInten[] = { {11, "Weak"}, {13, "Normal"}, {15, "Strong"}, {0,0} }; lookupValue lookCasioWhiteBalance[] = { {1, "Auto"}, {2, "Tungsten"}, {3, "Daylight"}, {4, "Flurescent"}, {5, "Shade"}, {129, "Manual"}, {0,0} }; lookupValue lookCasioDigitalZoom[] = { {0x10000, "Off"}, {0x10001, "2X"}, {0,0} }; lookupValue lookCasioSharpness[] = { {0, "Normal"}, {1, "Soft"}, {2, "Hard"}, {0,0} }; lookupValue lookCasioContrast[] = { {0, "Normal"}, {1, "Low"}, {2, "High"}, {0,0} }; lookupValue lookCasioSaturation[] = { {0, "Normal"}, {1, "Low"}, {2, "High"}, {0,0} }; lookupValue lookCasioSensitivity[] = { /* QV3000 Only: */ {64, "Normal"}, {125, "+1.0"}, {250, "+2.0"}, {244, "+3.0"}, /* QV2000/QV8000 Only: */ {80, "Normal"}, {100, "High"}, {0,0} }; lookupValue lookExifColorSpace[] = { {1, "sRGB"}, {0x0FFFF, "Uncalibrated"}, {0,0} }; lookupValue lookExposureMode[] = { {0, "Auto Exposure"}, {1, "Manual Exposure"}, {2, "Auto Bracket"}, {0,0} }; lookupValue lookWhiteBalance[] = { {0, "Auto White Balance"}, {1, "Manual White Balance"}, {0,0} }; lookupValue lookSceneCaptureType[] = { {0, "Standard"}, {1, "Landscape"}, {2, "Portrait"}, {3, "Night Scene"}, {0,0} }; lookupValue lookGainControl[] = { {0, "None"}, {1, "Low Gain Up"}, {2, "High Gain Up"}, {3, "Low Gain Down"}, {4, "High Gain Down"}, {0,0} }; lookupValue lookContrast[] = { {0, "Normal"}, {1, "Soft"}, {2, "Hard"}, {0,0} }; lookupValue lookSaturation[] = { {0, "Normal"}, {1, "Low Saturation"}, {2, "High Saturation"}, {0,0} }; lookupValue lookSubjectDistanceRange[] = { {0, "Unknown"}, {1, "Macro"}, {2, "Close View"}, {3, "Distant View"}, {0,0} }; lookupValue lookFocusPosition[] = { {0, "Center"}, {1, "Top"}, {2, "Bottom"}, {3, "Left"}, {4, "Right"}, {0,0} }; lookupValue lookCustomRendered[] = { {0, "Normal Process"}, {1, "Custom Process"}, {0,0} }; lookupValue lookSceneType[] = { {1, "Directly Photographed"}, {0,0} }; lookupValue lookFileSource[] = { {3, "DSC"}, {0,0} }; metacam-1.2/metacam.cc0000644000076500007650000002243010111706345014247 0ustar daniel00000000000000/* ------------------------------------------------------------------------------ MetaCam - Extract EXIF information from digital camera files, with support for Vendor specific blocks. Copyright (C) 2000 Daniel Stephens (daniel@cheeseplant.org) 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. ------------------------------------------------------------------------------ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "metacam.h" #include "filetiff.h" #include "odrivers.h" #include "dpyfuncs.h" static const char *rcsid __attribute__((unused))="$Id: metacam.cc,v 1.12 2004/08/21 17:11:17 daniel Exp $"; static void processIFD(const IFD &ifd, tagmap &tag_map) { for (int i=0; istartGroup(header); ctx->setContextValue("resolutionUnit", "Inch"); tagmap::iterator iter; for (int i=0; known[i].tag; ++i) { idpair id(known[i].tag, known[i].type); iter = tag_map.find(id); if (iter == tag_map.end()) {continue;} IFDEntry e = (*iter).second; if (!e) continue; tag_map[id] = IFDEntry(); if (known[i].verbose > verbose) continue; if (known[i].func) { known[i].func(*ctx, known[i].name, e, known[i].funcdata); } else { ctx->startBlock(known[i].name); e.outputValue(ctx->os()); } ctx->endBlock(); } if (verbose > 1) { for (iter=tag_map.begin(); iter != tag_map.end(); ++iter) { if (!(*iter).second) continue; IFDEntry e = (*iter).second ; ostringstream taghdr; taghdr << "[0x" << hex << e.getTag() << dec << "-" << e.getType() << "]" << ends; ctx->startBlock(taghdr.str()); e.outputValue(ctx->os()); ctx->endBlock(); } } driver->endGroup(); } void clearTagMap(tagmap &tag_map) { tagmap::iterator iter; for (iter = tag_map.begin(); iter != tag_map.end(); ++iter) { if ((*iter).second) (*iter).second = IFDEntry(); } tag_map.clear(); } static int verbose_option=0; static int help_option=0; static int all_option=0; static int xml_option=0; static int verbose_level = 0; static void processFile(OutputDriver *driver, const char *fname, istream &is) { tagmap tag_map; unsigned char header[2]; is.read((char*)header, 2); if (is.gcount() != 2) { int err = errno; cerr << "Read failed: " << strerror(err) << endl; return; } driver->startFile(fname); int ofs=0; if ((header[0] == 0xFF) && (header[1] == 0xD8)) { // JPEG File // Search through file for Exif header.... int curofs = 2; unsigned char scanbuf[1024]; int startofs = 0; // Where do we start reading into the buffer bool failed_scan = false; bool found_exif = true; while (!is.eof()) { if (!is.good()) { int err = errno; cerr << "Failure while scanning: " << strerror(err) << endl; failed_scan = true; break; } is.read((char*)&scanbuf[startofs], 1024 - startofs); int got = is.gcount(); if (got == 0) continue; if (got < 0) { int err = errno; cerr << "Failure while scanning: " << strerror(err) << endl; failed_scan = true; break; } // Pretend we read the WHOLE buffer got += startofs; // If we didn't get enough, try to get more if (got < 4) { startofs = got; continue; } for (int i=0; iendFile(); return; } tiffUNSIGNED exif_ifd_start = 0; IFD maker_ifd; knowntag *maker_known_table = 0; // Get IFD0 IFD ifd = tiff.getIFD(); processIFD(ifd, tag_map); ifd = ifd.nextIFD(); // Look for the EXIF IFD idpair exif_id(0x8769, 4); tagmap::iterator iter = tag_map.find(exif_id); if (iter != tag_map.end() && ((*iter).second)) { vector uv = (*iter).second.getUVALUE(); exif_ifd_start = uv[0]; (*iter).second = IFDEntry(); } string maker_name; // For later use idpair makername_id(0x010f, 2); iter = tag_map.find(makername_id); if (iter != tag_map.end() && ((*iter).second)) { vector v = (*iter).second.getSTRING(); maker_name = v[0]; } displayTags(driver, "Standard Fields", tag_map, main_known, verbose_level); clearTagMap(tag_map); if (exif_ifd_start) { IFD exif = tiff.getIFD(exif_ifd_start); processIFD(exif, tag_map); // Look for the MakerNote idpair makernote_id(0x927C, 7); iter = tag_map.find(makernote_id); if (iter != tag_map.end() && ((*iter).second)) { if (strncmp(maker_name.data(), "NIKON", 5) == 0) { unsigned char nikontest[7]; nikontest[6] = 0; tiff.seek((*iter).second.getSourceOffset()); tiff.getData(nikontest, 6); if (strcmp((const char *)nikontest,"Nikon") == 0) { // Strange new D100 way of doing things TIFFDataSource ntiff(new _FileTIFF(is, ofs + (*iter).second.getSourceOffset() + 10)); if (ntiff.isGood()) maker_ifd = ntiff.getIFD(); } else { maker_ifd = tiff.getIFD((*iter).second.getSourceOffset()); } maker_known_table = nikon_known; (*iter).second = IFDEntry(); } else if (strncmp(maker_name.data(), "OLYMP", 5) == 0) { maker_ifd = tiff.getIFD((*iter).second.getSourceOffset()+0x08); maker_known_table = olympus_known; (*iter).second = IFDEntry(); } else if (strncasecmp(maker_name.data(), "CASIO", 5) == 0) { maker_ifd = tiff.getIFD((*iter).second.getSourceOffset()); maker_known_table = casio_known; (*iter).second = IFDEntry(); } else if (strncasecmp(maker_name.data(), "CANON", 5) == 0) { maker_ifd = tiff.getIFD((*iter).second.getSourceOffset()); maker_known_table = canon_known; (*iter).second = IFDEntry(); } } displayTags(driver, "EXIF Fields", tag_map, exif_known, verbose_level); clearTagMap(tag_map); } if (maker_ifd && maker_known_table) { processIFD(maker_ifd, tag_map); displayTags(driver, "Manufacturer Fields", tag_map, maker_known_table, verbose_level); clearTagMap(tag_map); } driver->endFile(); } extern int main(int argc, char *argv[]) { while (1) { int oidx; int opt = getopt_long(argc, argv, "havx", opts, &oidx); if (opt == -1) break; switch (opt) { case 'h': help_option = 1; break; case 'v': verbose_option = 1; break; case 'a': all_option = 1; break; case 'x': xml_option = 1; break; } } if ((optind >= argc) || (help_option)) { cerr << "Usage: " << argv[0] << " [filename(s)...]" << endl; cerr << endl << " -h,--help Display this help" << endl << " -v,--verbose Display unknown tags too" << endl << " -a,--all Display ALL tags (implies -v)" << endl << " -x,--xml Output as XML" << endl << endl; if (!help_option) exit(2); exit(0); } if (verbose_option) verbose_level = 1; if (all_option) verbose_level = 2; OutputDriver *odriver = 0; if (xml_option) { odriver = new XMLOutputDriver(cout); } else { odriver = new DisplayOutputDriver(cout); } for (int o=optind; oclose(); delete odriver; } // Table of tags I know about // 1000000+ are tags in the odd Nikon data structure // Tags at the bottom are 'real' tags I know about and want to ignore metacam-1.2/metacam.h0000644000076500007650000000667010111706345014121 0ustar daniel00000000000000/* This file is -*-C++-*- ------------------------------------------------------------------------------ MetaCam - Extract EXIF information from digital camera files, with support for Vendor specific blocks. Copyright (C) 2000 Daniel Stephens (daniel@cheeseplant.org) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ------------------------------------------------------------------------------ $Id: metacam.h,v 1.6 2004/08/21 17:11:17 daniel Exp $ */ #ifndef METACAM_H_INCLUDED #define METACAM_H_INCLUDED #include #include "metatiff.h" class idpair { private: unsigned long tag; unsigned short type; public: idpair() : tag(0), type(0) {}; idpair(unsigned long a, unsigned short b) : tag(a), type(b) {}; bool operator==(const idpair &i) const { return (tag==i.tag) && (type == i.type); } bool operator!=(const idpair &i) const { return (tag!=i.tag) || (type != i.type); } bool operator<=(const idpair &i) const { if (tag < i.tag) return true; if (tag > i.tag) return false; return (type <= i.type); } bool operator<(const idpair &i) const { if (tag < i.tag) return true; if (tag > i.tag) return false; return (type < i.type); } bool operator>(const idpair &i) const { if (tag > i.tag) return true; if (tag < i.tag) return false; return (type > i.type); } bool operator>=(const idpair &i) const { if (tag > i.tag) return true; if (tag < i.tag) return false; return (type >= i.type); } }; typedef map tagmap; class OutputContext { private: map cmap; public: OutputContext() {}; virtual ~OutputContext(); string getContextValue(string key) { map::iterator iter = cmap.find(key); if (iter == cmap.end()) return string(); return (*iter).second; } void setContextValue(string key, string val) { cmap[key] = val; } bool hasContextValue(string key) { map::iterator iter = cmap.find(key); return (iter != cmap.end()); } virtual ostream &startBlock(const char *hdr) = 0; virtual ostream &startBlock(const string &hdr) = 0; virtual ostream &os() = 0; virtual void endBlock() = 0; }; class OutputDriver { public: virtual ~OutputDriver(); virtual void startFile(const char *fname) = 0; virtual OutputContext *startGroup(const char *header) = 0; virtual OutputContext *startGroup(const string &header) = 0; virtual void endGroup() = 0; virtual void endFile() = 0; virtual void close() = 0; }; typedef void dpyFunction(OutputContext &ctx, const char *, const IFDEntry &e, const void *fdata); struct knowntag { unsigned long tag; unsigned short type; int verbose; const char *name; dpyFunction *func; const void *funcdata; }; struct lookupValue { int key; const char *value; }; #endif /* METACAM_H_INCLUDED */ metacam-1.2/metatiff.cc0000644000076500007650000000477010111706345014446 0ustar daniel00000000000000/* ------------------------------------------------------------------------------ MetaCam - Extract EXIF information from digital camera files, with support for Vendor specific blocks. Copyright (C) 2000 Daniel Stephens (daniel@cheeseplant.org) 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. ------------------------------------------------------------------------------ */ #include #include "metatiff.h" #include "datatiff.h" #include "edittiff.h" static const char *rcsid __attribute__((unused))="$Id: metatiff.cc,v 1.2 2002/09/02 19:20:01 daniel Exp $"; _ReferenceCounted::~_ReferenceCounted() { // Nothing } _IFD::~_IFD() { if (getRefCount()) { cerr << "DEBUG: Deleting _IFD with reference count of " << getRefCount() << endl; } } _IFDEntry::~_IFDEntry() { if (getRefCount()) { cerr << "DEBUG: Deleting _IFDEntry with reference count of " << getRefCount() << endl; } } int _IFDEntry::typeLength(unsigned short type) { switch (type) { case tBYTE: return 1; /* BYTE */ case tASCII: return 1; /* ASCII */ case tSHORT: return 2; /* SHORT */ case tLONG: return 4; /* LONG */ case tRATIONAL: return 8; /* RATIONAL */ case tSBYTE: return 1; /* SBYTE */ case tUNDEFINED: return 1; /* UNDEFINED */ case tSSHORT: return 2; /* SSHORT */ case tSLONG: return 4; /* SLONG */ case tSRATIONAL: return 8; /* SRATIONAL */ case tFLOAT: return 4; /* FLOAT */ case tDOUBLE: return 8; /* DOUBLE */ }; cerr << "WARNING: Unknown field type " << type << endl; return 0; } _TIFFDataSource::~_TIFFDataSource() { // Nothing } IFD TIFFDataSource::getIFD() const { return src->getIFD(); } IFD TIFFDataSource::getIFD(unsigned long ofs) const { return src->getIFD(ofs); } IFD IFD::getEditable() { return IFD(new _EditIFD(*this)); } int _BaseAnnotation::next_avail_type = taFIRST_AVAILABLE; metacam-1.2/metatiff.h0000644000076500007650000003123010111706345014277 0ustar daniel00000000000000/* This file is -*-C++-*- ------------------------------------------------------------------------------ MetaCam - Extract EXIF information from digital camera files, with support for Vendor specific blocks. Copyright (C) 2000 Daniel Stephens (daniel@cheeseplant.org) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ------------------------------------------------------------------------------ $Id: metatiff.h,v 1.3 2002/09/02 19:20:01 daniel Exp $ */ #ifndef METATIFF_H_INCLUDED #define METATIFF_H_INCLUDED #include #include #include using namespace std; /* Classes for access to meta-infomation from tiff files */ class _TIFFDataSource; class _IFD; class _IFDEntry; class TIFFDataSource; class IFD; class IFDEntry; typedef unsigned long tiffUNSIGNED; typedef signed long tiffSIGNED; const int tBYTE = 1; const int tASCII = 2; const int tSHORT = 3; const int tLONG = 4; const int tRATIONAL = 5; const int tSBYTE = 6; const int tUNDEFINED = 7; const int tSSHORT = 8; const int tSLONG = 9; const int tSRATIONAL = 10; const int tFLOAT = 11; const int tDOUBLE = 12; // Now have special types which are parsed versions of the above ones const int tReferencedIFD = -1; const int tDataIFD = -2; class tiffRATIONAL { private: tiffUNSIGNED num; tiffUNSIGNED den; public: tiffRATIONAL() : num(0), den(0) {}; tiffRATIONAL(tiffUNSIGNED n, tiffUNSIGNED d) : num(n), den(d) {}; bool operator == (const tiffRATIONAL &r) const { return ((num == r.num) && (den == r.den)); } bool operator != (const tiffRATIONAL &r) const { return ((num != r.num) || (den != r.den)); } tiffUNSIGNED getNumerator() const { return num; } tiffUNSIGNED getDenominator() const { return den; } operator double() const { double n(num); double d(den); return n/d; } tiffRATIONAL normalize() const; }; class tiffSRATIONAL { private: tiffSIGNED num; tiffSIGNED den; public: tiffSRATIONAL() : num(0), den(0) {}; tiffSRATIONAL(tiffSIGNED n, tiffSIGNED d) : num(n), den(d) {}; bool operator == (const tiffSRATIONAL &r) const { return ((num == r.num) && (den == r.den)); } bool operator != (const tiffSRATIONAL &r) const { return ((num != r.num) || (den != r.den)); } tiffSIGNED getNumerator() const { return num; } tiffSIGNED getDenominator() const { return den; } operator double() const { double n(num); double d(den); return n/d; } tiffSRATIONAL normalize() const; }; inline ostream &operator << (ostream &os, const tiffRATIONAL &r) { os << r.getNumerator() << "/" << r.getDenominator(); return os; } inline ostream &operator << (ostream &os, const tiffSRATIONAL &r) { os << r.getNumerator() << "/" << r.getDenominator(); return os; } class _ReferenceCounted { private: bool do_not_delete; // True if this cannot be re-created automatically int ref_count; public: _ReferenceCounted(bool dnd = false) : do_not_delete(dnd), ref_count(0) {}; virtual ~_ReferenceCounted(); // Reference counters void addRef() { ++ref_count; } void delRef() { --ref_count; if (ref_count == 0) { if (!do_not_delete) delete this; } } int getRefCount() const { return ref_count; } }; const int taFIRST_AVAILABLE = 10000; class _BaseAnnotation : public _ReferenceCounted { private: const int anno_type; static int next_avail_type; public: _BaseAnnotation(int t, bool dnd=false) : _ReferenceCounted(dnd), anno_type(t) {}; int getType() { return anno_type; } virtual void display(ostream &os); static int getAnnotationType(const char *use) { return ++next_avail_type; } }; // Front-end wrapper class for Annotation's class Annotation { private: _BaseAnnotation *anno; public: Annotation() : anno(0) {}; Annotation(_BaseAnnotation *i) : anno(i) { if (anno) anno->addRef(); } Annotation(const Annotation &oi) : anno(oi.anno) {if (anno) anno->addRef(); } _BaseAnnotation *getReal() const { return anno; } ~Annotation() { if (anno) anno->delRef(); anno = 0; } Annotation & operator = (const Annotation &oi) { if (oi.anno == anno) return *this; if (oi.anno) oi.anno->addRef(); if (anno) anno->delRef(); anno = oi.anno; return *this; } bool operator!() const { return anno == 0; } operator bool() const { return anno != 0; } bool operator==(const Annotation &i) const { return i.anno == anno; } bool operator!=(const Annotation &i) const { return i.anno != anno; } int getType() const { return anno ? anno->getType() : 0; } void display(ostream &os) const { if (anno) anno->display(os); } static int getAnnotationType(const char *use) { return _BaseAnnotation::getAnnotationType(use); } }; inline ostream &operator << (ostream &os, const Annotation &r) { r.display(os); return os; } /** Represents a view into a source of data from a TIFF file */ class _TIFFDataSource : public _ReferenceCounted { public: _TIFFDataSource(bool dnd=false) : _ReferenceCounted(dnd) {} virtual ~_TIFFDataSource(); virtual bool bigEndian() const = 0; virtual void seek(unsigned long ofs) = 0; virtual unsigned long tell() const = 0; virtual size_t getData(unsigned char *buf, size_t bytes) = 0; virtual unsigned char getUByte(); virtual unsigned short getUShort(); virtual unsigned long getULong(); virtual signed char getSByte(); virtual signed short getSShort(); virtual signed long getSLong(); virtual bool isGood() const = 0; virtual IFD getIFD(); virtual IFD getIFD(unsigned long ofs); }; // Front-end wrapper class for data sources class TIFFDataSource { private: _TIFFDataSource *src; public: TIFFDataSource() : src(0) {}; TIFFDataSource(_TIFFDataSource *i) : src(i) { if (src) src->addRef(); } TIFFDataSource(const TIFFDataSource &oi) : src(oi.src) {if (src) src->addRef(); } ~TIFFDataSource() { if (src) src->delRef(); src = 0; } TIFFDataSource & operator = (const TIFFDataSource &oi) { if (oi.src == src) return *this; if (oi.src) oi.src->addRef(); if (src) src->delRef(); src = oi.src; return *this; } bool operator!() const { return src == 0; } operator bool() const { return src != 0; } bool operator==(const TIFFDataSource &i) const { return i.src == src; } bool operator!=(const TIFFDataSource &i) const { return i.src != src; } bool bigEndian() const { return src->bigEndian(); }; void seek(unsigned long ofs) const { src->seek(ofs); }; unsigned long tell() const { return src->tell(); }; size_t getData(unsigned char *buf, size_t bytes) const { return src->getData(buf, bytes); }; unsigned char getUByte() const { return src->getUByte(); } unsigned short getUShort() const { return src->getUShort(); } unsigned long getULong() const { return src->getULong(); } signed char getSByte() const { return src->getSByte(); } signed short getSShort() const { return src->getSShort(); } signed long getSLong() const { return src->getSLong(); } bool isGood() const { return src ? src->isGood() : false; } IFD getIFD() const; IFD getIFD(unsigned long ofs) const; }; class _IFD : public _ReferenceCounted { public: _IFD(bool dnd=false) : _ReferenceCounted(dnd) {} virtual ~_IFD(); virtual bool isDynamic() const = 0; // Return true if this can be changed virtual IFDEntry operator[](int n) const = 0; virtual IFDEntry findEntry(unsigned long tag, _IFDEntry *after=0) const = 0; virtual unsigned short entries() const = 0; virtual IFD nextIFD() const = 0; }; class _IFDEntry: public _ReferenceCounted { friend class _IFD; private: unsigned long tag; unsigned short raw_type; int actual_type; public: _IFDEntry(unsigned long t, unsigned short raw, bool dnd=false) : _ReferenceCounted(dnd), tag(t), raw_type(raw), actual_type(raw) {} _IFDEntry(unsigned long t, unsigned short raw, int act, bool dnd=false) : _ReferenceCounted(dnd), tag(t), raw_type(raw), actual_type(act) {} virtual ~_IFDEntry(); static int typeLength(unsigned short); int length() const {return typeLength(raw_type) * values();} unsigned long getTag() const {return tag;} unsigned short getRawType() const {return raw_type;} int getType() const {return actual_type;} virtual unsigned long values() const = 0; virtual void outputValue(ostream &os) const = 0; virtual vector getUVALUE() const = 0; virtual vector getSVALUE() const = 0; virtual vector getRATIONAL() const = 0; virtual vector getSRATIONAL() const = 0; virtual vector getSTRING() const = 0; virtual vector getOPAQUE() const = 0; virtual TIFFDataSource getSource() const = 0; virtual unsigned long getSourceOffset() const = 0; }; // Front-end wrapper class for IFDEntries class IFDEntry { friend class IFD; private: _IFDEntry *entry; public: IFDEntry() : entry(0) {}; IFDEntry(_IFDEntry *i) : entry(i) { if (entry) entry->addRef(); } IFDEntry(const IFDEntry &oi) : entry(oi.entry) {if (entry) entry->addRef(); } ~IFDEntry() { if (entry) entry->delRef(); entry = 0; } IFDEntry & operator = (const IFDEntry &oi) { if (oi.entry == entry) return *this; if (oi.entry) oi.entry->addRef(); if (entry) entry->delRef(); entry = oi.entry; return *this; } _IFDEntry *getRealEntry() const { return entry; } bool operator!() const { return entry == 0; } operator bool() const { return entry != 0; } bool operator==(const IFDEntry &i) const { return i.entry == entry; } bool operator!=(const IFDEntry &i) const { return i.entry != entry; } int length() const { return entry ? entry->length() : 0; } unsigned long getTag() const { return entry ? entry->getTag() : 0; } unsigned short getRawType() const { return entry ? entry->getRawType() : 0 ;} int getType() const { return entry ? entry->getType() : 0 ; } unsigned long values() const { return entry ? entry->values() : 0;} void outputValue(ostream &os) const { entry->outputValue(os);} vector getUVALUE() const { return entry->getUVALUE(); } vector getSVALUE() const { return entry->getSVALUE(); } vector getRATIONAL() const { return entry->getRATIONAL(); } vector getSRATIONAL() const { return entry->getSRATIONAL(); } vector getSTRING() const { return entry->getSTRING(); } vector getOPAQUE() const { return entry->getOPAQUE(); } TIFFDataSource getSource() const { return entry->getSource(); } unsigned long getSourceOffset() const { return entry->getSourceOffset(); } }; // Front-end wrapper class for IFD's class IFD { private: _IFD *ifd; public: IFD() : ifd(0) {}; IFD(_IFD *i) : ifd(i) { if (ifd) ifd->addRef(); } IFD(const IFD &oi) : ifd(oi.ifd) {if (ifd) ifd->addRef(); } _IFD *getRealIFD() const { return ifd; } ~IFD() { if (ifd) ifd->delRef(); ifd = 0; } IFD & operator = (const IFD &oi) { if (oi.ifd == ifd) return *this; if (oi.ifd) oi.ifd->addRef(); if (ifd) ifd->delRef(); ifd = oi.ifd; return *this; } bool operator!() const { return ifd == 0; } operator bool() const { return ifd != 0; } bool operator==(const IFD &i) const { return i.ifd == ifd; } bool operator!=(const IFD &i) const { return i.ifd != ifd; } unsigned short entries() const { return ifd ? ifd->entries() : 0 ; } IFD nextIFD() const { return ifd ? IFD(ifd->nextIFD()) : IFD(); } bool isDynamic() { return ifd ? ifd->isDynamic() : false; } IFDEntry operator[](int n) const { return IFDEntry((*ifd)[n]); } IFDEntry findEntry(unsigned long tag) const { return IFDEntry(ifd->findEntry(tag)); } IFDEntry findEntry(unsigned long tag, IFDEntry &after) const { return IFDEntry(ifd->findEntry(tag, after.entry)); } IFD getEditable(); }; #endif /* METATIFF_H_INCLUDED */ metacam-1.2/nikontags.cc0000644000076500007650000000571310111706345014642 0ustar daniel00000000000000/* ------------------------------------------------------------------------------ MetaCam - Extract EXIF information from digital camera files, with support for Vendor specific blocks. Copyright (C) 2000 Daniel Stephens (daniel@cheeseplant.org) 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. ------------------------------------------------------------------------------ */ #include "dpyfuncs.h" static const char *rcsid __attribute__((unused))="$Id: nikontags.cc,v 1.5 2004/08/21 17:54:20 daniel Exp $"; // Nikon tags reverse engineered from a huge collection of well labeled images // on imaging-resource.com (Great Site BTW) // A number of additional tags provided by Jeremie Rostand knowntag nikon_known[] = { {0x0001, 7, 0, "Nikon Version Number", dpyExifVersion, 0}, {0x0002, 3, 0, "ISO Equivalent", dpyISO, 0}, {0x0003, 2, 0, "Color/BW", dpyString, 0}, {0x0004, 2, 0, "File Format", dpyString, 0}, {0x0005, 2, 0, "White Balance", dpyString, 0}, {0x0006, 2, 0, "Sharpening", dpyString, 0}, {0x0007, 2, 0, "Focus", dpyString, 0}, {0x0008, 2, 0, "Flash Mode", dpyString, 0}, {0x0009, 2, 0, "Flash Metering mode", dpyString, 0}, {0x000b, 8, 0, "White Balance Adjustment", dpySigned, 0}, // {0x000c, 5, 0, "??? White Point ???", 0, 0}, // {0x000e, 7, 0, "0x000e Unknown", dpyExifVersion}, {0x000f, 2, 0, "ISO Selection", dpyString, 0}, // {0x0010, 7, 0, "0x0010 Unknown", dpyExifVersion}, // {0x0011, 4, 0, "0x0011 Unsigned long", dpyPixels}, {0x0081, 2, 0, "Image Adjustment", dpyString, 0}, {0x0082, 2, 0, "Lens Adapter", dpyString, 0}, {0x0084, 5, 0, "Lens", dpyLens, 0}, {0x0085, 5, 0, "Manual Focus Distance", dpyRationalDistance, "m"}, {0x0086, 5, 0, "Digital Zoom", dpyZoomRatio, 0}, {0x0088, 7, 0, "Focus Position", dpyNikonFocusPosition, 0}, {0x0090, 2, 0, "Flash Type", dpyString, 0}, {0x0094, 8, 0, "Saturation", 0, 0}, {0x0095, 2, 0, "Noise Reduction", dpyString, 0}, // Added Nikkor Lens Info (Thanks to rr for providing details) {0x0098, 7, 0, "Nikkor Lens Info", dpyNikkorLensInfo, 0}, {0,0,0,0,0} }; metacam-1.2/ocontext.cc0000644000076500007650000001547110111706345014512 0ustar daniel00000000000000/* ------------------------------------------------------------------------------ MetaCam - Extract EXIF information from digital camera files, with support for Vendor specific blocks. Copyright (C) 2000 Daniel Stephens (daniel@cheeseplant.org) 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. ------------------------------------------------------------------------------ */ static const char *rcsid __attribute__((unused))="$Id: ocontext.cc,v 1.5 2004/08/21 17:23:24 daniel Exp $"; #include "odrivers.h" #include OutputContext::~OutputContext() { } OutputDriver::~OutputDriver() { } DisplayOutputContext::~DisplayOutputContext() { } ostream & DisplayOutputContext::startBlock(const char *hdr) { static const char *static_pad = " "; static const int padl = strlen(static_pad); if (in_block) endBlock(); int hlen = strlen(hdr); if (hlen < padl) { o_stream << &static_pad[hlen]; } o_stream << hdr << ": "; in_block = true; return o_stream; } ostream & DisplayOutputContext::startBlock(const string &hdr) { static const char *static_pad = " "; static const int padl = strlen(static_pad); if (in_block) endBlock(); int hlen = hdr.length(); if (hlen < padl) { o_stream << &static_pad[hlen]; } o_stream << hdr << ": "; in_block = true; return o_stream; } ostream & DisplayOutputContext::os() { if (!in_block) { cerr << "Attempted to access output stream outside of block!" << endl; in_block = true; } return o_stream; } void DisplayOutputContext::endBlock() { if (!in_block) return; os() << endl; in_block = false; } DisplayOutputDriver::~DisplayOutputDriver() { // Nothing } void DisplayOutputDriver::startFile(const char *fname) { os << "File: " << fname << endl; } OutputContext * DisplayOutputDriver::startGroup(const char *header) { static const char *DASH_LINE = "--------------------------------------------------"; static const int DASH_LEN = strlen(DASH_LINE); if (current_context) endGroup(); int hlen = strlen(header); os << " " << header; if (hlen < DASH_LEN) { os << " " << &DASH_LINE[hlen]; } os << endl; return new DisplayOutputContext(os); } OutputContext * DisplayOutputDriver::startGroup(const string &header) { static const char *DASH_LINE = "--------------------------------------------------"; static const int DASH_LEN = strlen(DASH_LINE); if (current_context) endGroup(); int hlen = header.length(); os << " " << header; if (hlen < DASH_LEN) { os << " " << &DASH_LINE[hlen]; } os << endl; return new DisplayOutputContext(os); } void DisplayOutputDriver::endGroup() { if (current_context) { current_context->endBlock(); delete current_context; current_context = 0; } } void DisplayOutputDriver::endFile() { endGroup(); os << endl; } void DisplayOutputDriver::close() { endFile(); } XMLOutputContext::~XMLOutputContext() { // Does nothing } ostream & XMLOutputContext::startBlock(const char *hdr) { if (in_block) endBlock(); driver.outputRaw(" str()); driver.outputLine("/>"); delete str; str = 0; in_block = false; } XMLOutputDriver::XMLOutputDriver(ostream &o) : os(o), current_context(0), is_open(true), in_file(false) { outputLine(""); outputLine(""); } XMLOutputDriver::~XMLOutputDriver() { if (is_open) close(); } void XMLOutputDriver::startFile(const char *fname) { if (in_file) endFile(); outputRaw(" "); in_file = true; } OutputContext * XMLOutputDriver::startGroup(const char *header) { if (current_context) endGroup(); outputRaw(" "); current_context = new XMLOutputContext(*this); return current_context; } OutputContext * XMLOutputDriver::startGroup(const string &header) { if (current_context) endGroup(); outputRaw(" "); current_context = new XMLOutputContext(*this); return current_context; } void XMLOutputDriver::endGroup() { if (current_context) { current_context->endBlock(); delete current_context; current_context = 0; outputLine(" "); } } void XMLOutputDriver::endFile() { if (in_file) { endGroup(); outputLine(" "); in_file = false; } } void XMLOutputDriver::close() { if (is_open) { endFile(); outputLine(""); is_open = false; } } static const char *HEXES = "0123456789ABCDEF"; void XMLOutputDriver::outputCooked(const string &buf) { outputCooked(buf.data()); } void XMLOutputDriver::outputCooked(const char *buf) { char tmphex[8]; int last_output = 0; int i; for (i=0; buf[i]; ++i) { char c= buf[i]; if (isalnum(c)) continue; const char *encode =0; if ((c < ' ') || (c > 126)) { tmphex[0] = '&'; tmphex[1] = '#'; tmphex[2] = HEXES[(c >> 4) & 15]; tmphex[3] = HEXES[c & 15]; tmphex[4] = 0; encode = tmphex; } else if (c == '&') { encode = "&"; } else if (c == '<') { encode = "<"; } else if (c == '>') { encode = ">"; } else if (c == '\"') { encode = """; } if (!encode) continue; if (last_output < i) { os.write(&buf[last_output], i); } os << encode; last_output = i+1; } if (last_output < i) { os.write(&buf[last_output], i); } } metacam-1.2/odrivers.h0000644000076500007650000000713410111706345014343 0ustar daniel00000000000000/* This file is -*-C++-*- ------------------------------------------------------------------------------ MetaCam - Extract EXIF information from digital camera files, with support for Vendor specific blocks. Copyright (C) 2000 Daniel Stephens (daniel@cheeseplant.org) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ------------------------------------------------------------------------------ $Id: odrivers.h,v 1.3 2004/08/21 17:23:24 daniel Exp $ */ #ifndef ODRIVERS_H_INCLUDED #define ODRIVERS_H_INCLUDED #include "metacam.h" #include class DisplayOutputContext : public OutputContext { private: ostream &o_stream; bool in_block; public: DisplayOutputContext(ostream &o) : o_stream(o), in_block(false) {}; virtual ~DisplayOutputContext(); virtual ostream &startBlock(const char *hdr); virtual ostream &startBlock(const string &hdr); virtual ostream &os(); virtual void endBlock(); }; class DisplayOutputDriver : public OutputDriver { private: ostream &os; OutputContext *current_context; public: DisplayOutputDriver(ostream &o) : os(o), current_context(0) {} virtual ~DisplayOutputDriver(); virtual void startFile(const char *fname); virtual OutputContext *startGroup(const char *header); virtual OutputContext *startGroup(const string &header); virtual void endGroup(); virtual void endFile(); virtual void close(); }; class XMLOutputDriver : public OutputDriver { private: ostream &os; OutputContext *current_context; bool is_open; bool in_file; public: XMLOutputDriver(ostream &o); virtual ~XMLOutputDriver(); virtual void startFile(const char *fname); virtual OutputContext *startGroup(const char *header); virtual OutputContext *startGroup(const string &header); virtual void endGroup(); virtual void endFile(); virtual void close(); void outputRaw(const char *buf ) {os << buf; } void outputCooked(const char *); void outputLine(const char *buf) { os << buf << endl; } void outputAttribute(const char *name, const char *value) { os << " " << name << "=\""; outputCooked(value); os << "\""; } void outputRaw(const string &buf ) {os << buf; } void outputCooked(const string &); void outputLine(const string &buf) { os << buf << endl; } void outputAttribute(const string &name, const string &value) { os << " " << name << "=\""; outputCooked(value); os << "\""; } void outputAttribute(const char *name, const string &value) { os << " " << name << "=\""; outputCooked(value); os << "\""; } }; class XMLOutputContext : public OutputContext { private: XMLOutputDriver &driver; ostringstream *str; bool in_block; public: XMLOutputContext(XMLOutputDriver &drv) : driver(drv), in_block(false) {}; virtual ~XMLOutputContext(); virtual ostream &startBlock(const char *hdr); virtual ostream &startBlock(const string &hdr); virtual ostream &os(); virtual void endBlock(); }; #endif /* ODRIVERS_H_INCLUDED */ metacam-1.2/olympustags.cc0000644000076500007650000000342110111706345015226 0ustar daniel00000000000000/* ------------------------------------------------------------------------------ MetaCam - Extract EXIF information from digital camera files, with support for Vendor specific blocks. Copyright (C) 2000 Daniel Stephens (daniel@cheeseplant.org) 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. ------------------------------------------------------------------------------ */ #include "dpyfuncs.h" static const char *rcsid __attribute__((unused))="$Id: olympustags.cc,v 1.5 2002/09/02 19:20:01 daniel Exp $"; // Initial olympus tag references from // http://www.butaman.ne.jp/~tsuruzoh/Computer/Digicams/exif-e.html knowntag olympus_known[] = { {0x0200, tLONG, 0, "Special Mode", dpyOlymSpecialMode, 0}, {0x0201, tSHORT, 0, "JPEG Quality", dpyUnsignedLookup, lookOlymJPEGQuality}, {0x0202, tSHORT, 0, "Macro", dpyUnsignedLookup, lookYesNo}, {0x0204, tRATIONAL, 0, "Digital Zoom", dpyOlymZoom, 0}, {0x0207, tASCII, 0, "Firmware Version", dpyString, 0}, {0x0208, tASCII, 1, "Picture Info", dpyString, 0}, {0x0209, tUNDEFINED, 0, "Camera ID", dpyExifVersion, 0}, {0,0,0,0} }; metacam-1.2/rationals.cc0000644000076500007650000000345010111706345014635 0ustar daniel00000000000000/* ------------------------------------------------------------------------------ MetaCam - Extract EXIF information from digital camera files, with support for Vendor specific blocks. Copyright (C) 2000 Daniel Stephens (daniel@cheeseplant.org) 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. ------------------------------------------------------------------------------ */ #include #include "metatiff.h" static const char *rcsid __attribute__((unused))="$Id: rationals.cc,v 1.4 2002/09/02 19:20:01 daniel Exp $"; static unsigned long Euclid(unsigned long a, unsigned long b) { if (b > a) return Euclid(b, a); if (b==0) return a; return Euclid(b, a % b); } tiffRATIONAL tiffRATIONAL::normalize() const { if ((num == 0) || (den == 0)) return *this; unsigned long d = Euclid(num, den); return tiffRATIONAL(num/d, den/d); } tiffSRATIONAL tiffSRATIONAL::normalize() const { if ((num==0) || (den==0)) return *this; long d; if ((num < 0) && (den<0)) { d = Euclid(-num,-den); } else if (num<0) { d = Euclid(-num,den); } else if (den<0) { d = Euclid(num,-den); } else{ d = Euclid(num,den); } return tiffSRATIONAL(num/d, den/d); } metacam-1.2/tiffdata.cc0000644000076500007650000000457310111706345014432 0ustar daniel00000000000000/* ------------------------------------------------------------------------------ MetaCam - Extract EXIF information from digital camera files, with support for Vendor specific blocks. Copyright (C) 2000 Daniel Stephens (daniel@cheeseplant.org) 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. ------------------------------------------------------------------------------ */ #include #include #include #include #include "metatiff.h" #include "datatiff.h" static const char *rcsid __attribute__((unused))="$Id: tiffdata.cc,v 1.2 2002/09/02 19:20:01 daniel Exp $"; unsigned char _TIFFDataSource::getUByte() { unsigned char b; if (getData((unsigned char *)&b, 1) != 1) return 0; return b; } unsigned short _TIFFDataSource::getUShort() { unsigned short s; if (getData((unsigned char *)&s, 2) != 2) return 0; if (bigEndian()) {return ntohs(s);} return s; } unsigned long _TIFFDataSource::getULong() { unsigned long l; if (getData((unsigned char *)&l, 4) != 4) return 0; if (bigEndian()) {return ntohl(l);} return l; } signed char _TIFFDataSource::getSByte() { signed char b; if (getData((unsigned char *)&b, 1) != 1) return 0; return b; } signed short _TIFFDataSource::getSShort() { signed short s; if (getData((unsigned char *)&s, 2) != 2) return 0; if (bigEndian()) {return ntohs(s);} return s; } signed long _TIFFDataSource::getSLong() { signed long l; if (getData((unsigned char *)&l, 4) != 4) return 0; if (bigEndian()) {return ntohl(l);} return l; } IFD _TIFFDataSource::getIFD() { return IFD(new _DataIFD(TIFFDataSource(this), 0)); } IFD _TIFFDataSource::getIFD(unsigned long ofs) { return IFD(new _DataIFD(TIFFDataSource(this), ofs)); }