Coverage Report

Created: 2026-09-13 06:12

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
18
    Image(ImageType::gif, mdNone, std::move(io), params) {
21
18
}
22
23
0
std::string GifImage::mimeType() const {
24
0
  return "image/gif";
25
0
}
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
15
void GifImage::readMetadata() {
43
#ifdef EXIV2_DEBUG_MESSAGES
44
  std::cerr << "Exiv2::GifImage::readMetadata: Reading GIF file " << io_->path() << "\n";
45
#endif
46
15
  if (io_->open() != 0) {
47
0
    throw Error(ErrorCode::kerDataSourceOpenFailed, io_->path(), strError());
48
0
  }
49
15
  IoCloser closer(*io_);
50
  // Ensure that this is the correct image type
51
15
  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
15
  clearMetadata();
57
58
15
  byte buf[4];
59
15
  if (io_->read(buf, sizeof(buf)) == sizeof(buf)) {
60
15
    pixelWidth_ = getShort(buf, littleEndian);
61
15
    pixelHeight_ = getShort(buf + 2, littleEndian);
62
15
  }
63
15
}  // 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
18
Image::UniquePtr newGifInstance(BasicIo::UniquePtr io, const ImageCtorParams& params) {
73
18
  auto image = std::make_unique<GifImage>(std::move(io), params);
74
18
  if (!image->good()) {
75
3
    return nullptr;
76
3
  }
77
15
  return image;
78
18
}
79
80
10.4k
bool isGifType(BasicIo& iIo, bool advance) {
81
10.4k
  const int32_t len = 6;
82
10.4k
  const std::array<byte, len> Gif87aId{'G', 'I', 'F', '8', '7', 'a'};
83
10.4k
  const std::array<byte, len> Gif89aId{'G', 'I', 'F', '8', '9', 'a'};
84
10.4k
  std::array<byte, len> buf;
85
10.4k
  iIo.read(buf.data(), len);
86
10.4k
  if (iIo.error() || iIo.eof()) {
87
149
    return false;
88
149
  }
89
10.2k
  bool matched = buf == Gif87aId || buf == Gif89aId;
90
10.2k
  if (!advance || !matched) {
91
10.2k
    iIo.seek(-len, BasicIo::cur);
92
10.2k
  }
93
10.2k
  return matched;
94
10.4k
}
95
}  // namespace Exiv2