#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmissing-declarations"
#include "libs/lodepng/lodepng.h"
#pragma GCC diagnostic pop

#include <stdlib.h>

#include "io/ImageReader.h"
#include "utils/Cleaner.h"

void ImageReader::Image::clean(ColorChannel*& c) {
    free(c);
}

static void cleanRawData(ColorChannel*& c) {
    free(c);
}

static void cleanState(LodePNGState& state) {
    lodepng_state_cleanup(&state);
}

ImageReader::Image::Image() : data(nullptr) {
}

Error ImageReader::load(Image& image, const char* path) {
    Cleaner<ColorChannel*, cleanRawData> rawData(nullptr);
    size_t rawSize;
    unsigned int error = lodepng_load_file(&rawData, &rawSize, path);
    if(error) {
        Error e{"cannot load file '"};
        e.message.append(path).append("': ").append(lodepng_error_text(error));
        return e;
    }
    Cleaner<LodePNGState, cleanState> state;
    lodepng_state_init(&state);
    state->decoder.color_convert = false;
    error = lodepng_decode(&image.data, &image.width, &image.height, &state,
                           rawData, rawSize);
    if(error) {
        Error e{"cannot decode file '"};
        e.message.append(path).append("'").append(lodepng_error_text(error));
        return e;
    }
    image.channels = lodepng_get_channels(&state->info_png.color);
    image.bitdepth = state->info_png.color.bitdepth;
    return {};
}