// Módulo de imágenes en escala de grises, en formato PGM de texto (P2).
// Ahora sin tamaño máximo: cada imagen ocupa dos bloques del heap.
#ifndef IMAGE_H
#define IMAGE_H

#define IMAGE_MAX_VALUE 255

// pixels apunta a width * height enteros, fila por fila: el píxel de la fila y y la
// columna x es pixels[y * width + x]. Cada uno vale de 0 (negro) a max_value (blanco).
struct image {
    int width;
    int height;
    int max_value;
    int *pixels;
};

// Las tres funciones siguientes devuelven una imagen nueva. Quien llama es su owner y
// debe liberarla con image_free. Si algo falla, devuelven NULL y no queda nada reservado.

// Imagen con todos sus píxeles en value. Falla si algún dato no está en su rango, si
// width * height no cabe en un int o si no hay memoria.
struct image *image_new(int width, int height, int max_value, int value);

// Igual, pero toma los píxeles de values, fila por fila (width * height elementos).
struct image *image_from_values(int width, int height, int max_value, const int *values);

// Lee un archivo PGM de texto. Falla si no se puede abrir, si no es P2, si sus datos
// están mal o si no hay memoria.
struct image *image_load(const char *name);

// Libera la imagen y sus píxeles. Con NULL no hace nada.
void image_free(struct image *img);

// Devuelve 1 si tienen el mismo tamaño, el mismo max_value y los mismos píxeles.
int image_equal(const struct image *a, const struct image *b);

// Escribe la imagen en un archivo PGM de texto. Devuelve 1 si pudo y 0 si no.
int image_save(const struct image *img, const char *name);

// Escribe el tamaño y los números de cada píxel, para imágenes pequeñas.
void image_print(const struct image *img);

// Dibuja la imagen en la terminal con letras: más claro, más lleno.
void image_show(const struct image *img);

#endif
