filters

kis_exif_io.cpp
1/*
2 * Copyright (c) 2006 Cyrille Berger <cberger@cberger.net>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20#include "kis_exif_io.h"
21
22#include <kdebug.h>
23
24extern "C" {
25#include <libexif/exif-tag.h>
26#include <libexif/exif-log.h>
27}
28
29KisExifIO::KisExifIO(KisExifInfo* ei) : m_exifInfo(ei)
30{
31}
32
33void KisExifIO::readExifFromFile( const char* fileName)
34{
35 readExifData( exif_data_new_from_file(fileName) );
36}
37
38void KisExifIO::readExifFromMem( const unsigned char* data , unsigned int size)
39{
40 readExifData( exif_data_new_from_data(data, size) );
41}
42
43void KisExifIO::saveExifToMem( unsigned char** data, unsigned int *size)
44{
45 ExifData* exifData = exif_data_new();
46 writeExifData( exifData );
47 exif_data_save_data( exifData, data, size);
48}
49
50ExifValue::ExifType KisExifIO::format2type(ExifFormat format)
51{
52 switch(format)
53 {
54 case EXIF_FORMAT_BYTE:
55 return ExifValue::EXIF_TYPE_BYTE;
56 case EXIF_FORMAT_ASCII:
57 return ExifValue::EXIF_TYPE_ASCII;
58 case EXIF_FORMAT_SHORT:
59 return ExifValue::EXIF_TYPE_SHORT;
60 case EXIF_FORMAT_LONG:
61 return ExifValue::EXIF_TYPE_LONG;
62 case EXIF_FORMAT_RATIONAL:
63 return ExifValue::EXIF_TYPE_RATIONAL;
64 case EXIF_FORMAT_SBYTE:
65 return ExifValue::EXIF_TYPE_SBYTE;
66 case EXIF_FORMAT_SSHORT:
67 return ExifValue::EXIF_TYPE_SSHORT;
68 case EXIF_FORMAT_SLONG:
69 return ExifValue::EXIF_TYPE_SLONG;
70 case EXIF_FORMAT_SRATIONAL:
71 return ExifValue::EXIF_TYPE_SRATIONAL;
72 case EXIF_FORMAT_FLOAT:
73 return ExifValue::EXIF_TYPE_FLOAT;
74 case EXIF_FORMAT_DOUBLE:
75 return ExifValue::EXIF_TYPE_DOUBLE;
76 default:
77 case EXIF_FORMAT_UNDEFINED:
78 return ExifValue::EXIF_TYPE_UNDEFINED;
79 }
80}
81
82void KisExifIO::readExifData( ExifData* exifData)
83{
84 ExifValue::ByteOrder bO;
85 if(exif_data_get_byte_order( exifData) == EXIF_BYTE_ORDER_MOTOROLA)
86 {
87 bO = ExifValue::BYTE_ORDER_MOTOROLA;
88 } else {
89 bO = ExifValue::BYTE_ORDER_INTEL;
90 }
91 static ExifIfd ifds[5] = {
92 EXIF_IFD_0,
93 EXIF_IFD_1,
94 EXIF_IFD_EXIF,
95 EXIF_IFD_INTEROPERABILITY,
96 EXIF_IFD_GPS
97 };
98 for(int ifd = 0; ifd < 5; ifd ++)
99 {
100 ExifContent* content = exifData->ifd[ifds[ifd]];
101 kdDebug() << "There are " << content->count << " values in ifd=" << ifd << endl;
102 for (uint i = 0; i < content->count; i++)
103 {
104 ExifEntry* entry = content->entries[i];
105 TQString tagname = exif_tag_get_name ( entry->tag );
106// kdDebug() << "found tag : " << tagname << endl;
107 // 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)
108 ExifValue value( format2type(entry->format), entry->data, entry->size, ifds[ifd], entry->components, bO );
109// exif_entry_dump( entry, 4);
110// kdDebug() << "value = " << value.toString() << endl;
111 m_exifInfo->setValue( tagname, value);
112 }
113 }
114
115}
116
117ExifFormat KisExifIO::type2format( ExifValue::ExifType type)
118{
119 switch(type)
120 {
121 case ExifValue::EXIF_TYPE_BYTE:
122 return EXIF_FORMAT_BYTE;
123 case ExifValue::EXIF_TYPE_ASCII:
124 return EXIF_FORMAT_ASCII;
125 case ExifValue::EXIF_TYPE_SHORT:
126 return EXIF_FORMAT_SHORT;
127 case ExifValue::EXIF_TYPE_LONG:
128 return EXIF_FORMAT_LONG;
129 case ExifValue::EXIF_TYPE_RATIONAL:
130 return EXIF_FORMAT_RATIONAL;
131 case ExifValue::EXIF_TYPE_SBYTE:
132 return EXIF_FORMAT_SBYTE;
133 case ExifValue::EXIF_TYPE_SSHORT:
134 return EXIF_FORMAT_SSHORT;
135 case ExifValue::EXIF_TYPE_SLONG:
136 return EXIF_FORMAT_SLONG;
137 case ExifValue::EXIF_TYPE_SRATIONAL:
138 return EXIF_FORMAT_SRATIONAL;
139 case ExifValue::EXIF_TYPE_FLOAT:
140 return EXIF_FORMAT_FLOAT;
141 case ExifValue::EXIF_TYPE_DOUBLE:
142 return EXIF_FORMAT_DOUBLE;
143 default:
144 case ExifValue::EXIF_TYPE_UNDEFINED:
145 return EXIF_FORMAT_UNDEFINED;
146 }
147}
148
149
150void KisExifIO::writeExifData( ExifData* exifData)
151{
152 ExifValue::ByteOrder bO;
153 if(exif_data_get_byte_order( exifData) == EXIF_BYTE_ORDER_MOTOROLA)
154 {
155 bO = ExifValue::BYTE_ORDER_MOTOROLA;
156 } else {
157 bO = ExifValue::BYTE_ORDER_INTEL;
158 }
159
160 for( KisExifInfo::evMap::const_iterator it = m_exifInfo->begin(); it != m_exifInfo->end(); ++it)
161 {
162 ExifValue ev = it.data();
163 if(ev.ifd() != -1)
164 {
165 ExifEntry * entry = exif_entry_new();
166 ExifContent* content = exifData->ifd[ev.ifd()];
167 exif_content_add_entry(content, entry);
168 kdDebug() << "Saving tag:" << it.key() << " " << ev.toString() << endl;
169 ExifTag tag = exif_tag_from_name( it.key().ascii());
170 entry->components = ev.components();
171 entry->format = type2format( ev.type());
172 entry->tag = tag;
173// exif_entry_dump(entry, 2);
174 ev.convertToData(&entry->data, &entry->size, bO);
175 }
176 }
177}