/*
 * Copyright 2022 Google LLC
 *
 * 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 <stdlib.h>

#include "samples/risp4ml/common/image.h"

Image* image_new(uint16_t num_channels, uint16_t height, uint16_t width) {
  Image* image = (Image*)malloc(sizeof(Image));
  if (image) {
    image->num_channels = num_channels;
    image->height = height;
    image->width = width;
    uint32_t num_pixels = width * height * num_channels;
    image->data = (pixel_type_t*)malloc(num_pixels * sizeof(pixel_type_t));
  }
  return image;
}

void image_delete(Image* image) {
  if (image) {
    if (image->data) free(image->data);
    free(image);
  }
}

pixel_type_t* image_pixel(Image* image, uint16_t c, uint16_t y, uint16_t x) {
  const uint32_t stride_c = image->width * image->height;
  const uint16_t stride_y = image->width;
  const uint16_t stride_x = 1;
  return (image->data + c * stride_c + y * stride_y + x * stride_x);
}

pixel_type_t* image_row(Image* image, uint16_t c, uint16_t y) {
  const uint32_t stride_c = image->width * image->height;
  const uint16_t stride_y = image->width;
  return (image->data + c * stride_c + y * stride_y);
}
