#pragma once
#include <csetjmp>
#include "common.hpp"
extern "C" {
#include <jpeglib.h>
}
#include "image.hpp"


template <class T> class JpegErrorMgr {
    private:
        typedef struct {
            struct jpeg_error_mgr pub; // first member
            jmp_buf setjmp_buffer;
        } ctx_t;

        static void jpeg_create(jpeg_compress_struct* cinfo) { jpeg_create_compress(cinfo); }
        static void jpeg_create(jpeg_decompress_struct* cinfo) { jpeg_create_decompress(cinfo); }
        static void jpeg_destroy(jpeg_compress_struct* cinfo) { jpeg_destroy_compress(cinfo); }
        static void jpeg_destroy(jpeg_decompress_struct* cinfo) { jpeg_destroy_decompress(cinfo); }

        static void error_exit(j_common_ptr);

    public:
        typedef bool (*handler_t)(T&, void*);
        static bool handle(handler_t, void*);
};


class JpegImage {
    private:
        typedef struct {
            FILE* fp;
            union {
                Image* in;
                const Image* out;
            } im;
        } args_t;

        static bool jpeg_read(jpeg_decompress_struct&, void*);
        static bool jpeg_write(jpeg_compress_struct&, void*);

    public:
        static Image* in(const char*);
        static bool out(const char*, const Image*);
};