Coverage Report

Created: 2026-01-16 06:09

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