CARLA
ImageIOConfig.h
Go to the documentation of this file.
1 // Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma
2 // de Barcelona (UAB).
3 //
4 // This work is licensed under the terms of the MIT license.
5 // For a copy, see <https://opensource.org/licenses/MIT>.
6 
7 #pragma once
8 
9 #include "carla/FileSystem.h"
10 #include "carla/Logging.h"
11 #include "carla/StringUtil.h"
12 #include "carla/image/BoostGil.h"
13 
14 #ifndef LIBCARLA_IMAGE_WITH_PNG_SUPPORT
15 # if defined(__has_include) && __has_include("png.h")
16 # define LIBCARLA_IMAGE_WITH_PNG_SUPPORT true
17 # else
18 # define LIBCARLA_IMAGE_WITH_PNG_SUPPORT false
19 # endif
20 #endif
21 
22 #ifndef LIBCARLA_IMAGE_WITH_JPEG_SUPPORT
23 # if defined(__has_include) && __has_include("jpeglib.h")
24 # define LIBCARLA_IMAGE_WITH_JPEG_SUPPORT true
25 # else
26 # define LIBCARLA_IMAGE_WITH_JPEG_SUPPORT false
27 # endif
28 #endif
29 
30 #ifndef LIBCARLA_IMAGE_WITH_TIFF_SUPPORT
31 # if defined(__has_include) && __has_include("tiffio.h")
32 # define LIBCARLA_IMAGE_WITH_TIFF_SUPPORT true
33 # else
34 # define LIBCARLA_IMAGE_WITH_TIFF_SUPPORT false
35 # endif
36 #endif
37 
38 #if defined(__clang__)
39 # pragma clang diagnostic push
40 # pragma clang diagnostic ignored "-Wunused-parameter"
41 #endif
42 
43 #if LIBCARLA_IMAGE_WITH_PNG_SUPPORT == true
44 # ifndef png_infopp_NULL
45 # define png_infopp_NULL (png_infopp)NULL
46 # endif // png_infopp_NULL
47 # ifndef int_p_NULL
48 # define int_p_NULL (int*)NULL
49 # endif // int_p_NULL
50 # if defined(__clang__)
51 # pragma clang diagnostic push
52 # pragma clang diagnostic ignored "-Wignored-qualifiers"
53 # pragma clang diagnostic ignored "-Wparentheses"
54 # endif
55 # include <boost/gil/extension/io/png.hpp>
56 # if defined(__clang__)
57 # pragma clang diagnostic pop
58 # endif
59 #endif
60 
61 #if LIBCARLA_IMAGE_WITH_JPEG_SUPPORT == true
62 # include <boost/gil/extension/io/jpeg.hpp>
63 #endif
64 
65 #if LIBCARLA_IMAGE_WITH_TIFF_SUPPORT == true
66 # include <boost/gil/extension/io/tiff.hpp>
67 #endif
68 
69 #if defined(__clang__)
70 # pragma clang diagnostic pop
71 #endif
72 
73 namespace carla {
74 namespace image {
75 namespace io {
76 
77  constexpr bool has_png_support() {
79  }
80 
81  constexpr bool has_jpeg_support() {
83  }
84 
85  constexpr bool has_tiff_support() {
87  }
88 
89  static_assert(has_png_support() || has_jpeg_support() || has_tiff_support(),
90  "No image format supported, please compile with at least one of "
91  "LIBCARLA_IMAGE_WITH_PNG_SUPPORT, LIBCARLA_IMAGE_WITH_JPEG_SUPPORT, "
92  "or LIBCARLA_IMAGE_WITH_TIFF_SUPPORT");
93 
94 namespace detail {
95 
96  template <typename ViewT, typename IOTag>
98  static constexpr bool value = boost::gil::is_write_supported<typename boost::gil::get_pixel_type<ViewT>::type, IOTag>::value;
99  };
100 
101  struct io_png {
102 
103  static constexpr bool is_supported = has_png_support();
104 
105 #if LIBCARLA_IMAGE_WITH_PNG_SUPPORT
106 
107  static constexpr const char *get_default_extension() {
108  return "png";
109  }
110 
111  template <typename Str>
112  static bool match_extension(const Str &str) {
113  return StringUtil::EndsWith(str, get_default_extension());
114  }
115 
116  template <typename Str, typename ImageT>
117  static void read_image(Str &&in_filename, ImageT &image) {
118  boost::gil::read_and_convert_image(std::forward<Str>(in_filename), image, boost::gil::png_tag());
119  }
120 
121  template <typename Str, typename ViewT>
122  static void write_view(Str &&out_filename, const ViewT &view) {
123  boost::gil::write_view(std::forward<Str>(out_filename), view, boost::gil::png_tag());
124  }
125 
126 #endif // LIBCARLA_IMAGE_WITH_PNG_SUPPORT
127  };
128 
129  struct io_jpeg {
130 
131  static constexpr bool is_supported = has_jpeg_support();
132 
133 #if LIBCARLA_IMAGE_WITH_JPEG_SUPPORT
134 
135  static constexpr const char *get_default_extension() {
136  return "jpeg";
137  }
138 
139  template <typename Str>
140  static bool match_extension(const Str &str) {
141  return StringUtil::EndsWith(str, get_default_extension()) ||
142  StringUtil::EndsWith(str, "jpg");
143  }
144 
145  template <typename Str, typename ImageT>
146  static void read_image(Str &&in_filename, ImageT &image) {
147  boost::gil::read_image(std::forward<Str>(in_filename), image, boost::gil::jpeg_tag());
148  }
149 
150  template <typename Str, typename ViewT>
151  static typename std::enable_if<is_write_supported<ViewT, boost::gil::jpeg_tag>::value>::type
152  write_view(Str &&out_filename, const ViewT &view) {
153  boost::gil::write_view(std::forward<Str>(out_filename), view, boost::gil::jpeg_tag());
154  }
155 
156  template <typename Str, typename ViewT>
157  static typename std::enable_if<!is_write_supported<ViewT, boost::gil::jpeg_tag>::value>::type
158  write_view(Str &&out_filename, const ViewT &view) {
159  boost::gil::write_view(
160  std::forward<Str>(out_filename),
161  boost::gil::color_converted_view<boost::gil::rgb8_pixel_t>(view),
162  boost::gil::jpeg_tag());
163  }
164 
165 #endif // LIBCARLA_IMAGE_WITH_JPEG_SUPPORT
166  };
167 
168  struct io_tiff {
169 
170  static constexpr bool is_supported = has_tiff_support();
171 
172 #if LIBCARLA_IMAGE_WITH_TIFF_SUPPORT
173 
174  static constexpr const char *get_default_extension() {
175  return "tiff";
176  }
177 
178  template <typename Str>
179  static bool match_extension(const Str &str) {
180  return StringUtil::EndsWith(str, get_default_extension());
181  }
182 
183  template <typename Str, typename ImageT>
184  static void read_image(Str &&in_filename, ImageT &image) {
185  boost::gil::read_and_convert_image(std::forward<Str>(in_filename), image, boost::gil::tiff_tag());
186  }
187 
188  template <typename Str, typename ViewT>
189  static typename std::enable_if<is_write_supported<ViewT, boost::gil::tiff_tag>::value>::type
190  write_view(Str &&out_filename, const ViewT &view) {
191  boost::gil::write_view(std::forward<Str>(out_filename), view, boost::gil::tiff_tag());
192  }
193 
194  template <typename Str, typename ViewT>
195  static typename std::enable_if<!is_write_supported<ViewT, boost::gil::tiff_tag>::value>::type
196  write_view(Str &&out_filename, const ViewT &view) {
197  boost::gil::write_view(
198  std::forward<Str>(out_filename),
199  boost::gil::color_converted_view<boost::gil::rgb8_pixel_t>(view),
200  boost::gil::tiff_tag());
201  }
202 
203 #endif // LIBCARLA_IMAGE_WITH_TIFF_SUPPORT
204  };
205 
206  struct io_resolver {
207 
208  template <typename IO, typename Str>
209  static typename std::enable_if<IO::is_supported, bool>::type match_extension(const Str &str) {
210  return IO::match_extension(str);
211  }
212 
213  template <typename IO, typename Str>
214  static typename std::enable_if<!IO::is_supported, bool>::type match_extension(const Str &) {
215  return false;
216  }
217 
218  template <typename IO, typename Str, typename... Args>
219  static typename std::enable_if<IO::is_supported>::type read_image(const Str &path, Args &&... args) {
220  log_debug("reading", path, "as", IO::get_default_extension());
221  IO::read_image(path, std::forward<Args>(args)...);
222  }
223 
224  template <typename IO, typename... Args>
225  static typename std::enable_if<!IO::is_supported>::type read_image(Args &&...) {
226  DEBUG_ASSERT(false);
227  }
228 
229  template <typename IO, typename... Args>
230  static typename std::enable_if<IO::is_supported>::type write_view(std::string &path, Args &&... args) {
231  FileSystem::ValidateFilePath(path, IO::get_default_extension());
232  log_debug("writing", path, "as", IO::get_default_extension());
233  IO::write_view(path, std::forward<Args>(args)...);
234  }
235 
236  template <typename IO, typename... Args>
237  static typename std::enable_if<!IO::is_supported>::type write_view(Args &&...) {
238  DEBUG_ASSERT(false);
239  }
240  };
241 
242  template <typename... IOs>
243  struct io_impl;
244 
245  template <typename IO>
246  struct io_impl<IO> {
247  constexpr static bool is_supported = IO::is_supported;
248 
249  template <typename... Args>
250  static void read_image(Args &&... args) {
251  io_resolver::read_image<IO>(std::forward<Args>(args)...);
252  }
253 
254  template <typename... Args>
255  static void write_view(Args &&... args) {
256  io_resolver::write_view<IO>(std::forward<Args>(args)...);
257  }
258 
259  template <typename Str, typename... Args>
260  static bool try_read_image(const Str &filename, Args &&... args) {
261  if (io_resolver::match_extension<IO>(filename)) {
262  io_resolver::read_image<IO>(filename, std::forward<Args>(args)...);
263  return true;
264  }
265  return false;
266  }
267 
268  template <typename Str, typename... Args>
269  static bool try_write_view(Str &filename, Args &&... args) {
270  if (io_resolver::match_extension<IO>(filename)) {
271  io_resolver::write_view<IO>(filename, std::forward<Args>(args)...);
272  return true;
273  }
274  return false;
275  }
276  };
277 
278  template <typename IO, typename... IOs>
279  struct io_impl<IO, IOs...> {
280  private:
281  using self = io_impl<IO>;
282  using recursive = io_impl<IOs...>;
283  public:
284 
285  constexpr static bool is_supported = self::is_supported || recursive::is_supported;
286 
287  template <typename... Args>
288  static void read_image(Args &... args) {
289  if (!recursive::try_read_image(args...)) {
290  self::read_image(args...);
291  }
292  }
293 
294  template <typename... Args>
295  static bool try_read_image(Args &... args) {
296  return recursive::try_read_image(args...) || self::try_read_image(args...);
297  }
298 
299  template <typename... Args>
300  static void write_view(Args &... args) {
301  if (!recursive::try_write_view(args...)) {
302  self::write_view(args...);
303  }
304  }
305 
306  template <typename... Args>
307  static bool try_write_view(Args &... args) {
308  return recursive::try_write_view(args...) || self::try_write_view(args...);
309  }
310  };
311 
312  template <typename DefaultIO, typename... IOs>
313  struct io_any : detail::io_impl<DefaultIO, IOs...> {
314  static_assert(DefaultIO::is_supported, "Default IO needs to be supported.");
315  };
316 
317 } // namespace detail
318 
319  struct png : detail::io_impl<detail::io_png> {};
320 
321  struct jpeg : detail::io_impl<detail::io_jpeg> {};
322 
323  struct tiff : detail::io_impl<detail::io_tiff> {};
324 
325 #if LIBCARLA_IMAGE_WITH_PNG_SUPPORT
326 
327  struct any : detail::io_any<detail::io_png, detail::io_tiff, detail::io_jpeg> {};
328 
329 #elif LIBCARLA_IMAGE_WITH_TIFF_SUPPORT
330 
331  struct any : detail::io_any<detail::io_tiff, detail::io_jpeg> {};
332 
333 #else // Then for sure this one is available.
334 
335  struct any : detail::io_any<detail::io_jpeg> {};
336 
337 #endif
338 
339 } // namespace io
340 } // namespace image
341 } // namespace carla
static std::enable_if< IO::is_supported >::type read_image(const Str &path, Args &&... args)
static std::enable_if<!IO::is_supported >::type read_image(Args &&...)
static bool EndsWith(const Range1T &input, const Range2T &test)
Definition: StringUtil.h:31
static std::enable_if<!IO::is_supported >::type write_view(Args &&...)
static std::enable_if<!IO::is_supported, bool >::type match_extension(const Str &)
static void write_view(Args &&... args)
static void ValidateFilePath(std::string &filepath, const std::string &default_extension="")
Convenient function to validate a path before creating a file.
Definition: FileSystem.cpp:18
#define LIBCARLA_IMAGE_WITH_PNG_SUPPORT
Definition: ImageIOConfig.h:18
This file contains definitions of common data structures used in traffic manager. ...
Definition: Carla.cpp:99
static std::enable_if< IO::is_supported >::type write_view(std::string &path, Args &&... args)
static void log_debug(Args &&...)
Definition: Logging.h:75
constexpr bool has_jpeg_support()
Definition: ImageIOConfig.h:81
#define DEBUG_ASSERT(predicate)
Definition: Debug.h:66
static std::enable_if< IO::is_supported, bool >::type match_extension(const Str &str)
#define LIBCARLA_IMAGE_WITH_TIFF_SUPPORT
Definition: ImageIOConfig.h:34
#define LIBCARLA_IMAGE_WITH_JPEG_SUPPORT
Definition: ImageIOConfig.h:26
constexpr bool has_tiff_support()
Definition: ImageIOConfig.h:85
static void read_image(Args &&... args)
static bool try_read_image(const Str &filename, Args &&... args)
static bool try_write_view(Str &filename, Args &&... args)
constexpr bool has_png_support()
Definition: ImageIOConfig.h:77