// 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/hsv_generator.h"

#include <lib/image-format/image_format.h>
#include <lib/syslog/cpp/macros.h>
#include <zircon/assert.h>
#include <zircon/syscalls.h>

#include <array>
#include <iostream>

#include "src/camera/lib/image_utils/color_source.h"
#include "src/camera/lib/image_utils/image_format_rgba.h"

namespace camera {

constexpr uint8_t kTwoByteShift = 16;
constexpr uint8_t kOneByteShift = 8;
// Set the alpha value to 100%:
constexpr uint8_t kAlphaValue = 0xff;
constexpr uint8_t kOneByteMask = 0xff;
constexpr uint64_t kTwoByteMask = 0xffff;

// Write an image plane whose pixels are 2^n bytes wide.
template <class PixelSize>
void WriteByteAligned(void* start, PixelSize value, uint32_t width, uint32_t height,
                      uint32_t stride) {
  auto* pixels = reinterpret_cast<PixelSize*>(start);
  for (uint32_t row = 0; row < height; ++row) {
    for (uint32_t col = 0; col < width; ++col) {
      pixels[row * stride / sizeof(value) + col] = value;
    }
  }
}

void WriteSingleColorImage(Rgba rgba, const fuchsia::sysmem::ImageFormat_2& format, void* buffer) {
  // Check if valid format
  uint32_t packed_value = RgbaPack(format.pixel_format.type, rgba);
  auto pixel_format_c = ConvertPixelFormatToC(format.pixel_format);
  uint32_t bytes_per_pixel = ImageFormatBitsPerPixel(&pixel_format_c) / 8;

  if (bytes_per_pixel == 4) {
    WriteByteAligned(buffer, packed_value, format.coded_width, format.coded_height,
                     format.bytes_per_row);
  }
  // 24 bit formats need to be handles specially, because we don't have a uint24_t:
  if (bytes_per_pixel == 3) {
    auto* pixels = reinterpret_cast<uint8_t*>(buffer);
    uint8_t color1 = packed_value >> kTwoByteShift & kOneByteMask;
    uint8_t color2 = packed_value >> kOneByteShift & kOneByteMask;
    uint8_t color3 = packed_value & kOneByteMask;
    for (uint32_t row = 0; row < format.coded_height; ++row) {
      for (uint32_t col = 0; col < format.coded_width; ++col) {
        uint32_t start = row * format.bytes_per_row + col * bytes_per_pixel;
        pixels[start] = color1;
        pixels[start + 1] = color2;
        pixels[start + 2] = color3;
      }
    }
  }
  if (bytes_per_pixel == 2) {
    uint16_t color = packed_value & kTwoByteMask;
    WriteByteAligned(buffer, color, format.coded_width, format.coded_height, format.bytes_per_row);
  }
  if (bytes_per_pixel == 1) {
    uint8_t color = packed_value & kOneByteMask;
    WriteByteAligned(buffer, color, format.coded_width, format.coded_height, format.bytes_per_row);
  }
}

zx_status_t HsvGenerator(void* start, const fuchsia::sysmem::ImageFormat_2& format,
                         uint32_t frame_index) {
  // Currently only support RGB colors
  if (!IsSupportedPixelFormat(format.pixel_format.type)) {
    FX_LOGS(ERROR) << "Unsupported format";
    return ZX_ERR_INVALID_ARGS;
  }
  // Get the color:
  Rgba color;
  ColorSource::hsv_color(frame_index, &color.r, &color.g, &color.b);
  color.a = kAlphaValue;
  WriteSingleColorImage(color, format, start);
  return ZX_OK;
}

}  // namespace camera
