Coverage Report

Created: 2026-04-29 07:00

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