1// Copyright 2019 The Amber Authors. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15#include "samples/ppm.h" 16 17#include <cassert> 18 19#include "amber/result.h" 20#include "amber/value.h" 21 22namespace ppm { 23namespace { 24 25const uint32_t kMaximumColorValue = 255; 26 27uint8_t byte0(uint32_t word) { 28 return static_cast<uint8_t>(word & 0xff); 29} 30 31uint8_t byte1(uint32_t word) { 32 return static_cast<uint8_t>((word >> 8) & 0xff); 33} 34 35uint8_t byte2(uint32_t word) { 36 return static_cast<uint8_t>((word >> 16) & 0xff); 37} 38 39} // namespace 40 41amber::Result ConvertToPPM(uint32_t width, 42 uint32_t height, 43 const std::vector<amber::Value>& values, 44 std::vector<uint8_t>* buffer) { 45 assert(values.size() == (width * height) && 46 "Buffer values != width * height"); 47 assert(!values.empty() && "Buffer empty"); 48 49 // Write PPM header 50 std::string image = "P6\n"; 51 image += std::to_string(width) + " " + std::to_string(height) + "\n"; 52 image += std::to_string(kMaximumColorValue) + "\n"; 53 54 for (char ch : image) 55 buffer->push_back(static_cast<uint8_t>(ch)); 56 57 // Write PPM data 58 for (amber::Value value : values) { 59 const uint32_t pixel = value.AsUint32(); 60 // We assume B8G8R8A8_UNORM here: 61 buffer->push_back(byte2(pixel)); // R 62 buffer->push_back(byte1(pixel)); // G 63 buffer->push_back(byte0(pixel)); // B 64 // PPM does not support alpha channel 65 } 66 67 return {}; 68} 69 70} // namespace ppm 71