#include <stdio.h>
#include <stdlib.h>
#include <jpeglib.h>
#include <libheif/heif.h>

int main(int argc, char *argv[]) {
    if (argc != 3) {
        fprintf(stderr, "Usage: %s input.heic output.jpg\n", argv[0]);
        return 1;
    }
    const char *infile = argv[1];
    const char *outfile = argv[2];

    struct heif_context *ctx = heif_context_alloc();
    struct heif_error err;

    err = heif_context_read_from_file(ctx, infile, NULL);
    if (err.code != heif_error_Ok) {
        fprintf(stderr, "Failed to read HEIC file '%s': %s\n", infile, err.message);
        heif_context_free(ctx);
        return 1;
    }

    struct heif_image_handle *handle;
    err = heif_context_get_primary_image_handle(ctx, &handle);
    if (err.code != heif_error_Ok) {
        fprintf(stderr, "Failed to get primary image handle: %s\n", err.message);
        heif_context_free(ctx);
        return 1;
    }

    struct heif_image *img;
    struct heif_decoding_options *dec_opts = heif_decoding_options_alloc();
    err = heif_decode_image(handle, &img, heif_colorspace_RGB, heif_chroma_interleaved_RGB, dec_opts);
    heif_decoding_options_free(dec_opts);
    if (err.code != heif_error_Ok) {
        fprintf(stderr, "Failed to decode image: %s\n", err.message);
        heif_image_handle_release(handle);
        heif_context_free(ctx);
        return 1;
    }

    int width = heif_image_get_width(img, heif_channel_interleaved);
    int height = heif_image_get_height(img, heif_channel_interleaved);
    int stride;
    const uint8_t *data = heif_image_get_plane(img, heif_channel_interleaved, &stride);

    FILE *out = fopen(outfile, "wb");
    if (!out) {
        perror("fopen");
        heif_image_release(img);
        heif_image_handle_release(handle);
        heif_context_free(ctx);
        return 1;
    }

    struct jpeg_compress_struct cinfo;
    struct jpeg_error_mgr jerr;
    cinfo.err = jpeg_std_error(&jerr);
    jpeg_create_compress(&cinfo);
    jpeg_stdio_dest(&cinfo, out);

    cinfo.image_width = width;
    cinfo.image_height = height;
    cinfo.input_components = 3;
    cinfo.in_color_space = JCS_RGB;
    jpeg_set_defaults(&cinfo);
    jpeg_set_quality(&cinfo, 90, TRUE);
    jpeg_start_compress(&cinfo, TRUE);

    while (cinfo.next_scanline < cinfo.image_height) {
        JSAMPROW row_pointer = (JSAMPROW)(data + cinfo.next_scanline * stride);
        jpeg_write_scanlines(&cinfo, &row_pointer, 1);
    }

    jpeg_finish_compress(&cinfo);
    jpeg_destroy_compress(&cinfo);
    fclose(out);

    heif_image_release(img);
    heif_image_handle_release(handle);
    heif_context_free(ctx);
    return 0;
}
