31 #pragma GCC diagnostic push
32 #pragma GCC diagnostic ignored "-Wunused-parameter"
33 #include "libnpy/npy.hpp"
34 #pragma GCC diagnostic pop
44 #include <unordered_map>
53 template <typename T, typename std::enable_if<std::is_integral<T>::value,
int>
::type = 0>
54 void rgb_to_luminance(
const RawTensor &
src, RawTensor &
dst)
59 const size_t num_elements =
dst.num_elements();
63 for(
size_t i = 0, j = 0; j < num_elements; i += 3, ++j)
65 reinterpret_cast<T *
>(
dst.data())[j] = 0.2126f *
src.data()[i] + 0.7152f *
src.data()[i + 1] + 0.0722f *
src.data()[i + 2];
69 void extract_r_from_rgb(
const RawTensor &
src, RawTensor &
dst)
73 const size_t num_elements =
dst.num_elements();
75 for(
size_t i = 0, j = 0; j < num_elements; i += 3, ++j)
77 dst.data()[j] =
src.data()[i];
81 void extract_g_from_rgb(
const RawTensor &
src, RawTensor &
dst)
85 const size_t num_elements =
dst.num_elements();
87 for(
size_t i = 1, j = 0; j < num_elements; i += 3, ++j)
89 dst.data()[j] =
src.data()[i];
93 void extract_b_from_rgb(
const RawTensor &
src, RawTensor &
dst)
97 const size_t num_elements =
dst.num_elements();
99 for(
size_t i = 2, j = 0; j < num_elements; i += 3, ++j)
101 dst.data()[j] =
src.data()[i];
105 void discard_comments(std::ifstream &fs)
107 while(fs.peek() ==
'#')
109 fs.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
113 void discard_comments_and_spaces(std::ifstream &fs)
117 discard_comments(fs);
119 if(isspace(fs.peek()) == 0)
128 std::tuple<unsigned int, unsigned int, int> parse_netpbm_format_header(std::ifstream &fs,
char number)
131 std::array<char, 2> magic_number{ { 0 } };
132 fs >> magic_number[0] >> magic_number[1];
134 if(magic_number[0] !=
'P' || magic_number[1] != number)
136 throw std::runtime_error(
"File type magic number not supported");
139 discard_comments_and_spaces(fs);
141 unsigned int width = 0;
144 discard_comments_and_spaces(fs);
146 unsigned int height = 0;
149 discard_comments_and_spaces(fs);
156 throw std::runtime_error(
"Cannot read image dimensions");
161 throw std::runtime_error(
"RawTensor doesn't have 8-bit values");
164 discard_comments(fs);
166 if(isspace(fs.peek()) == 0)
168 throw std::runtime_error(
"Invalid image header");
173 return std::make_tuple(width, height, max_value);
176 std::tuple<unsigned int, unsigned int, int>
parse_ppm_header(std::ifstream &fs)
178 return parse_netpbm_format_header(fs,
'6');
181 std::tuple<unsigned int, unsigned int, int> parse_pgm_header(std::ifstream &fs)
183 return parse_netpbm_format_header(fs,
'5');
186 void check_image_size(std::ifstream &fs,
size_t raw_size)
188 const size_t current_position = fs.tellg();
190 const size_t end_position = fs.tellg();
191 fs.seekg(current_position, std::ios_base::beg);
193 if((end_position - current_position) < raw_size)
195 throw std::runtime_error(
"Not enough data in file");
199 void read_image_buffer(std::ifstream &fs, RawTensor &raw)
201 fs.read(
reinterpret_cast<std::fstream::char_type *
>(raw.data()), raw.size());
205 throw std::runtime_error(
"Failure while reading image buffer");
209 RawTensor load_ppm(
const std::string &
path)
211 std::ifstream file(
path, std::ios::in | std::ios::binary);
215 throw framework::FileNotFound(
"Could not load PPM image: " +
path);
218 unsigned int width = 0;
219 unsigned int height = 0;
225 check_image_size(file, raw.size());
226 read_image_buffer(file, raw);
231 RawTensor load_pgm(
const std::string &
path)
233 std::ifstream file(
path, std::ios::in | std::ios::binary);
237 throw framework::FileNotFound(
"Could not load PGM image: " +
path);
240 unsigned int width = 0;
241 unsigned int height = 0;
243 std::tie(width, height, std::ignore) = parse_pgm_header(file);
245 RawTensor raw(TensorShape(width, height),
Format::U8);
247 check_image_size(file, raw.size());
248 read_image_buffer(file, raw);
255 : _library_path(std::move(
path)),
262 return _library_path;
288 const AssetsLibrary::Loader &AssetsLibrary::get_loader(
const std::string &extension)
const
290 static std::unordered_map<std::string, Loader> loaders =
296 const auto it = loaders.find(extension);
298 if(it != loaders.end())
304 throw std::invalid_argument(
"Cannot load image with extension '" + extension +
"'");
308 const AssetsLibrary::Converter &AssetsLibrary::get_converter(
Format src,
Format dst)
const
310 static std::map<std::pair<Format, Format>, Converter> converters =
318 const auto it = converters.find(std::make_pair(
src,
dst));
320 if(it != converters.end())
326 std::stringstream msg;
327 msg <<
"Cannot convert from format '" <<
src <<
"' to format '" <<
dst <<
"'\n";
328 throw std::invalid_argument(msg.str());
334 static std::map<std::pair<DataType, Format>, Converter> converters = {};
336 const auto it = converters.find(std::make_pair(
src,
dst));
338 if(it != converters.end())
344 std::stringstream msg;
345 msg <<
"Cannot convert from data type '" <<
src <<
"' to format '" <<
dst <<
"'\n";
346 throw std::invalid_argument(msg.str());
352 static std::map<std::pair<DataType, DataType>, Converter> converters = {};
354 const auto it = converters.find(std::make_pair(
src,
dst));
356 if(it != converters.end())
362 std::stringstream msg;
363 msg <<
"Cannot convert from data type '" <<
src <<
"' to data type '" <<
dst <<
"'\n";
364 throw std::invalid_argument(msg.str());
370 static std::map<std::pair<Format, DataType>, Converter> converters = {};
372 const auto it = converters.find(std::make_pair(
src,
dst));
374 if(it != converters.end())
380 std::stringstream msg;
381 msg <<
"Cannot convert from format '" <<
src <<
"' to data type '" <<
dst <<
"'\n";
382 throw std::invalid_argument(msg.str());
386 const AssetsLibrary::Extractor &AssetsLibrary::get_extractor(
Format format,
Channel channel)
const
388 static std::map<std::pair<Format, Channel>, Extractor> extractors =
395 const auto it = extractors.find(std::make_pair(
format, channel));
397 if(it != extractors.end())
403 std::stringstream msg;
404 msg <<
"Cannot extract channel '" << channel <<
"' from format '" <<
format <<
"'\n";
405 throw std::invalid_argument(msg.str());
409 RawTensor AssetsLibrary::load_image(
const std::string &
name)
const
412 const std::string image_path = (
"\\images\\");
414 const std::string image_path = (
"/images/");
417 const std::string
path = _library_path + image_path +
name;
418 const std::string extension =
path.substr(
path.find_last_of(
'.') + 1);
419 return (*get_loader(extension))(
path);
422 const RawTensor &AssetsLibrary::find_or_create_raw_tensor(
const std::string &
name,
Format format)
const
424 std::lock_guard<arm_compute::Mutex> guard(_format_lock);
426 const RawTensor *ptr = _cache.
find(std::forward_as_tuple(
name,
format));
433 RawTensor raw = load_image(
name);
435 if(raw.format() !=
format)
439 (*get_converter(raw.format(),
format))(raw,
dst);
440 raw = std::move(
dst);
443 return _cache.
add(std::forward_as_tuple(
name,
format), std::move(raw));
446 const RawTensor &AssetsLibrary::find_or_create_raw_tensor(
const std::string &
name,
Format format,
Channel channel)
const
448 std::lock_guard<arm_compute::Mutex> guard(_channel_lock);
450 const RawTensor *ptr = _cache.
find(std::forward_as_tuple(
name,
format, channel));
463 return _cache.
add(std::forward_as_tuple(
name,
format, channel), std::move(
dst));
492 return find_or_create_raw_tensor(
name,
format);
512 return find_or_create_raw_tensor(
name,
format, channel);
527 std::string header_s = npy::read_header(stream);
530 npy::header_t
header = npy::parse_header(header_s);
533 bool fortran_order =
header.fortran_order;
534 std::string typestr =
header.dtype.str();
543 for(
size_t i = 0; i <
shape.size(); ++i)
550 for(
size_t i = 0; i <
shape.size(); ++i)