1 // ***************************************************************** -*- C++ -*- 2 /* 3 * Copyright (C) 2004-2021 Exiv2 authors 4 * This program is part of the Exiv2 distribution. 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * as published by the Free Software Foundation; either version 2 9 * of the License, or (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA. 19 */ 20 // ***************************************************************************** 21 // included header files 22 #include "config.h" 23 24 #include "rafimage.hpp" 25 #include "tiffimage.hpp" 26 #include "image_int.hpp" 27 #include "image.hpp" 28 #include "basicio.hpp" 29 #include "error.hpp" 30 #include "futils.hpp" 31 #include "enforce.hpp" 32 #include "safe_op.hpp" 33 34 // +standard includes 35 #include <string> 36 #include <cstring> 37 #include <iostream> 38 #include <cassert> 39 40 // ***************************************************************************** 41 // class member definitions 42 namespace Exiv2 { 43 RafImage(BasicIo::AutoPtr io,bool)44 RafImage::RafImage(BasicIo::AutoPtr io, bool /*create*/) 45 : Image(ImageType::raf, mdExif | mdIptc | mdXmp, io) 46 { 47 } // RafImage::RafImage 48 mimeType() const49 std::string RafImage::mimeType() const 50 { 51 return "image/x-fuji-raf"; 52 } 53 pixelWidth() const54 int RafImage::pixelWidth() const 55 { 56 Exiv2::ExifData::const_iterator widthIter = exifData_.findKey(Exiv2::ExifKey("Exif.Photo.PixelXDimension")); 57 if (widthIter != exifData_.end() && widthIter->count() > 0) { 58 return widthIter->toLong(); 59 } 60 return 0; 61 } 62 pixelHeight() const63 int RafImage::pixelHeight() const 64 { 65 Exiv2::ExifData::const_iterator heightIter = exifData_.findKey(Exiv2::ExifKey("Exif.Photo.PixelYDimension")); 66 if (heightIter != exifData_.end() && heightIter->count() > 0) { 67 return heightIter->toLong(); 68 } 69 return 0; 70 } 71 setExifData(const ExifData &)72 void RafImage::setExifData(const ExifData& /*exifData*/) 73 { 74 // Todo: implement me! 75 throw(Error(kerInvalidSettingForImage, "Exif metadata", "RAF")); 76 } 77 setIptcData(const IptcData &)78 void RafImage::setIptcData(const IptcData& /*iptcData*/) 79 { 80 // Todo: implement me! 81 throw(Error(kerInvalidSettingForImage, "IPTC metadata", "RAF")); 82 } 83 setComment(const std::string &)84 void RafImage::setComment(const std::string& /*comment*/) 85 { 86 // not supported 87 throw(Error(kerInvalidSettingForImage, "Image comment", "RAF")); 88 } 89 printStructure(std::ostream & out,PrintStructureOption option,int depth)90 void RafImage::printStructure(std::ostream& out, PrintStructureOption option, int depth) { 91 if (io_->open() != 0) { 92 throw Error(kerDataSourceOpenFailed, io_->path(), strError()); 93 } 94 // Ensure this is the correct image type 95 if (!isRafType(*io_, true)) { 96 if (io_->error() || io_->eof()) throw Error(kerFailedToReadImageData); 97 throw Error(kerNotAnImage, "RAF"); 98 } 99 size_t address = 0 ; 100 size_t address2 = 0 ; 101 const bool bPrint = option==kpsBasic || option==kpsRecursive; 102 if ( bPrint ) { 103 io_->seek(0,BasicIo::beg); // rewind 104 address = io_->tell(); 105 const char* format = " %8d | %8d | "; 106 107 { 108 out << Internal::indent(depth) 109 << "STRUCTURE OF RAF FILE: " 110 << io().path() 111 << std::endl; 112 out << Internal::indent(depth) 113 << Internal::stringFormat(" Address | Length | Payload") 114 << std::endl; 115 } 116 117 byte magicdata [17]; 118 io_->read(magicdata, 16); 119 magicdata[16] = 0; 120 { 121 out << Internal::indent(depth) 122 << Internal::stringFormat(format,address, 16, 0) 123 << " magic : " 124 << (char*) magicdata 125 << std::endl; 126 } 127 128 address = io_->tell(); 129 byte data1 [5]; 130 io_->read(data1, 4); 131 data1[4] = 0; 132 { 133 out << Internal::indent(depth) 134 << Internal::stringFormat(format,address, 4, 16) 135 << " data1 : " 136 << std::string((char*)&data1) 137 << std::endl; 138 } 139 140 address = io_->tell(); 141 byte data2 [9]; 142 io_->read(data2, 8); 143 data2[8] = 0; 144 { 145 out << Internal::indent(depth) 146 << Internal::stringFormat(format,address, 8, 20) 147 << " data2 : " 148 << std::string((char*)&data2) 149 << std::endl; 150 } 151 152 address = io_->tell(); 153 byte camdata [33]; 154 io_->read(camdata, 32); 155 camdata[32] = 0; 156 { 157 out << Internal::indent(depth) 158 << Internal::stringFormat(format,address, 32, 28) 159 << " camera : " 160 << std::string((char*)&camdata) 161 << std::endl; 162 } 163 164 address = io_->tell(); 165 byte dir_version [5]; 166 io_->read(dir_version, 4); 167 dir_version[4] = 0; 168 { 169 out << Internal::indent(depth) 170 << Internal::stringFormat(format,address, 4, 60) 171 << " version : " 172 << std::string((char*)&dir_version) 173 << std::endl; 174 } 175 176 address = io_->tell(); 177 DataBuf unknown(20); 178 io_->read(unknown.pData_,unknown.size_); 179 { 180 out << Internal::indent(depth) 181 << Internal::stringFormat(format,address, 20) 182 << " unknown : " 183 << Internal::binaryToString(makeSlice(unknown, 0,unknown.size_)) 184 << std::endl; 185 } 186 187 188 address = io_->tell(); 189 byte jpg_img_offset [4]; 190 io_->read(jpg_img_offset, 4); 191 byte jpg_img_length [4]; 192 address2 = io_->tell(); 193 io_->read(jpg_img_length, 4); 194 195 long jpg_img_off = Exiv2::getULong((const byte *) jpg_img_offset, bigEndian); 196 long jpg_img_len = Exiv2::getULong((const byte *) jpg_img_length, bigEndian); 197 std::stringstream j_off; 198 std::stringstream j_len; 199 j_off << jpg_img_off; 200 j_len << jpg_img_len; 201 { 202 out << Internal::indent(depth) 203 << Internal::stringFormat(format,address, 4) 204 << "JPEG Offset : " 205 << j_off.str() 206 << std::endl; 207 out << Internal::indent(depth) 208 << Internal::stringFormat(format,address2, 4) 209 << "JPEG Length : " 210 << j_len.str() 211 << std::endl; 212 } 213 214 address = io_->tell(); 215 byte cfa_header_offset [4]; 216 io_->read(cfa_header_offset, 4); 217 byte cfa_header_length [4]; 218 address2 = io_->tell(); 219 io_->read(cfa_header_length, 4); 220 long cfa_hdr_off = Exiv2::getULong((const byte *) cfa_header_offset, bigEndian); 221 long cfa_hdr_len = Exiv2::getULong((const byte *) cfa_header_length, bigEndian); 222 std::stringstream ch_off; 223 std::stringstream ch_len; 224 ch_off << cfa_hdr_off; 225 ch_len << cfa_hdr_len; 226 { 227 out << Internal::indent(depth) 228 << Internal::stringFormat(format,address, 4) 229 << " CFA Offset : " 230 << ch_off.str() 231 << std::endl; 232 out << Internal::indent(depth) 233 << Internal::stringFormat(format,address2, 4) 234 << " CFA Length : " 235 << ch_len.str() 236 << std::endl; 237 } 238 239 byte cfa_offset [4]; 240 address = io_->tell(); 241 io_->read(cfa_offset, 4); 242 byte cfa_length [4]; 243 address2 = io_->tell(); 244 io_->read(cfa_length, 4); 245 long cfa_off = Exiv2::getULong((const byte *) cfa_offset, bigEndian); 246 long cfa_len = Exiv2::getULong((const byte *) cfa_length, bigEndian); 247 std::stringstream c_off; 248 std::stringstream c_len; 249 c_off << cfa_off; 250 c_len << cfa_len; 251 { 252 out << Internal::indent(depth) 253 << Internal::stringFormat(format,address,4) 254 << "TIFF Offset : " 255 << c_off.str() 256 << std::endl; 257 out << Internal::indent(depth) 258 << Internal::stringFormat(format,address2,4) 259 << "TIFF Length : " 260 << c_len.str() 261 << std::endl; 262 } 263 264 io_->seek(jpg_img_off, BasicIo::beg); // rewind 265 address = io_->tell(); 266 DataBuf payload(16); // header is different from chunks 267 io_->read(payload.pData_, payload.size_); 268 { 269 out << Internal::indent(depth) 270 << Internal::stringFormat(format,address, jpg_img_len) // , jpg_img_off) 271 << " JPEG : " 272 << Internal::binaryToString(makeSlice(payload, 0, payload.size_)) 273 << std::endl; 274 } 275 276 io_->seek(cfa_hdr_off, BasicIo::beg); // rewind 277 address = io_->tell(); 278 io_->read(payload.pData_, payload.size_); 279 { 280 out << Internal::indent(depth) 281 << Internal::stringFormat(format,address, cfa_hdr_len, cfa_hdr_off) 282 << " CFA : " 283 << Internal::binaryToString(makeSlice(payload, 0, payload.size_)) 284 << std::endl; 285 } 286 287 io_->seek(cfa_off, BasicIo::beg); // rewind 288 address = io_->tell(); 289 io_->read(payload.pData_, payload.size_); 290 { 291 out << Internal::indent(depth) 292 << Internal::stringFormat(format,address, cfa_len, cfa_off) 293 << " TIFF : " 294 << Internal::binaryToString(makeSlice(payload, 0, payload.size_)) 295 << std::endl; 296 } 297 } 298 } // RafImage::printStructure 299 readMetadata()300 void RafImage::readMetadata() 301 { 302 #ifdef EXIV2_DEBUG_MESSAGES 303 std::cerr << "Reading RAF file " << io_->path() << "\n"; 304 #endif 305 if (io_->open() != 0) throw Error(kerDataSourceOpenFailed, io_->path(), strError()); 306 IoCloser closer(*io_); 307 // Ensure that this is the correct image type 308 if (!isRafType(*io_, false)) { 309 if (io_->error() || io_->eof()) throw Error(kerFailedToReadImageData); 310 throw Error(kerNotAnImage, "RAF"); 311 } 312 313 clearMetadata(); 314 315 if (io_->seek(84,BasicIo::beg) != 0) throw Error(kerFailedToReadImageData); 316 byte jpg_img_offset [4]; 317 if (io_->read(jpg_img_offset, 4) != 4) throw Error(kerFailedToReadImageData); 318 byte jpg_img_length [4]; 319 if (io_->read(jpg_img_length, 4) != 4) throw Error(kerFailedToReadImageData); 320 uint32_t jpg_img_off_u32 = Exiv2::getULong((const byte *) jpg_img_offset, bigEndian); 321 uint32_t jpg_img_len_u32 = Exiv2::getULong((const byte *) jpg_img_length, bigEndian); 322 323 enforce(Safe::add(jpg_img_off_u32, jpg_img_len_u32) <= io_->size(), kerCorruptedMetadata); 324 325 #if LONG_MAX < UINT_MAX 326 enforce(jpg_img_off_u32 <= static_cast<uint32_t>(std::numeric_limits<long>::max()), 327 kerCorruptedMetadata); 328 enforce(jpg_img_len_u32 <= static_cast<uint32_t>(std::numeric_limits<long>::max()), 329 kerCorruptedMetadata); 330 #endif 331 332 long jpg_img_off = static_cast<long>(jpg_img_off_u32); 333 long jpg_img_len = static_cast<long>(jpg_img_len_u32); 334 335 enforce(jpg_img_len >= 12, kerCorruptedMetadata); 336 337 DataBuf buf(jpg_img_len - 12); 338 if (io_->seek(jpg_img_off + 12,BasicIo::beg) != 0) throw Error(kerFailedToReadImageData); 339 io_->read(buf.pData_, buf.size_); 340 if (io_->error() || io_->eof()) throw Error(kerFailedToReadImageData); 341 342 io_->seek(0,BasicIo::beg); // rewind 343 344 ByteOrder bo = TiffParser::decode(exifData_, 345 iptcData_, 346 xmpData_, 347 buf.pData_, 348 buf.size_); 349 350 exifData_["Exif.Image2.JPEGInterchangeFormat"] = getULong(jpg_img_offset, bigEndian); 351 exifData_["Exif.Image2.JPEGInterchangeFormatLength"] = getULong(jpg_img_length, bigEndian); 352 353 setByteOrder(bo); 354 355 // parse the tiff 356 byte readBuff[4]; 357 if (io_->seek(100, BasicIo::beg) != 0) throw Error(kerFailedToReadImageData); 358 if (io_->read(readBuff, 4) != 4 ) throw Error(kerFailedToReadImageData); 359 uint32_t tiffOffset = Exiv2::getULong(readBuff, bigEndian); 360 361 if (io_->read(readBuff, 4) != 4) throw Error(kerFailedToReadImageData); 362 uint32_t tiffLength = Exiv2::getULong(readBuff, bigEndian); 363 364 // sanity check. Does tiff lie inside the file? 365 enforce(Safe::add(tiffOffset, tiffLength) <= io_->size(), kerCorruptedMetadata); 366 367 if (io_->seek(tiffOffset, BasicIo::beg) != 0) throw Error(kerFailedToReadImageData); 368 369 // Check if this really is a tiff and then call the tiff parser. 370 // Check is needed because some older models just embed a raw bitstream. 371 // For those files we skip the parsing step. 372 if (io_->read(readBuff, 4) != 4) { throw Error(kerFailedToReadImageData); } 373 io_->seek(-4, BasicIo::cur); 374 if (memcmp(readBuff, "\x49\x49\x2A\x00", 4) == 0 || 375 memcmp(readBuff, "\x4D\x4D\x00\x2A", 4) == 0) 376 { 377 DataBuf tiff(tiffLength); 378 io_->read(tiff.pData_, tiff.size_); 379 380 if (!io_->error() && !io_->eof()) 381 { 382 TiffParser::decode(exifData_, 383 iptcData_, 384 xmpData_, 385 tiff.pData_, 386 tiff.size_); 387 } 388 } 389 } // RafImage::readMetadata 390 writeMetadata()391 void RafImage::writeMetadata() 392 { 393 //! Todo: implement me! 394 throw(Error(kerWritingImageFormatUnsupported, "RAF")); 395 } // RafImage::writeMetadata 396 397 // ************************************************************************* 398 // free functions newRafInstance(BasicIo::AutoPtr io,bool create)399 Image::AutoPtr newRafInstance(BasicIo::AutoPtr io, bool create) 400 { 401 Image::AutoPtr image(new RafImage(io, create)); 402 if (!image->good()) { 403 image.reset(); 404 } 405 return image; 406 } 407 isRafType(BasicIo & iIo,bool advance)408 bool isRafType(BasicIo& iIo, bool advance) 409 { 410 const int32_t len = 8; 411 byte buf[len]; 412 iIo.read(buf, len); 413 if (iIo.error() || iIo.eof()) { 414 return false; 415 } 416 int rc = memcmp(buf, "FUJIFILM", 8); 417 if (!advance || rc != 0) { 418 iIo.seek(-len, BasicIo::cur); 419 } 420 return rc == 0; 421 } 422 423 } // namespace Exiv2 424