comparison src/exiv2.cc @ 1426:cd88fe4e5588

handle sidecar files for raw formats that are not known to exiv2
author nadvornik
date Fri, 13 Mar 2009 10:36:32 +0000
parents 91bed0d66cf2
children e37cde2857c1
comparison
equal deleted inserted replaced
1425:80462be81410 1426:cd88fe4e5588
127 Exiv2::Image::AutoPtr image_; 127 Exiv2::Image::AutoPtr image_;
128 128
129 /* the icc profile in jpeg is not technically exif - store it here */ 129 /* the icc profile in jpeg is not technically exif - store it here */
130 unsigned char *cp_data_; 130 unsigned char *cp_data_;
131 guint cp_length_; 131 guint cp_length_;
132 gboolean valid_;
133
134 Exiv2::ExifData emptyExifData_;
135 Exiv2::IptcData emptyIptcData_;
136 #if EXIV2_TEST_VERSION(0,16,0)
137 Exiv2::XmpData emptyXmpData_;
138 #endif
132 139
133 public: 140 public:
134 _ExifDataOriginal(Exiv2::Image::AutoPtr image) 141 _ExifDataOriginal(Exiv2::Image::AutoPtr image)
135 { 142 {
136 cp_data_ = NULL; 143 cp_data_ = NULL;
137 cp_length_ = 0; 144 cp_length_ = 0;
138 image_ = image; 145 image_ = image;
146 valid_ = TRUE;
139 } 147 }
140 148
141 _ExifDataOriginal(gchar *path) 149 _ExifDataOriginal(gchar *path)
142 { 150 {
143 cp_data_ = NULL; 151 cp_data_ = NULL;
144 cp_length_ = 0; 152 cp_length_ = 0;
153 valid_ = TRUE;
154
145 gchar *pathl = path_from_utf8(path); 155 gchar *pathl = path_from_utf8(path);
146 image_ = Exiv2::ImageFactory::open(pathl); 156 try
157 {
158 image_ = Exiv2::ImageFactory::open(pathl);
159 // g_assert (image.get() != 0);
160 image_->readMetadata();
161
162 #if EXIV2_TEST_VERSION(0,16,0)
163 if (image_->mimeType() == "application/rdf+xml")
164 {
165 //Exiv2 sidecar converts xmp to exif and iptc, we don't want it.
166 image_->clearExifData();
167 image_->clearIptcData();
168 }
169 #endif
170
171 #if EXIV2_TEST_VERSION(0,14,0)
172 if (image_->mimeType() == "image/jpeg")
173 {
174 /* try to get jpeg color profile */
175 Exiv2::BasicIo &io = image_->io();
176 gint open = io.isopen();
177 if (!open) io.open();
178 if (io.isopen())
179 {
180 unsigned char *mapped = (unsigned char*)io.mmap();
181 if (mapped) exif_jpeg_parse_color(this, mapped, io.size());
182 io.munmap();
183 }
184 if (!open) io.close();
185 }
186 #endif
187 }
188 catch (Exiv2::AnyError& e)
189 {
190 valid_ = FALSE;
191 }
147 g_free(pathl); 192 g_free(pathl);
148 // g_assert (image.get() != 0);
149 image_->readMetadata();
150
151 #if EXIV2_TEST_VERSION(0,16,0)
152 if (image_->mimeType() == "application/rdf+xml")
153 {
154 //Exiv2 sidecar converts xmp to exif and iptc, we don't want it.
155 image_->clearExifData();
156 image_->clearIptcData();
157 }
158 #endif
159
160 #if EXIV2_TEST_VERSION(0,14,0)
161 if (image_->mimeType() == "image/jpeg")
162 {
163 /* try to get jpeg color profile */
164 Exiv2::BasicIo &io = image_->io();
165 gint open = io.isopen();
166 if (!open) io.open();
167 if (io.isopen())
168 {
169 unsigned char *mapped = (unsigned char*)io.mmap();
170 if (mapped) exif_jpeg_parse_color(this, mapped, io.size());
171 io.munmap();
172 }
173 if (!open) io.close();
174 }
175 #endif
176 } 193 }
177 194
178 virtual ~_ExifDataOriginal() 195 virtual ~_ExifDataOriginal()
179 { 196 {
180 if (cp_data_) g_free(cp_data_); 197 if (cp_data_) g_free(cp_data_);
181 } 198 }
182 199
183 virtual Exiv2::Image *image() 200 virtual Exiv2::Image *image()
184 { 201 {
202 if (!valid_) return NULL;
185 return image_.get(); 203 return image_.get();
186 } 204 }
187 205
188 virtual Exiv2::ExifData &exifData () 206 virtual Exiv2::ExifData &exifData ()
189 { 207 {
208 if (!valid_) return emptyExifData_;
190 return image_->exifData(); 209 return image_->exifData();
191 } 210 }
192 211
193 virtual Exiv2::IptcData &iptcData () 212 virtual Exiv2::IptcData &iptcData ()
194 { 213 {
214 if (!valid_) return emptyIptcData_;
195 return image_->iptcData(); 215 return image_->iptcData();
196 } 216 }
197 217
198 #if EXIV2_TEST_VERSION(0,16,0) 218 #if EXIV2_TEST_VERSION(0,16,0)
199 virtual Exiv2::XmpData &xmpData () 219 virtual Exiv2::XmpData &xmpData ()
200 { 220 {
221 if (!valid_) return emptyXmpData_;
201 return image_->xmpData(); 222 return image_->xmpData();
202 } 223 }
203 #endif 224 #endif
204 225
205 virtual void add_jpeg_color_profile(unsigned char *cp_data, guint cp_length) 226 virtual void add_jpeg_color_profile(unsigned char *cp_data, guint cp_length)
286 else 307 else
287 iptcData_.clear(); 308 iptcData_.clear();
288 309
289 copyXmpToExif(xmpData_, exifData_); 310 copyXmpToExif(xmpData_, exifData_);
290 #endif 311 #endif
291 imageData_->image()->setExifData(exifData_); 312 Exiv2::Image *image = imageData_->image();
292 imageData_->image()->setIptcData(iptcData_); 313
293 #if EXIV2_TEST_VERSION(0,16,0) 314 if (!image) Exiv2::Error(21);
294 imageData_->image()->setXmpData(xmpData_); 315 image->setExifData(exifData_);
295 #endif 316 image->setIptcData(iptcData_);
296 imageData_->image()->writeMetadata(); 317 #if EXIV2_TEST_VERSION(0,16,0)
318 image->setXmpData(xmpData_);
319 #endif
320 image->writeMetadata();
297 } 321 }
298 else 322 else
299 { 323 {
300 #if EXIV2_TEST_VERSION(0,17,0) 324 #if EXIV2_TEST_VERSION(0,17,0)
301 gchar *pathl = path_from_utf8(path);; 325 gchar *pathl = path_from_utf8(path);;
1050 1074
1051 guchar *exif_get_preview(ExifData *exif, guint *data_len, gint requested_width, gint requested_height) 1075 guchar *exif_get_preview(ExifData *exif, guint *data_len, gint requested_width, gint requested_height)
1052 { 1076 {
1053 if (!exif) return NULL; 1077 if (!exif) return NULL;
1054 1078
1079 if (!exif->image()) return NULL;
1080
1055 const char* path = exif->image()->io().path().c_str(); 1081 const char* path = exif->image()->io().path().c_str();
1056 /* given image pathname, first do simple (and fast) file extension test */ 1082 /* given image pathname, first do simple (and fast) file extension test */
1057 gboolean is_raw = filter_file_class(path, FORMAT_CLASS_RAWIMAGE); 1083 gboolean is_raw = filter_file_class(path, FORMAT_CLASS_RAWIMAGE);
1058 1084
1059 if (!is_raw && requested_width == 0) return NULL; 1085 if (!is_raw && requested_width == 0) return NULL;
1150 extern "C" guchar *exif_get_preview(ExifData *exif, guint *data_len, gint requested_width, gint requested_height) 1176 extern "C" guchar *exif_get_preview(ExifData *exif, guint *data_len, gint requested_width, gint requested_height)
1151 { 1177 {
1152 unsigned long offset; 1178 unsigned long offset;
1153 1179
1154 if (!exif) return NULL; 1180 if (!exif) return NULL;
1181 if (!exif->image()) return NULL;
1182
1155 const char* path = exif->image()->io().path().c_str(); 1183 const char* path = exif->image()->io().path().c_str();
1156 1184
1157 /* given image pathname, first do simple (and fast) file extension test */ 1185 /* given image pathname, first do simple (and fast) file extension test */
1158 if (!filter_file_class(path, FORMAT_CLASS_RAWIMAGE)) return NULL; 1186 if (!filter_file_class(path, FORMAT_CLASS_RAWIMAGE)) return NULL;
1159 1187