Factor out jpeg list image dataset loading for use in calibration.

Change-Id: Ie546a9458699fd80cb4359c703b8cacc32e2e52a
diff --git a/aos/vision/debug/jpeg_list-source.cc b/aos/vision/debug/jpeg_list-source.cc
index d3e1006..027acc9 100644
--- a/aos/vision/debug/jpeg_list-source.cc
+++ b/aos/vision/debug/jpeg_list-source.cc
@@ -1,5 +1,7 @@
 #include "aos/vision/debug/debug_framework.h"
 
+#include "aos/vision/image/image_dataset.h"
+
 #include <gdk/gdk.h>
 #include <fstream>
 #include <string>
@@ -7,77 +9,12 @@
 namespace aos {
 namespace vision {
 
-namespace {
-std::string GetFileContents(const std::string &filename) {
-  std::ifstream in(filename, std::ios::in | std::ios::binary);
-  if (in) {
-    std::string contents;
-    in.seekg(0, std::ios::end);
-    contents.resize(in.tellg());
-    in.seekg(0, std::ios::beg);
-    in.read(&contents[0], contents.size());
-    in.close();
-    return (contents);
-  }
-  fprintf(stderr, "Could not read file: %s\n", filename.c_str());
-  exit(-1);
-}
-
-std::vector<std::string> Split(DataRef inp, char delim) {
-  size_t i = 0;
-  std::vector<size_t> pos;
-  while (i < inp.size()) {
-    i = inp.find(delim, i);
-    if (i == std::string::npos) break;
-    // fprintf(stderr, "k=%d, i=%d\n", k, (int)i);
-    pos.emplace_back(i);
-    i = i + 1;
-  }
-  std::vector<std::string> res;
-  res.reserve(pos.size() + 1);
-  i = 0;
-  for (auto p : pos) {
-    res.emplace_back(inp.substr(i, p - i).to_string());
-    i = p + 1;
-  }
-  res.emplace_back(inp.substr(i).to_string());
-  return res;
-}
-}  // namespace
-
 class JpegListImageSource : public ImageSource {
  public:
   void Init(const std::string &jpeg_list_filename,
             DebugFrameworkInterface *interface) override {
     interface_ = interface;
-    auto contents = GetFileContents(jpeg_list_filename);
-
-    std::string basename;
-    auto it = jpeg_list_filename.find_last_of('/');
-    if (it != std::string::npos) {
-      basename = jpeg_list_filename.substr(0, it + 1);
-    }
-
-    for (const auto &jpeg_filename : Split(contents, '\n')) {
-      [&]() {
-        if (jpeg_filename.empty()) return;
-        for (std::size_t i = 0; i < jpeg_filename.size(); ++i) {
-          if (jpeg_filename[i] == '#') return;
-          if (jpeg_filename[i] != ' ') break;
-        }
-        bool is_jpeg = true;
-        size_t l = jpeg_filename.size();
-        if (l > 4 && jpeg_filename[l - 1] == 'v') {
-          is_jpeg = false;
-        }
-        if (jpeg_filename[0] == '/') {
-          images_.emplace_back(Frame{is_jpeg, GetFileContents(jpeg_filename)});
-        } else {
-          images_.emplace_back(
-              Frame{is_jpeg, GetFileContents(basename + jpeg_filename)});
-        }
-      }();
-    }
+    images_ = LoadDataset(jpeg_list_filename);
     fprintf(stderr, "loaded %lu items\n", images_.size());
     if (!images_.empty()) {
       SetCurrentFrame();
@@ -123,11 +60,7 @@
 
  private:
   DebugFrameworkInterface *interface_ = nullptr;
-  struct Frame {
-    bool is_jpeg = true;
-    std::string data;
-  };
-  std::vector<Frame> images_;
+  std::vector<DatasetFrame> images_;
   size_t idx_ = 0;
 };
 
diff --git a/aos/vision/image/BUILD b/aos/vision/image/BUILD
index 9bc3c19..be702d7 100644
--- a/aos/vision/image/BUILD
+++ b/aos/vision/image/BUILD
@@ -42,6 +42,15 @@
 )
 
 cc_library(
+    name = "image_dataset",
+    srcs = ["image_dataset.cc"],
+    hdrs = ["image_dataset.h"],
+    deps = [
+        ":image_types",
+    ],
+)
+
+cc_library(
     name = "image_stream",
     hdrs = ["image_stream.h"],
     deps = [
diff --git a/aos/vision/image/image_dataset.cc b/aos/vision/image/image_dataset.cc
new file mode 100644
index 0000000..cd3ec46
--- /dev/null
+++ b/aos/vision/image/image_dataset.cc
@@ -0,0 +1,84 @@
+#include "aos/vision/image/image_dataset.h"
+
+#include <fstream>
+
+#include "aos/vision/image/image_types.h"
+
+namespace aos {
+namespace vision {
+
+namespace {
+std::string GetFileContents(const std::string &filename) {
+  std::ifstream in(filename, std::ios::in | std::ios::binary);
+  if (in) {
+    std::string contents;
+    in.seekg(0, std::ios::end);
+    contents.resize(in.tellg());
+    in.seekg(0, std::ios::beg);
+    in.read(&contents[0], contents.size());
+    in.close();
+    return (contents);
+  }
+  fprintf(stderr, "Could not read file: %s\n", filename.c_str());
+  exit(-1);
+}
+
+std::vector<std::string> Split(DataRef inp, char delim) {
+  size_t i = 0;
+  std::vector<size_t> pos;
+  while (i < inp.size()) {
+    i = inp.find(delim, i);
+    if (i == std::string::npos) break;
+    // fprintf(stderr, "k=%d, i=%d\n", k, (int)i);
+    pos.emplace_back(i);
+    i = i + 1;
+  }
+  std::vector<std::string> res;
+  res.reserve(pos.size() + 1);
+  i = 0;
+  for (auto p : pos) {
+    res.emplace_back(inp.substr(i, p - i).to_string());
+    i = p + 1;
+  }
+  res.emplace_back(inp.substr(i).to_string());
+  return res;
+}
+}  // namespace
+
+std::vector<DatasetFrame> LoadDataset(const std::string &jpeg_list_filename) {
+  std::vector<DatasetFrame> images;
+  auto contents = GetFileContents(jpeg_list_filename);
+
+  std::string basename;
+  auto it = jpeg_list_filename.find_last_of('/');
+  if (it != std::string::npos) {
+    basename = jpeg_list_filename.substr(0, it + 1);
+  }
+
+  for (const auto &jpeg_filename : Split(contents, '\n')) {
+    [&]() {
+      if (jpeg_filename.empty()) return;
+      for (std::size_t i = 0; i < jpeg_filename.size(); ++i) {
+        if (jpeg_filename[i] == '#') return;
+        if (jpeg_filename[i] != ' ') break;
+      }
+      bool is_jpeg = true;
+      size_t l = jpeg_filename.size();
+      if (l > 4 && jpeg_filename[l - 1] == 'v') {
+        is_jpeg = false;
+      }
+      if (jpeg_filename[0] == '/') {
+        images.emplace_back(
+            DatasetFrame{is_jpeg, GetFileContents(jpeg_filename)});
+      } else {
+        images.emplace_back(
+            DatasetFrame{is_jpeg, GetFileContents(basename + jpeg_filename)});
+      }
+    }();
+  }
+
+  return images;
+}
+
+}  // namespace vision
+}  // namespace aos
diff --git a/aos/vision/image/image_dataset.h b/aos/vision/image/image_dataset.h
new file mode 100644
index 0000000..ce8c841
--- /dev/null
+++ b/aos/vision/image/image_dataset.h
@@ -0,0 +1,21 @@
+#ifndef _AOS_VISION_IMAGE_IMAGE_DATASET_H_
+#define _AOS_VISION_IMAGE_IMAGE_DATASET_H_
+
+#include <string>
+#include <vector>
+
+namespace aos {
+namespace vision {
+
+struct DatasetFrame {
+  // TODO: These should be V4L formats ideally.
+  bool is_jpeg = true;
+  std::string data;
+};
+
+std::vector<DatasetFrame> LoadDataset(const std::string &jpeg_list_filename);
+
+}  // namespace vision
+}  // namespace aos
+
+#endif  // _AOS_VISION_IMAGE_IMAGE_DATASET_H_