Sundry tweaks to aos/vision libs

Change-Id: Ia5578dcf2d42ac53b81af239bf329eb084fcf1d9
diff --git a/aos/vision/blob/stream_view.h b/aos/vision/blob/stream_view.h
index 2ae56ac..a6a661a 100644
--- a/aos/vision/blob/stream_view.h
+++ b/aos/vision/blob/stream_view.h
@@ -29,56 +29,51 @@
     memset(image_.data(), 0, fmt.ImgSize() * sizeof(PixelRef));
   }
 
-  inline void DrawBlobList(const BlobList &blob_list, PixelRef color) {
+  template <typename PixelCallback>
+  inline void ForPxInBlobList(const BlobList &blob_list,
+                              PixelCallback pixel_callback) {
     ImagePtr ptr = img();
-    for (const RangeImage &blob : blob_list) {
+    auto fmt = ptr.fmt();
+    for (const auto &blob : blob_list) {
       for (int i = 0; i < (int)blob.ranges().size(); ++i) {
-        for (const auto &range : blob.ranges()[i]) {
-          for (int j = range.st; j < range.ed; ++j) {
-            ptr.get_px(j, i + blob.min_y()) = color;
+        int y = blob.min_y() + i;
+        if (y >= 0 && y < fmt.h) {
+          for (const auto &range : blob.ranges()[i]) {
+            for (int j = std::max(0, range.st); j < std::min(fmt.w, range.ed);
+                 ++j) {
+              pixel_callback(ptr.get_px(j, y));
+            }
           }
         }
       }
     }
   }
 
+  inline void DrawBlobList(const BlobList &blob_list, PixelRef color) {
+    ForPxInBlobList(blob_list, [&](PixelRef &px) { px = color; });
+  }
+
   inline void DrawSecondBlobList(const BlobList &blob_list, PixelRef color1,
                                  PixelRef color2) {
-    ImagePtr ptr = img();
-    for (const auto &blob : blob_list) {
-      for (int i = 0; i < (int)blob.ranges().size(); ++i) {
-        for (const auto &range : blob.ranges()[i]) {
-          for (int j = range.st; j < range.ed; ++j) {
-            auto px = ptr.get_px(j, i + blob.min_y());
-            if (px.r == 0 && px.g == 0 && px.b == 0) {
-              ptr.get_px(j, i + blob.min_y()) = color1;
-            } else {
-              ptr.get_px(j, i + blob.min_y()) = color2;
-            }
-          }
-        }
+    ForPxInBlobList(blob_list, [&](PixelRef &px) {
+      if (px.r == 0 && px.g == 0 && px.b == 0) {
+        px = color1;
+      } else {
+        px = color2;
       }
-    }
+    });
   }
 
   inline void DrawSecondBlobList(const BlobList &blob_list, PixelRef color1,
                                  PixelRef color2, PixelRef prev_color) {
-    ImagePtr ptr = img();
-    for (const auto &blob : blob_list) {
-      for (int i = 0; i < (int)blob.ranges().size(); ++i) {
-        for (const auto &range : blob.ranges()[i]) {
-          for (int j = range.st; j < range.ed; ++j) {
-            auto px = ptr.get_px(j, i + blob.min_y());
-            if (px.r == prev_color.r && px.g == prev_color.g &&
-                px.b == prev_color.b) {
-              ptr.get_px(j, i + blob.min_y()) = color2;
-            } else {
-              ptr.get_px(j, i + blob.min_y()) = color1;
-            }
-          }
-        }
+    ForPxInBlobList(blob_list, [&](PixelRef &px) {
+      if (px.r == prev_color.r && px.g == prev_color.g &&
+          px.b == prev_color.b) {
+        px = color2;
+      } else {
+        px = color1;
       }
-    }
+    });
   }
 
   // Backwards compatible.