/*
 * 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 "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);
}
