/*
 * Copyright 2023 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 "risp4ml/common/image.h"

#include <stdlib.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);
}
