diff options
author | dan sinclair <dj2@everburning.com> | 2019-02-20 15:47:49 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-02-20 15:47:49 -0500 |
commit | ec5f9d42e67216cd1a2030a4f9dc392a6808ddf7 (patch) | |
tree | 1aff02df96886b25a7c8b436f99457f25ec428e6 /samples | |
parent | ff296ea40354da2f891b27dbd52a3d1685e31d8b (diff) | |
download | amber-ec5f9d42e67216cd1a2030a4f9dc392a6808ddf7.tar.gz |
Add image dump in PNG (#302)
This change adds support to dump image to PNG format, it relies on the
third party 'lodepng' library (zlib license).
This CL is based on Pull #301 by @hevrard.
Diffstat (limited to 'samples')
-rw-r--r-- | samples/Android.mk | 5 | ||||
-rw-r--r-- | samples/CMakeLists.txt | 3 | ||||
-rw-r--r-- | samples/amber.cc | 16 | ||||
-rw-r--r-- | samples/png.cc | 76 | ||||
-rw-r--r-- | samples/png.h | 36 | ||||
-rw-r--r-- | samples/ppm.h | 2 |
6 files changed, 131 insertions, 7 deletions
diff --git a/samples/Android.mk b/samples/Android.mk index 9d8033e..06f5fe9 100644 --- a/samples/Android.mk +++ b/samples/Android.mk @@ -22,11 +22,12 @@ LOCAL_SRC_FILES:= \ config_helper.cc \ config_helper_vulkan.cc \ log.cc \ - ppm.cc + ppm.cc \ + png.cc LOCAL_C_INCLUDES := $(LOCAL_PATH)/.. $(LOCAL_PATH)/../include LOCAL_LDLIBS:=-landroid -lvulkan -llog LOCAL_CXXFLAGS:=-std=c++11 -fno-exceptions -fno-rtti -Werror -Wno-unknown-pragmas -DAMBER_ENGINE_VULKAN=1 -LOCAL_STATIC_LIBRARIES:=amber +LOCAL_STATIC_LIBRARIES:=amber lodepng include $(BUILD_EXECUTABLE) include $(LOCAL_PATH)/../Android.mk diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index c71291a..77e1da7 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -19,10 +19,11 @@ set(AMBER_SOURCES config_helper.cc log.cc ppm.cc + png.cc ${CMAKE_BINARY_DIR}/src/build-versions.h.fake ) -set(AMBER_EXTRA_LIBS "") +set(AMBER_EXTRA_LIBS "lodepng") if (${Vulkan_FOUND}) set(AMBER_SOURCES ${AMBER_SOURCES} config_helper_vulkan.cc) diff --git a/samples/amber.cc b/samples/amber.cc index 33fcf70..012f273 100644 --- a/samples/amber.cc +++ b/samples/amber.cc @@ -24,6 +24,7 @@ #include "amber/amber.h" #include "amber/recipe.h" #include "samples/config_helper.h" +#include "samples/png.h" #include "samples/ppm.h" #include "src/build-versions.h" #include "src/make_unique.h" @@ -56,7 +57,7 @@ const char kUsage[] = R"(Usage: amber [options] SCRIPT [SCRIPTS...] -s -- Print summary of pass/failure. -d -- Disable validation layers. -t <spirv_env> -- The target SPIR-V environment. Defaults to SPV_ENV_UNIVERSAL_1_0. - -i <filename> -- Write rendering to <filename> as a PPM image. + -i <filename> -- Write rendering to <filename> as a PNG image if it ends with '.png', or as a PPM image otherwise. -b <filename> -- Write contents of a UBO or SSBO to <filename>. -B [<desc set>:]<binding> -- Descriptor set and binding of buffer to write. Default is [0:]0. @@ -330,10 +331,19 @@ int main(int argc, const char** argv) { if (!options.image_filename.empty()) { std::string image; + + auto pos = options.image_filename.find_last_of('.'); + bool usePNG = pos != std::string::npos && + options.image_filename.substr(pos + 1) == "png"; for (amber::BufferInfo buffer_info : amber_options.extractions) { if (buffer_info.buffer_name == "framebuffer") { - std::tie(result, image) = ppm::ConvertToPPM( - buffer_info.width, buffer_info.height, buffer_info.values); + if (usePNG) { + std::tie(result, image) = png::ConvertToPNG( + buffer_info.width, buffer_info.height, buffer_info.values); + } else { + std::tie(result, image) = ppm::ConvertToPPM( + buffer_info.width, buffer_info.height, buffer_info.values); + } break; } } diff --git a/samples/png.cc b/samples/png.cc new file mode 100644 index 0000000..79c6983 --- /dev/null +++ b/samples/png.cc @@ -0,0 +1,76 @@ +// Copyright 2019 The Amber Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "samples/png.h" + +#include <cassert> + +#include "amber/result.h" +#include "amber/value.h" + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wweak-vtables" +#include "third_party/lodepng/lodepng.h" +#pragma clang diagnostic pop + +namespace png { + +namespace { + +unsigned char byte0(uint32_t word) { + return static_cast<unsigned char>(word); +} + +unsigned char byte1(uint32_t word) { + return static_cast<unsigned char>(word >> 8); +} + +unsigned char byte2(uint32_t word) { + return static_cast<unsigned char>(word >> 16); +} + +unsigned char byte3(uint32_t word) { + return static_cast<unsigned char>(word >> 24); +} + +} // namespace + +std::pair<amber::Result, std::string> ConvertToPNG( + uint32_t width, + uint32_t height, + const std::vector<amber::Value>& values) { + assert(values.size() == width * height); + + std::vector<unsigned char> data; + + // Prepare data as lodepng expects it + for (amber::Value value : values) { + const uint32_t pixel = value.AsUint32(); + data.push_back(byte2(pixel)); // R + data.push_back(byte1(pixel)); // G + data.push_back(byte0(pixel)); // B + data.push_back(byte3(pixel)); // A + } + + std::vector<unsigned char> png; + unsigned error = lodepng::encode(png, data, width, height); + if (error) { + return std::make_pair(amber::Result("lodepng::encode() returned non-zero"), + nullptr); + } + + return std::make_pair(amber::Result(), std::string(png.begin(), png.end())); +} + +} // namespace png diff --git a/samples/png.h b/samples/png.h new file mode 100644 index 0000000..2008e9e --- /dev/null +++ b/samples/png.h @@ -0,0 +1,36 @@ +// Copyright 2019 The Amber Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SAMPLES_PNG_H_ +#define SAMPLES_PNG_H_ + +#include <string> +#include <utility> +#include <vector> + +#include "amber/amber.h" + +namespace png { + +/// Converts the image of dimensions |width| and |height| and with pixels stored +/// in row-major order in |values| with format B8G8R8A8 into PNG format, +/// returning the PNG binary as a string. +std::pair<amber::Result, std::string> ConvertToPNG( + uint32_t width, + uint32_t height, + const std::vector<amber::Value>& values); + +} // namespace png + +#endif // SAMPLES_PNG_H_ diff --git a/samples/ppm.h b/samples/ppm.h index 0eb1f8e..9b237f3 100644 --- a/samples/ppm.h +++ b/samples/ppm.h @@ -24,7 +24,7 @@ namespace ppm { /// Converts the image of dimensions |width| and |height| and with pixels stored -/// in row-major order in |values| with format R8G8B8A8 into PPM format, +/// in row-major order in |values| with format B8G8R8A8 into PPM format, /// returning the PPM binary as a string. std::pair<amber::Result, std::string> ConvertToPPM( uint32_t width, |