// 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 "src/camera/lib/image_utils/raw12_writer.h"

#include <lib/syslog/cpp/macros.h>

#include <array>
#include <vector>

namespace camera {

// Helper methods.
std::array<uint8_t, kBytesPerDoublePixel> PixelValuesToDoublePixel(uint16_t first_pixel_val,
                                                                   uint16_t second_pixel_val) {
  return std::array<uint8_t, kBytesPerDoublePixel>(
      {static_cast<uint8_t>(((first_pixel_val & kHighByteMask) >> kHalfByteShift)),
       static_cast<uint8_t>(((second_pixel_val & kHighByteMask) >> kHalfByteShift)),
       static_cast<uint8_t>((((second_pixel_val & kLowHalfByteMask) << kHalfByteShift) |
                             (first_pixel_val & kLowHalfByteMask)))});
}

std::pair<uint16_t, uint16_t> DoublePixelToPixelValues(
    std::array<uint8_t, kBytesPerDoublePixel> double_pixel) {
  return std::pair(
      (double_pixel[0] << kHalfByteShift) | (double_pixel[2] & kLowHalfByteMask),
      (double_pixel[1] << kHalfByteShift) | ((double_pixel[2] & kHighByteMask) >> kHalfByteShift));
}

// RAW12 Writer methods.
fpromise::result<std::unique_ptr<Raw12Writer>, zx_status_t> Raw12Writer::Create(uint32_t width,
                                                                                uint32_t height) {
  // TODO(nzo): consider if there's a case where odd width/height would be necessary.
  if (!(width > 0 && height > 0)) {
    FX_LOGS(DEBUG) << "Invalid dimensions passed in.";
    return fpromise::error(ZX_ERR_INVALID_ARGS);
  }
  const size_t kSize = width * height * kBytesPerDoublePixel;
  return fpromise::ok(std::make_unique<Raw12Writer>(width, height, kSize));
}

zx_status_t Raw12Writer::Write(zx::vmo* vmo, uint16_t r, uint16_t g, uint16_t b) {
  zx_status_t status = zx::vmo::create(vmo_size(), 0, vmo);
  if (status != ZX_OK) {
    FX_LOGS(ERROR) << "Failed to create VMO.";
    return status;
  }

  std::array<uint8_t, kBytesPerDoublePixel> double_pixel_val;

  auto buf = std::vector<uint8_t>(vmo_size(), 0);

  // Value for colors on the first column/row will be zero, increase by constant factor up to
  // maximum value for every column/row after that.
  const uint16_t kGreenStepFactor = (height() == 1) ? 0 : b / (height() - 1);
  const uint16_t kBlueStepFactor = (width() == 1) ? 0 : g / (width() - 1);
  uint16_t green_pixel = 0;
  uint16_t blue_pixel = 0;

  uint32_t row_num = 0;

  for (uint32_t i = 0; i < vmo_size(); i += kBytesPerDoublePixel) {
    if ((i != 0) && (i % (width() * kBytesPerDoublePixel) == 0)) {
      row_num++;
      green_pixel += kGreenStepFactor;
      blue_pixel = 0;
    }

    double_pixel_val = (row_num % 2 == 0) ? PixelValuesToDoublePixel(r, green_pixel)
                                          : PixelValuesToDoublePixel(green_pixel, blue_pixel);
    buf[i] = double_pixel_val[0];
    buf[i + 1] = double_pixel_val[1];
    buf[i + 2] = double_pixel_val[2];

    blue_pixel += kBlueStepFactor;
  }

  status = vmo->write(&buf.front(), 0, buf.size());
  if (status != ZX_OK) {
    FX_LOGS(ERROR) << "Failed to write to VMO.";
    return status;
  }

  return ZX_OK;
}

}  // namespace camera
