/* * Copyright (c) 2006 Cyrille Berger * * 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., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "kis_exif_io.h" #include extern "C" { #include #include } KisExifIO::KisExifIO(KisExifInfo* ei) : m_exifInfo(ei) { } void KisExifIO::readExifFromFile( const char* fileName) { readExifData( exif_data_new_from_file(fileName) ); } void KisExifIO::readExifFromMem( const unsigned char* data , unsigned int size) { readExifData( exif_data_new_from_data(data, size) ); } void KisExifIO::saveExifToMem( unsigned char** data, unsigned int *size) { ExifData* exifData = exif_data_new(); writeExifData( exifData ); exif_data_save_data( exifData, data, size); } ExifValue::ExifType KisExifIO::format2type(ExifFormat format) { switch(format) { case EXIF_FORMAT_BYTE: return ExifValue::EXIF_TYPE_BYTE; case EXIF_FORMAT_ASCII: return ExifValue::EXIF_TYPE_ASCII; case EXIF_FORMAT_SHORT: return ExifValue::EXIF_TYPE_SHORT; case EXIF_FORMAT_LONG: return ExifValue::EXIF_TYPE_LONG; case EXIF_FORMAT_RATIONAL: return ExifValue::EXIF_TYPE_RATIONAL; case EXIF_FORMAT_SBYTE: return ExifValue::EXIF_TYPE_SBYTE; case EXIF_FORMAT_SSHORT: return ExifValue::EXIF_TYPE_SSHORT; case EXIF_FORMAT_SLONG: return ExifValue::EXIF_TYPE_SLONG; case EXIF_FORMAT_SRATIONAL: return ExifValue::EXIF_TYPE_SRATIONAL; case EXIF_FORMAT_FLOAT: return ExifValue::EXIF_TYPE_FLOAT; case EXIF_FORMAT_DOUBLE: return ExifValue::EXIF_TYPE_DOUBLE; default: case EXIF_FORMAT_UNDEFINED: return ExifValue::EXIF_TYPE_UNDEFINED; } } void KisExifIO::readExifData( ExifData* exifData) { ExifValue::ByteOrder bO; if(exif_data_get_byte_order( exifData) == EXIF_BYTE_ORDER_MOTOROLA) { bO = ExifValue::BYTE_ORDER_MOTOROLA; } else { bO = ExifValue::BYTE_ORDER_INTEL; } static ExifIfd ifds[5] = { EXIF_IFD_0, EXIF_IFD_1, EXIF_IFD_EXIF, EXIF_IFD_INTEROPERABILITY, EXIF_IFD_GPS }; for(int ifd = 0; ifd < 5; ifd ++) { ExifContent* content = exifData->ifd[ifds[ifd]]; kdDebug() << "There are " << content->count << " values in ifd=" << ifd << endl; for (uint i = 0; i < content->count; i++) { ExifEntry* entry = content->entries[i]; TQString tagname = exif_tag_get_name ( entry->tag ); // kdDebug() << "found tag : " << tagname << endl; // TQString tagname = exif_tag_get_name_in_ifd ( entry->tag, EXIF_IFD_0 ); TODO: would be better to rely on 0.6.13 when it becomes more common, as it supports better other IFD (GPS and interoperrabilibity) ExifValue value( format2type(entry->format), entry->data, entry->size, ifds[ifd], entry->components, bO ); // exif_entry_dump( entry, 4); // kdDebug() << "value = " << value.toString() << endl; m_exifInfo->setValue( tagname, value); } } } ExifFormat KisExifIO::type2format( ExifValue::ExifType type) { switch(type) { case ExifValue::EXIF_TYPE_BYTE: return EXIF_FORMAT_BYTE; case ExifValue::EXIF_TYPE_ASCII: return EXIF_FORMAT_ASCII; case ExifValue::EXIF_TYPE_SHORT: return EXIF_FORMAT_SHORT; case ExifValue::EXIF_TYPE_LONG: return EXIF_FORMAT_LONG; case ExifValue::EXIF_TYPE_RATIONAL: return EXIF_FORMAT_RATIONAL; case ExifValue::EXIF_TYPE_SBYTE: return EXIF_FORMAT_SBYTE; case ExifValue::EXIF_TYPE_SSHORT: return EXIF_FORMAT_SSHORT; case ExifValue::EXIF_TYPE_SLONG: return EXIF_FORMAT_SLONG; case ExifValue::EXIF_TYPE_SRATIONAL: return EXIF_FORMAT_SRATIONAL; case ExifValue::EXIF_TYPE_FLOAT: return EXIF_FORMAT_FLOAT; case ExifValue::EXIF_TYPE_DOUBLE: return EXIF_FORMAT_DOUBLE; default: case ExifValue::EXIF_TYPE_UNDEFINED: return EXIF_FORMAT_UNDEFINED; } } void KisExifIO::writeExifData( ExifData* exifData) { ExifValue::ByteOrder bO; if(exif_data_get_byte_order( exifData) == EXIF_BYTE_ORDER_MOTOROLA) { bO = ExifValue::BYTE_ORDER_MOTOROLA; } else { bO = ExifValue::BYTE_ORDER_INTEL; } for( KisExifInfo::evMap::const_iterator it = m_exifInfo->begin(); it != m_exifInfo->end(); ++it) { ExifValue ev = it.data(); if(ev.ifd() != -1) { ExifEntry * entry = exif_entry_new(); ExifContent* content = exifData->ifd[ev.ifd()]; exif_content_add_entry(content, entry); kdDebug() << "Saving tag:" << it.key() << " " << ev.toString() << endl; ExifTag tag = exif_tag_from_name( it.key().ascii()); entry->components = ev.components(); entry->format = type2format( ev.type()); entry->tag = tag; // exif_entry_dump(entry, 2); ev.convertToData(&entry->data, &entry->size, bO); } } }