• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
22 namespace ppm {
23 namespace {
24 
25 const uint32_t kMaximumColorValue = 255;
26 
byte0(uint32_t word)27 uint8_t byte0(uint32_t word) {
28   return static_cast<uint8_t>(word & 0xff);
29 }
30 
byte1(uint32_t word)31 uint8_t byte1(uint32_t word) {
32   return static_cast<uint8_t>((word >> 8) & 0xff);
33 }
34 
byte2(uint32_t word)35 uint8_t byte2(uint32_t word) {
36   return static_cast<uint8_t>((word >> 16) & 0xff);
37 }
38 
39 }  // namespace
40 
ConvertToPPM(uint32_t width,uint32_t height,const std::vector<amber::Value> & values,std::vector<uint8_t> * buffer)41 amber::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