RawSpeed
fast raw decoding library
Loading...
Searching...
No Matches
CameraMetaData.cpp
Go to the documentation of this file.
1/*
2 RawSpeed - RAW file decoder.
3
4 Copyright (C) 2009-2014 Klaus Post
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with this library; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19*/
20
21#include "rawspeedconfig.h"
23#include "common/Common.h"
24#include "metadata/Camera.h"
25#include <algorithm>
26#include <cstdint>
27#include <map>
28#include <memory>
29#include <string>
30#include <string_view>
31#include <tuple>
32#include <utility>
33
34#ifdef HAVE_PUGIXML
36#include <pugixml.hpp>
37#include <vector>
38
39using pugi::xml_document;
40using pugi::xml_node;
41using pugi::xml_parse_result;
42#endif
43
44namespace rawspeed {
45
46#ifdef HAVE_PUGIXML
47CameraMetaData::CameraMetaData(const char* docname) {
48 xml_document doc;
49
50 if (xml_parse_result result =
51#if defined(__unix__) || defined(__APPLE__)
52 doc.load_file(docname)
53#else
54 doc.load_file(pugi::as_wide(docname).c_str())
55#endif
56 ;
57 !result) {
58 ThrowCME("XML Document \"%s\" could not be parsed successfully. Error was: "
59 "%s in %s",
60 docname, result.description(),
61 doc.child("node").attribute("attr").value());
62 }
63
64 for (xml_node camera : doc.child("Cameras").children("Camera")) {
65 const auto* cam = addCamera(std::make_unique<Camera>(camera));
66
67 if (cam == nullptr)
68 continue;
69
70 // Create cameras for aliases.
71 for (auto i = 0UL; i < cam->aliases.size(); i++) {
72 addCamera(std::make_unique<Camera>(cam, i));
73 }
74 }
75}
76#endif
77
78namespace {
79
80inline CameraId getId(const std::string& make, const std::string& model,
81 const std::string& mode) {
82 CameraId id;
83 id.make = trimSpaces(make);
84 id.model = trimSpaces(model);
85 id.mode = trimSpaces(mode);
86
87 return id;
88}
89
90} // namespace
91
92const Camera* CameraMetaData::getCamera(const std::string& make,
93 const std::string& model,
94 const std::string& mode) const {
95 auto camera = cameras.find(getId(make, model, mode));
96 return camera == cameras.end() ? nullptr : camera->second.get();
97}
98
99const Camera* CameraMetaData::getCamera(const std::string& make,
100 const std::string& model) const {
101 auto id = getId(make, model, "");
102
103 auto iter = find_if(
104 cameras.cbegin(), cameras.cend(), [&id](decltype(*cameras.cbegin())& i) {
105 const auto& cid = i.first;
106 return tie(id.make, id.model) == tie(cid.make, cid.model);
107 });
108
109 if (iter == cameras.end())
110 return nullptr;
111
112 return iter->second.get();
113}
114
115bool CameraMetaData::hasCamera(const std::string& make,
116 const std::string& model,
117 const std::string& mode) const {
118 return getCamera(make, model, mode);
119}
120
121const Camera* RAWSPEED_READONLY
123 auto camera = chdkCameras.find(filesize);
124 return camera == chdkCameras.end() ? nullptr : camera->second;
125}
126
127bool RAWSPEED_READONLY CameraMetaData::hasChdkCamera(uint32_t filesize) const {
128 return chdkCameras.contains(filesize);
129}
130
131const Camera* CameraMetaData::addCamera(std::unique_ptr<Camera> cam) {
132 auto id = getId(cam->make, cam->model, cam->mode);
133 if (cameras.contains(id)) {
134 writeLog(
136 "CameraMetaData: Duplicate entry found for camera: %s %s, Skipping!",
137 cam->make.c_str(), cam->model.c_str());
138 return nullptr;
139 }
140 cameras[id] = std::move(cam);
141
142 if (std::string::npos != cameras[id]->mode.find("chdk")) {
143 auto filesize_hint = cameras[id]->hints.get("filesize", std::string());
144 if (filesize_hint.empty()) {
146 "CameraMetaData: CHDK camera: %s %s, no \"filesize\" hint set!",
147 cameras[id]->make.c_str(), cameras[id]->model.c_str());
148 } else {
149 chdkCameras[stoi(filesize_hint)] = cameras[id].get();
150 // writeLog(DEBUG_PRIO::WARNING, "CHDK camera: %s %s size:%u",
151 // cameras[id]->make.c_str(), cameras[id]->model.c_str(), size);
152 }
153 }
154 return cameras[id].get();
155}
156
157void CameraMetaData::disableMake(std::string_view make) const {
158 for (const auto& [id, cam] : cameras) {
159 if (cam->make == make)
160 cam->supportStatus = Camera::SupportStatus::Unsupported;
161 }
162}
163
164void CameraMetaData::disableCamera(std::string_view make,
165 std::string_view model) const {
166 for (const auto& [id, cam] : cameras) {
167 if (cam->make == make && cam->model == model)
168 cam->supportStatus = Camera::SupportStatus::Unsupported;
169 }
170}
171
172} // namespace rawspeed
#define ThrowCME(...)
const Camera * getCamera(const std::string &make, const std::string &model, const std::string &mode) const
std::map< uint32_t, Camera * > chdkCameras
const Camera *RAWSPEED_READONLY getChdkCamera(uint32_t filesize) const
std::map< CameraId, std::unique_ptr< Camera > > cameras
bool hasCamera(const std::string &make, const std::string &model, const std::string &mode) const
void disableCamera(std::string_view make, std::string_view model) const
void disableMake(std::string_view make) const
bool RAWSPEED_READONLY hasChdkCamera(uint32_t filesize) const
const Camera * addCamera(std::unique_ptr< Camera > cam)
CameraId getId(const std::string &make, const std::string &model, const std::string &mode)
std::string trimSpaces(std::string_view str)
Definition Common.h:163
void writeLog(DEBUG_PRIO priority, const char *format,...)
Definition Common.cpp:37