| // Copyright 2019 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "image_io_util.h" |
| |
| #include <lib/fzl/vmo-mapper.h> |
| #include <lib/syslog/cpp/macros.h> |
| |
| #include <vector> |
| |
| #include "src/lib/files/directory.h" |
| #include "src/lib/files/file.h" |
| #include "src/lib/files/path.h" |
| |
| namespace camera { |
| |
| fit::result<std::unique_ptr<ImageIOUtil>, zx_status_t> ImageIOUtil::Create( |
| fuchsia::sysmem::BufferCollectionInfo_2* buffer_collection, const std::string& dir_path) { |
| if (buffer_collection->buffer_count <= 0) { |
| FX_LOGS(DEBUG) << "Failed to create ImageIOUtil with empty BufferCollection."; |
| return fit::error(ZX_ERR_INVALID_ARGS); |
| } |
| |
| fuchsia::sysmem::BufferCollectionInfo_2 buffer_collection_clone; |
| zx_status_t status = buffer_collection->Clone(&buffer_collection_clone); |
| if (status != ZX_OK) { |
| FX_LOGS(ERROR) << "Failed to clone BufferCollection."; |
| return fit::error(status); |
| } |
| auto stream_io = std::make_unique<ImageIOUtil>(std::move(buffer_collection_clone), dir_path); |
| |
| if (!files::CreateDirectory(stream_io->GetDirpath())) { |
| FX_LOGS(ERROR) << "Failed to create on-disk directory to write to."; |
| return fit::error(ZX_ERR_IO); |
| } |
| |
| return fit::ok(std::move(stream_io)); |
| } |
| |
| // TODO(nzo): add functionality to ensure all previously written images (i.e. before this |
| // ImageIOUtil was created) are also deleted. |
| zx_status_t ImageIOUtil::DeleteImageData() { |
| bool delete_status = true; |
| if (dir_path_.empty()) { |
| for (uint32_t i = 0; i < num_image_; ++i) { |
| delete_status &= files::DeletePath(GetFilepath(i), false); |
| } |
| } else { |
| delete_status = files::DeletePath(GetDirpath(), true); |
| } |
| |
| return delete_status ? ZX_OK : ZX_ERR_IO; |
| } |
| |
| zx_status_t ImageIOUtil::WriteImageData(uint32_t id) { |
| if (id >= buffer_collection_.buffer_count) { |
| FX_LOGS(ERROR) << "An invalid buffer id was passed in."; |
| return ZX_ERR_INVALID_ARGS; |
| } |
| // TODO(nzo): change this to use information from ImageFormat_2 instead. |
| size_t num_bytes = buffer_collection_.settings.buffer_settings.size_bytes; |
| |
| fzl::VmoMapper mapper; |
| zx_status_t status = |
| mapper.Map(buffer_collection_.buffers[id].vmo, 0, num_bytes, ZX_VM_PERM_READ); |
| if (status != ZX_OK) { |
| FX_LOGS(ERROR) << "Failed to map vmo."; |
| return status; |
| } |
| |
| if (!files::WriteFile(GetFilepath(num_image_), static_cast<const char*>(mapper.start()), |
| num_bytes)) { |
| FX_LOGS(ERROR) << "Failed to write to file on disk."; |
| return ZX_ERR_IO; |
| } |
| |
| FX_LOGS(INFO) << "Image written to disk.\n Run `fx scp " << GetFilepath(num_image_) |
| << " ~/[HOST DESTINATION]` to transfer the file from device."; |
| ++num_image_; |
| |
| return ZX_OK; |
| } |
| |
| } // namespace camera |