JeVois  1.5
JeVois Smart Embedded Machine Vision Toolkit
Share this page:
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 #include <cctype> // for std::isspace()
35 
36 // ####################################################################################################
37 std::string jevois::fccstr(unsigned int fcc)
38 {
39  if (fcc == 0) return "NONE"; // for no video over USB output
40 
41  std::string ret(" ");
42  ret[0] = static_cast<char>(fcc & 0xff);
43  ret[1] = static_cast<char>((fcc >> 8) & 0xff);
44  ret[2] = static_cast<char>((fcc >> 16) & 0xff);
45  ret[3] = static_cast<char>((fcc >> 24) & 0xff);
46  return ret;
47 }
48 
49 // ####################################################################################################
50 unsigned int jevois::strfcc(std::string const & str)
51 {
52  if (str == "BAYER") return V4L2_PIX_FMT_SRGGB8;
53  else if (str == "YUYV") return V4L2_PIX_FMT_YUYV;
54  else if (str == "GREY" || str == "GRAY") return V4L2_PIX_FMT_GREY;
55  else if (str == "MJPG") return V4L2_PIX_FMT_MJPEG;
56  else if (str == "RGB565") return V4L2_PIX_FMT_RGB565;
57  else if (str == "BGR24") return V4L2_PIX_FMT_BGR24;
58  else if (str == "NONE") return 0;
59  else throw std::runtime_error("Invalid pixel format " + str);
60 }
61 
62 // ####################################################################################################
63 unsigned int jevois::v4l2BytesPerPix(unsigned int fcc)
64 {
65  switch (fcc)
66  {
67  case V4L2_PIX_FMT_YUYV: return 2U;
68  case V4L2_PIX_FMT_GREY: return 1U;
69  case V4L2_PIX_FMT_SRGGB8: return 1U;
70  case V4L2_PIX_FMT_RGB565: return 2U;
71  case V4L2_PIX_FMT_MJPEG: return 2U; // at most??
72  case V4L2_PIX_FMT_BGR24: return 3U;
73  case 0: return 0U; // for NONE output to USB mode
74  default: LFATAL("Unsupported pixel format " << jevois::fccstr(fcc));
75  }
76 }
77 
78 // ####################################################################################################
79 unsigned int jevois::v4l2ImageSize(unsigned int fcc, unsigned int width, unsigned int height)
80 { return width * height * jevois::v4l2BytesPerPix(fcc); }
81 
82 // ####################################################################################################
83 unsigned int jevois::blackColor(unsigned int fcc)
84 {
85  switch (fcc)
86  {
87  case V4L2_PIX_FMT_YUYV: return 0x8000;
88  case V4L2_PIX_FMT_GREY: return 0;
89  case V4L2_PIX_FMT_SRGGB8: return 0;
90  case V4L2_PIX_FMT_RGB565: return 0;
91  case V4L2_PIX_FMT_MJPEG: return 0;
92  case V4L2_PIX_FMT_BGR24: return 0;
93  default: LFATAL("Unsupported pixel format " << jevois::fccstr(fcc));
94  }
95 }
96 
97 // ####################################################################################################
98 unsigned int jevois::whiteColor(unsigned int fcc)
99 {
100  switch (fcc)
101  {
102  case V4L2_PIX_FMT_YUYV: return 0x80ff;
103  case V4L2_PIX_FMT_GREY: return 0xff;
104  case V4L2_PIX_FMT_SRGGB8: return 0xff;
105  case V4L2_PIX_FMT_RGB565: return 0xffff;
106  case V4L2_PIX_FMT_MJPEG: return 0xff;
107  case V4L2_PIX_FMT_BGR24: return 0xffffff;
108  default: LFATAL("Unsupported pixel format " << jevois::fccstr(fcc));
109  }
110 }
111 
112 // ####################################################################################################
113 std::vector<std::string> jevois::split(std::string const & input, std::string const & regex)
114 {
115  // This code is from: http://stackoverflow.com/questions/9435385/split-a-string-using-c11
116  // passing -1 as the submatch index parameter performs splitting
117  std::regex re(regex);
118  std::sregex_token_iterator first{input.begin(), input.end(), re, -1}, last;
119  return { first, last };
120 }
121 
122 // ####################################################################################################
123 std::string jevois::join(std::vector<std::string> const & strings, std::string const & delimiter)
124 {
125  if (strings.empty()) return "";
126  if (strings.size() == 1) return strings[0];
127 
128  std::string ret; size_t const szm1 = strings.size() - 1;
129 
130  for (size_t i = 0; i < szm1; ++i) ret += strings[i] + delimiter;
131  ret += strings[szm1];
132 
133  return ret;
134 }
135 
136 // ####################################################################################################
137 bool jevois::stringStartsWith(std::string const & str, std::string const & prefix)
138 {
139  return (strncmp(str.c_str(), prefix.c_str(), prefix.length()) == 0);
140 }
141 
142 // ####################################################################################################
143 std::string jevois::replaceWhitespace(std::string const & str, char rep)
144 {
145  std::string ret = str;
146  for (char & c : ret) if (std::isspace(c)) c = rep;
147  return ret;
148 }
149 
150 // ####################################################################################################
151 namespace
152 {
153  // This code is from NRT, and before that from the iLab C++ neuromorphic vision toolkit
154  std::string vsformat(char const * fmt, va_list ap)
155  {
156  // if we have a null pointer or an empty string, then just return an empty std::string
157  if (fmt == nullptr || fmt[0] == '\0') return std::string();
158 
159  int bufsize = 1024;
160  while (true)
161  {
162  char buf[bufsize];
163 
164  int const nchars = vsnprintf(buf, bufsize, fmt, ap);
165 
166  if (nchars < 0)
167  {
168  // Better leave this as LFATAL() rather than LERROR(), otherwise we have to return a bogus std::string (e.g. an
169  // empty string, or "none", or...), which might be dangerous if it is later used as a filename, for example.
170  LFATAL("vsnprintf failed for format '" << fmt << "' with bufsize = " << bufsize);
171  }
172  else if (nchars >= bufsize)
173  {
174  // buffer was too small, so let's double the bufsize and try again:
175  bufsize *= 2;
176  continue;
177  }
178  else
179  {
180  // OK, the vsnprintf() succeeded:
181  return std::string(&buf[0], nchars);
182  }
183  }
184  return std::string(); // can't happen, but placate the compiler
185  }
186 }
187 
188 // ####################################################################################################
189 std::string jevois::sformat(char const * fmt, ...)
190 {
191  va_list a;
192  va_start(a, fmt);
193  std::string result = vsformat(fmt, a);
194  va_end(a);
195  return result;
196 }
197 
198 // ####################################################################################################
200 {
201 #ifdef JEVOIS_PLATFORM
202  std::ofstream ofs("/proc/sys/vm/drop_caches");
203  if (ofs.is_open()) ofs << "3" << std::endl;
204  else LERROR("Failed to flush cache -- ignored");
205 #endif
206 }
207 
208 // ####################################################################################################
209 // This code modified from here: https://stackoverflow.com/questions/478898/how-to-execute-a-command-and-get-
210 // output-of-command-within-c-using-posix
211 std::string jevois::system(std::string const & cmd)
212 {
213  std::array<char, 128> buffer; std::string result;
214  std::shared_ptr<FILE> pipe(popen(cmd.c_str(), "r"), pclose);
215  if (!pipe) LFATAL("popen() failed for command [" << cmd << ']');
216  while (!feof(pipe.get())) if (fgets(buffer.data(), 128, pipe.get()) != NULL) result += buffer.data();
217  return result;
218 }
unsigned int whiteColor(unsigned int fcc)
Return a value that corresponds to white for the given video format.
Definition: Utils.C:98
void flushcache()
Flush the caches, may sometimes be useful when running the camera in turbo mode.
Definition: Utils.C:199
unsigned int blackColor(unsigned int fcc)
Return a value that corresponds to black for the given video format.
Definition: Utils.C:83
std::string sformat(char const *fmt,...) __attribute__((format(__printf__
Create a string using printf style arguments.
Definition: Utils.C:189
std::string replaceWhitespace(std::string const &str, char rep='_')
Replace white space characters in a string with underscore (default) or another characters.
Definition: Utils.C:143
unsigned int v4l2BytesPerPix(unsigned int fcc)
Return the number of bytes per pixel for a given V4L2_PIX_FMT_...
Definition: Utils.C:63
#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:123
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:137
std::string fccstr(unsigned int fcc)
Convert a V4L2 four-cc code (V4L2_PIX_FMT_...) to a 4-char string.
Definition: Utils.C:37
#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:79
std::string system(std::string const &cmd)
Execute a command and grab stdout output to a string.
Definition: Utils.C:211
unsigned int strfcc(std::string const &str)
Convert a JeVois video format string to V4L2 four-cc code (V4L2_PIX_FMT_...)
Definition: Utils.C:50
std::vector< std::string > split(std::string const &input, std::string const &regex="\+")
Split string into vector of tokens using a regex to specify what to split on; default regex splits by...
Definition: Utils.C:113