/src/exiv2/src/gifimage.cpp
Line | Count | Source |
1 | | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | | |
3 | | // included header files |
4 | | #include "gifimage.hpp" |
5 | | #include "basicio.hpp" |
6 | | #include "config.h" |
7 | | #include "error.hpp" |
8 | | #include "futils.hpp" |
9 | | |
10 | | #include <array> |
11 | | |
12 | | #ifdef EXIV2_DEBUG_MESSAGES |
13 | | #include <iostream> |
14 | | #endif |
15 | | |
16 | | // ***************************************************************************** |
17 | | // class member definitions |
18 | | namespace Exiv2 { |
19 | | GifImage::GifImage(BasicIo::UniquePtr io, const ImageCtorParams& params) : |
20 | 31 | Image(ImageType::gif, mdNone, std::move(io), params) { |
21 | 31 | } |
22 | | |
23 | 20 | std::string GifImage::mimeType() const { |
24 | 20 | return "image/gif"; |
25 | 20 | } |
26 | | |
27 | 0 | void GifImage::setExifData(const ExifData& /*exifData*/) { |
28 | | // Todo: implement me! |
29 | 0 | throw(Error(ErrorCode::kerInvalidSettingForImage, "Exif metadata", "GIF")); |
30 | 0 | } |
31 | | |
32 | 0 | void GifImage::setIptcData(const IptcData& /*iptcData*/) { |
33 | | // Todo: implement me! |
34 | 0 | throw(Error(ErrorCode::kerInvalidSettingForImage, "IPTC metadata", "GIF")); |
35 | 0 | } |
36 | | |
37 | 0 | void GifImage::setComment(const std::string&) { |
38 | | // not supported |
39 | 0 | throw(Error(ErrorCode::kerInvalidSettingForImage, "Image comment", "GIF")); |
40 | 0 | } |
41 | | |
42 | 21 | void GifImage::readMetadata() { |
43 | | #ifdef EXIV2_DEBUG_MESSAGES |
44 | | std::cerr << "Exiv2::GifImage::readMetadata: Reading GIF file " << io_->path() << "\n"; |
45 | | #endif |
46 | 21 | if (io_->open() != 0) { |
47 | 0 | throw Error(ErrorCode::kerDataSourceOpenFailed, io_->path(), strError()); |
48 | 0 | } |
49 | 21 | IoCloser closer(*io_); |
50 | | // Ensure that this is the correct image type |
51 | 21 | if (!isGifType(*io_, true)) { |
52 | 0 | if (io_->error() || io_->eof()) |
53 | 0 | throw Error(ErrorCode::kerFailedToReadImageData); |
54 | 0 | throw Error(ErrorCode::kerNotAnImage, "GIF"); |
55 | 0 | } |
56 | 21 | clearMetadata(); |
57 | | |
58 | 21 | byte buf[4]; |
59 | 21 | if (io_->read(buf, sizeof(buf)) == sizeof(buf)) { |
60 | 21 | pixelWidth_ = getShort(buf, littleEndian); |
61 | 21 | pixelHeight_ = getShort(buf + 2, littleEndian); |
62 | 21 | } |
63 | 21 | } // GifImage::readMetadata |
64 | | |
65 | 0 | void GifImage::writeMetadata() { |
66 | | // Todo: implement me! |
67 | 0 | throw(Error(ErrorCode::kerWritingImageFormatUnsupported, "GIF")); |
68 | 0 | } // GifImage::writeMetadata |
69 | | |
70 | | // ************************************************************************* |
71 | | // free functions |
72 | 31 | Image::UniquePtr newGifInstance(BasicIo::UniquePtr io, const ImageCtorParams& params) { |
73 | 31 | auto image = std::make_unique<GifImage>(std::move(io), params); |
74 | 31 | if (!image->good()) { |
75 | 10 | return nullptr; |
76 | 10 | } |
77 | 21 | return image; |
78 | 31 | } |
79 | | |
80 | 10.3k | bool isGifType(BasicIo& iIo, bool advance) { |
81 | 10.3k | const int32_t len = 6; |
82 | 10.3k | const std::array<byte, len> Gif87aId{'G', 'I', 'F', '8', '7', 'a'}; |
83 | 10.3k | const std::array<byte, len> Gif89aId{'G', 'I', 'F', '8', '9', 'a'}; |
84 | 10.3k | std::array<byte, len> buf; |
85 | 10.3k | iIo.read(buf.data(), len); |
86 | 10.3k | if (iIo.error() || iIo.eof()) { |
87 | 251 | return false; |
88 | 251 | } |
89 | 10.0k | bool matched = buf == Gif87aId || buf == Gif89aId; |
90 | 10.0k | if (!advance || !matched) { |
91 | 10.0k | iIo.seek(-len, BasicIo::cur); |
92 | 10.0k | } |
93 | 10.0k | return matched; |
94 | 10.3k | } |
95 | | } // namespace Exiv2 |