JeVois  1.2
JeVois Smart Embedded Machine Vision Toolkit
Utils.C
Go to the documentation of this file.
1 // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2 //
3 // JeVois Smart Embedded Machine Vision Toolkit - Copyright (C) 2016 by Laurent Itti, the University of Southern
4 // California (USC), and iLab at USC. See http://iLab.usc.edu and http://jevois.org for information about this project.
5 //
6 // This file is part of the JeVois Smart Embedded Machine Vision Toolkit. This program is free software; you can
7 // redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software
8 // Foundation, version 2. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9 // without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
10 // License for more details. You should have received a copy of the GNU General Public License along with this program;
11 // if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
12 //
13 // Contact information: Laurent Itti - 3641 Watt Way, HNB-07A - Los Angeles, CA 90089-2520 - USA.
14 // Tel: +1 213 740 3527 - itti@pollux.usc.edu - http://iLab.usc.edu - http://jevois.org
15 // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
16 /*! \file */
17 
18 #include <jevois/Util/Utils.H>
19 #include <jevois/Debug/Log.H>
20 
21 #include <linux/videodev2.h>
22 #include <string>
23 #include <vector>
24 #include <regex>
25 
26 #include <string.h> // for strncmp
27 #include <fstream>
28 #include <cstdarg> // for va_start, etc
29 #include <cstdio>
30 #include <iostream>
31 #include <memory>
32 #include <stdexcept>
33 #include <array>
34 
35 // ####################################################################################################
36 std::string jevois::fccstr(unsigned int fcc)
37 {
38  if (fcc == 0) return "NONE"; // for no video over USB output
39 
40  std::string ret(" ");
41  ret[0] = static_cast<char>(fcc & 0xff);
42  ret[1] = static_cast<char>((fcc >> 8) & 0xff);
43  ret[2] = static_cast<char>((fcc >> 16) & 0xff);
44  ret[3] = static_cast<char>((fcc >> 24) & 0xff);
45  return ret;
46 }
47 
48 // ####################################################################################################
49 unsigned int jevois::v4l2BytesPerPix(unsigned int fcc)
50 {
51  switch (fcc)
52  {
53  case V4L2_PIX_FMT_YUYV: return 2U;
54  case V4L2_PIX_FMT_GREY: return 1U;
55  case V4L2_PIX_FMT_SRGGB8: return 1U;
56  case V4L2_PIX_FMT_RGB565: return 2U;
57  case V4L2_PIX_FMT_MJPEG: return 2U; // at most??
58  case V4L2_PIX_FMT_BGR24: return 3U;
59  case 0: return 0U; // for NONE output to USB mode
60  default: LFATAL("Unsupported pixel format " << jevois::fccstr(fcc));
61  }
62 }
63 
64 // ####################################################################################################
65 unsigned int jevois::v4l2ImageSize(unsigned int fcc, unsigned int width, unsigned int height)
66 { return width * height * jevois::v4l2BytesPerPix(fcc); }
67 
68 // ####################################################################################################
69 unsigned int jevois::blackColor(unsigned int fcc)
70 {
71  switch (fcc)
72  {
73  case V4L2_PIX_FMT_YUYV: return 0x8000;
74  case V4L2_PIX_FMT_GREY: return 0;
75  case V4L2_PIX_FMT_SRGGB8: return 0;
76  case V4L2_PIX_FMT_RGB565: return 0;
77  case V4L2_PIX_FMT_MJPEG: return 0;
78  case V4L2_PIX_FMT_BGR24: return 0;
79  default: LFATAL("Unsupported pixel format " << jevois::fccstr(fcc));
80  }
81 }
82 
83 // ####################################################################################################
84 unsigned int jevois::whiteColor(unsigned int fcc)
85 {
86  switch (fcc)
87  {
88  case V4L2_PIX_FMT_YUYV: return 0x80ff;
89  case V4L2_PIX_FMT_GREY: return 0xff;
90  case V4L2_PIX_FMT_SRGGB8: return 0xff;
91  case V4L2_PIX_FMT_RGB565: return 0xffff;
92  case V4L2_PIX_FMT_MJPEG: return 0xff;
93  case V4L2_PIX_FMT_BGR24: return 0xffffff;
94  default: LFATAL("Unsupported pixel format " << jevois::fccstr(fcc));
95  }
96 }
97 
98 // ####################################################################################################
99 std::vector<std::string> jevois::split(std::string const & input, std::string const & regex)
100 {
101  // This code is from: http://stackoverflow.com/questions/9435385/split-a-string-using-c11
102  // passing -1 as the submatch index parameter performs splitting
103  std::regex re(regex);
104  std::sregex_token_iterator first{input.begin(), input.end(), re, -1}, last;
105  return { first, last };
106 }
107 
108 // ####################################################################################################
109 std::string jevois::join(std::vector<std::string> const & strings, std::string const & delimiter)
110 {
111  if (strings.empty()) return "";
112  if (strings.size() == 1) return strings[0];
113 
114  std::string ret; size_t const szm1 = strings.size() - 1;
115 
116  for (size_t i = 0; i < szm1; ++i) ret += strings[i] + delimiter;
117  ret += strings[szm1];
118 
119  return ret;
120 }
121 
122 // ####################################################################################################
123 bool jevois::stringStartsWith(std::string const & str, std::string const & prefix)
124 {
125  return (strncmp(str.c_str(), prefix.c_str(), prefix.length()) == 0);
126 }
127 
128 // ####################################################################################################
129 namespace
130 {
131  // This code is from NRT, and before that from the iLab C++ neuromorphic vision toolkit
132  std::string vsformat(char const * fmt, va_list ap)
133  {
134  // if we have a null pointer or an empty string, then just return an empty std::string
135  if (fmt == nullptr || fmt[0] == '\0') return std::string();
136 
137  int bufsize = 1024;
138  while (true)
139  {
140  char buf[bufsize];
141 
142  int const nchars = vsnprintf(buf, bufsize, fmt, ap);
143 
144  if (nchars < 0)
145  {
146  // Better leave this as LFATAL() rather than LERROR(), otherwise we have to return a bogus std::string (e.g. an
147  // empty string, or "none", or...), which might be dangerous if it is later used as a filename, for example.
148  LFATAL("vsnprintf failed for format '" << fmt << "' with bufsize = " << bufsize);
149  }
150  else if (nchars >= bufsize)
151  {
152  // buffer was too small, so let's double the bufsize and try again:
153  bufsize *= 2;
154  continue;
155  }
156  else
157  {
158  // OK, the vsnprintf() succeeded:
159  return std::string(&buf[0], nchars);
160  }
161  }
162  return std::string(); // can't happen, but placate the compiler
163  }
164 }
165 
166 // ####################################################################################################
167 std::string jevois::sformat(char const * fmt, ...)
168 {
169  va_list a;
170  va_start(a, fmt);
171  std::string result = vsformat(fmt, a);
172  va_end(a);
173  return result;
174 }
175 
176 // ####################################################################################################
178 {
179 #ifdef JEVOIS_PLATFORM
180  std::ofstream ofs("/proc/sys/vm/drop_caches");
181  if (ofs.is_open()) ofs << "3" << std::endl;
182  else LERROR("Failed to flush cache -- ignored");
183 #endif
184 }
185 
186 // ####################################################################################################
187 // This code modified from here: https://stackoverflow.com/questions/478898/how-to-execute-a-command-and-get-
188 // output-of-command-within-c-using-posix
189 std::string jevois::system(std::string const & cmd)
190 {
191  std::array<char, 128> buffer; std::string result;
192  std::shared_ptr<FILE> pipe(popen(cmd.c_str(), "r"), pclose);
193  if (!pipe) LFATAL("popen() failed for command [" << cmd << ']');
194  while (!feof(pipe.get())) if (fgets(buffer.data(), 128, pipe.get()) != NULL) result += buffer.data();
195  return result;
196 }
unsigned int whiteColor(unsigned int fcc)
Return a value that corresponds to white for the given video format.
Definition: Utils.C:84
std::vector< std::string > split(std::string const &input, std::string const &regex="\\s+")
Split string into vector of tokens using a regex to specify what to split on; default regex splits by...
Definition: Utils.C:99
void flushcache()
Flush the caches, may sometimes be useful when running the camera in turbo mode.
Definition: Utils.C:177
unsigned int blackColor(unsigned int fcc)
Return a value that corresponds to black for the given video format.
Definition: Utils.C:69
std::string sformat(char const *fmt,...) __attribute__((format(__printf__
Create a string using printf style arguments.
Definition: Utils.C:167
unsigned int v4l2BytesPerPix(unsigned int fcc)
Return the number of bytes per pixel for a given V4L2_PIX_FMT_...
Definition: Utils.C:49
#define LERROR(msg)
Convenience macro for users to print out console or syslog messages, ERROR level. ...
Definition: Log.H:193
std::string join(std::vector< std::string > const &strings, std::string const &delimiter)
Concatenate a vector of tokens into a string.
Definition: Utils.C:109
bool stringStartsWith(std::string const &str, std::string const &prefix)
Return true if str starts with prefix (including if both strings are equal)
Definition: Utils.C:123
std::string fccstr(unsigned int fcc)
Convert a V4L2 four-cc code (V4L2_PIX_FMT_...) to a 4-char string.
Definition: Utils.C:36
#define LFATAL(msg)
Convenience macro for users to print out console or syslog messages, FATAL level. ...
Definition: Log.H:212
unsigned int v4l2ImageSize(unsigned int fcc, unsigned int width, unsigned int height)
Return the image size in bytes for a given V4L2_PIX_FMT_..., width, height.
Definition: Utils.C:65
std::string system(std::string const &cmd)
Execute a command and grab stdout output to a string.
Definition: Utils.C:189