Coverage Report

Created: 2026-08-17 07:50

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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