#ifndef __MODE_H__
#define __MODE_H__

typedef enum {
    IMAGING_MODE_UNKNOWN,

    IMAGING_MODE_1,
    IMAGING_MODE_CMYK,
    IMAGING_MODE_F,
    IMAGING_MODE_HSV,
    IMAGING_MODE_I,
    IMAGING_MODE_L,
    IMAGING_MODE_LA,
    IMAGING_MODE_LAB,
    IMAGING_MODE_La,
    IMAGING_MODE_P,
    IMAGING_MODE_PA,
    IMAGING_MODE_RGB,
    IMAGING_MODE_RGBA,
    IMAGING_MODE_RGBX,
    IMAGING_MODE_RGBa,
    IMAGING_MODE_YCbCr,

    IMAGING_MODE_I_16,
    IMAGING_MODE_I_16L,
    IMAGING_MODE_I_16B,
    IMAGING_MODE_I_16N,
} ModeID;

typedef struct {
    const char *const name;
} ModeData;

const ModeID
findModeID(const char *const name);
const ModeData *const
getModeData(const ModeID id);

typedef enum {
    IMAGING_RAWMODE_UNKNOWN,

    // Non-rawmode aliases.
    IMAGING_RAWMODE_1,
    IMAGING_RAWMODE_CMYK,
    IMAGING_RAWMODE_F,
    IMAGING_RAWMODE_HSV,
    IMAGING_RAWMODE_I,
    IMAGING_RAWMODE_L,
    IMAGING_RAWMODE_LA,
    IMAGING_RAWMODE_LAB,
    IMAGING_RAWMODE_La,
    IMAGING_RAWMODE_P,
    IMAGING_RAWMODE_PA,
    IMAGING_RAWMODE_RGB,
    IMAGING_RAWMODE_RGBA,
    IMAGING_RAWMODE_RGBX,
    IMAGING_RAWMODE_RGBa,
    IMAGING_RAWMODE_YCbCr,

    // I;* modes.
    IMAGING_RAWMODE_I_16,
    IMAGING_RAWMODE_I_16L,
    IMAGING_RAWMODE_I_16B,
    IMAGING_RAWMODE_I_16N,

    // Rawmodes
    IMAGING_RAWMODE_1_8,
    IMAGING_RAWMODE_1_I,
    IMAGING_RAWMODE_1_IR,
    IMAGING_RAWMODE_1_R,
    IMAGING_RAWMODE_A,
    IMAGING_RAWMODE_ABGR,
    IMAGING_RAWMODE_ARGB,
    IMAGING_RAWMODE_A_16B,
    IMAGING_RAWMODE_A_16L,
    IMAGING_RAWMODE_A_16N,
    IMAGING_RAWMODE_B,
    IMAGING_RAWMODE_BGAR,
    IMAGING_RAWMODE_BGR,
    IMAGING_RAWMODE_BGRA,
    IMAGING_RAWMODE_BGRA_15,
    IMAGING_RAWMODE_BGRA_15Z,
    IMAGING_RAWMODE_BGRA_16B,
    IMAGING_RAWMODE_BGRA_16L,
    IMAGING_RAWMODE_BGRX,
    IMAGING_RAWMODE_BGR_5,
    IMAGING_RAWMODE_BGR_15,
    IMAGING_RAWMODE_BGR_16,
    IMAGING_RAWMODE_BGRa,
    IMAGING_RAWMODE_BGXR,
    IMAGING_RAWMODE_B_16B,
    IMAGING_RAWMODE_B_16L,
    IMAGING_RAWMODE_B_16N,
    IMAGING_RAWMODE_C,
    IMAGING_RAWMODE_CMYKX,
    IMAGING_RAWMODE_CMYKXX,
    IMAGING_RAWMODE_CMYK_16B,
    IMAGING_RAWMODE_CMYK_16L,
    IMAGING_RAWMODE_CMYK_16N,
    IMAGING_RAWMODE_CMYK_I,
    IMAGING_RAWMODE_CMYK_L,
    IMAGING_RAWMODE_C_I,
    IMAGING_RAWMODE_Cb,
    IMAGING_RAWMODE_Cr,
    IMAGING_RAWMODE_I_32B,
    IMAGING_RAWMODE_F_16,
    IMAGING_RAWMODE_F_16B,
    IMAGING_RAWMODE_F_16BS,
    IMAGING_RAWMODE_F_16N,
    IMAGING_RAWMODE_F_16NS,
    IMAGING_RAWMODE_F_16S,
    IMAGING_RAWMODE_F_32,
    IMAGING_RAWMODE_F_32B,
    IMAGING_RAWMODE_F_32BF,
    IMAGING_RAWMODE_F_32BS,
    IMAGING_RAWMODE_F_32F,
    IMAGING_RAWMODE_F_32N,
    IMAGING_RAWMODE_F_32NF,
    IMAGING_RAWMODE_F_32NS,
    IMAGING_RAWMODE_F_32S,
    IMAGING_RAWMODE_F_64BF,
    IMAGING_RAWMODE_F_64F,
    IMAGING_RAWMODE_F_64NF,
    IMAGING_RAWMODE_F_8,
    IMAGING_RAWMODE_F_8S,
    IMAGING_RAWMODE_G,
    IMAGING_RAWMODE_G_16B,
    IMAGING_RAWMODE_G_16L,
    IMAGING_RAWMODE_G_16N,
    IMAGING_RAWMODE_H,
    IMAGING_RAWMODE_I_12,
    IMAGING_RAWMODE_I_16BS,
    IMAGING_RAWMODE_I_16NS,
    IMAGING_RAWMODE_I_16R,
    IMAGING_RAWMODE_I_16S,
    IMAGING_RAWMODE_I_32,
    IMAGING_RAWMODE_I_32BS,
    IMAGING_RAWMODE_I_32N,
    IMAGING_RAWMODE_I_32NS,
    IMAGING_RAWMODE_I_32S,
    IMAGING_RAWMODE_I_8,
    IMAGING_RAWMODE_I_8S,
    IMAGING_RAWMODE_K,
    IMAGING_RAWMODE_K_I,
    IMAGING_RAWMODE_LA_16B,
    IMAGING_RAWMODE_LA_L,
    IMAGING_RAWMODE_L_16,
    IMAGING_RAWMODE_L_16B,
    IMAGING_RAWMODE_L_2,
    IMAGING_RAWMODE_L_2I,
    IMAGING_RAWMODE_L_2IR,
    IMAGING_RAWMODE_L_2R,
    IMAGING_RAWMODE_L_4,
    IMAGING_RAWMODE_L_4I,
    IMAGING_RAWMODE_L_4IR,
    IMAGING_RAWMODE_L_4R,
    IMAGING_RAWMODE_L_I,
    IMAGING_RAWMODE_L_R,
    IMAGING_RAWMODE_M,
    IMAGING_RAWMODE_M_I,
    IMAGING_RAWMODE_PA_L,
    IMAGING_RAWMODE_PX,
    IMAGING_RAWMODE_P_1,
    IMAGING_RAWMODE_P_2,
    IMAGING_RAWMODE_P_2L,
    IMAGING_RAWMODE_P_4,
    IMAGING_RAWMODE_P_4L,
    IMAGING_RAWMODE_P_R,
    IMAGING_RAWMODE_R,
    IMAGING_RAWMODE_RGBAX,
    IMAGING_RAWMODE_RGBAXX,
    IMAGING_RAWMODE_RGBA_15,
    IMAGING_RAWMODE_RGBA_16B,
    IMAGING_RAWMODE_RGBA_16L,
    IMAGING_RAWMODE_RGBA_16N,
    IMAGING_RAWMODE_RGBA_4B,
    IMAGING_RAWMODE_RGBA_I,
    IMAGING_RAWMODE_RGBA_L,
    IMAGING_RAWMODE_RGBXX,
    IMAGING_RAWMODE_RGBXXX,
    IMAGING_RAWMODE_RGBX_16B,
    IMAGING_RAWMODE_RGBX_16L,
    IMAGING_RAWMODE_RGBX_16N,
    IMAGING_RAWMODE_RGBX_L,
    IMAGING_RAWMODE_RGB_15,
    IMAGING_RAWMODE_RGB_16,
    IMAGING_RAWMODE_RGB_16B,
    IMAGING_RAWMODE_RGB_16L,
    IMAGING_RAWMODE_RGB_16N,
    IMAGING_RAWMODE_RGB_4B,
    IMAGING_RAWMODE_RGB_L,
    IMAGING_RAWMODE_RGB_R,
    IMAGING_RAWMODE_RGBaX,
    IMAGING_RAWMODE_RGBaXX,
    IMAGING_RAWMODE_RGBa_16B,
    IMAGING_RAWMODE_RGBa_16L,
    IMAGING_RAWMODE_RGBa_16N,
    IMAGING_RAWMODE_R_16B,
    IMAGING_RAWMODE_R_16L,
    IMAGING_RAWMODE_R_16N,
    IMAGING_RAWMODE_S,
    IMAGING_RAWMODE_V,
    IMAGING_RAWMODE_X,
    IMAGING_RAWMODE_XBGR,
    IMAGING_RAWMODE_XRGB,
    IMAGING_RAWMODE_Y,
    IMAGING_RAWMODE_YCCA_P,
    IMAGING_RAWMODE_YCC_P,
    IMAGING_RAWMODE_YCbCrK,
    IMAGING_RAWMODE_YCbCrX,
    IMAGING_RAWMODE_YCbCr_L,
    IMAGING_RAWMODE_Y_I,
    IMAGING_RAWMODE_aBGR,
    IMAGING_RAWMODE_aRGB,
} RawModeID;

typedef struct {
    const char *const name;
} RawModeData;

const RawModeID
findRawModeID(const char *const name);
const RawModeData *const
getRawModeData(const RawModeID id);

int
isModeI16(const ModeID mode);

#endif  // __MODE_H__
