/*
 * Copyright 2018 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifdef _MSC_VER
    #define _CRT_SECURE_NO_WARNINGS
#endif

#include "skcms.h"
#include "src/PortableMath.h"
#include "src/TransferFunction.h"
#include "test_only.h"
#include <stdlib.h>
#include <string.h>

static void dump_transform_to_XYZD50(FILE* fp, const skcms_ICCProfile* profile) {
    // Here are 252 of a random shuffle of all possible bytes.
    // 252 is evenly divisible by 3 and 4.  Only 192, 10, 241, and 43 are missing.
    static const uint8_t k252_bytes[] = {
        8, 179, 128, 204, 253, 38, 134, 184, 68, 102, 32, 138, 99, 39, 169, 215,
        119, 26, 3, 223, 95, 239, 52, 132, 114, 74, 81, 234, 97, 116, 244, 205, 30,
        154, 173, 12, 51, 159, 122, 153, 61, 226, 236, 178, 229, 55, 181, 220, 191,
        194, 160, 126, 168, 82, 131, 18, 180, 245, 163, 22, 246, 69, 235, 252, 57,
        108, 14, 6, 152, 240, 255, 171, 242, 20, 227, 177, 238, 96, 85, 16, 211,
        70, 200, 149, 155, 146, 127, 145, 100, 151, 109, 19, 165, 208, 195, 164,
        137, 254, 182, 248, 64, 201, 45, 209, 5, 147, 207, 210, 113, 162, 83, 225,
        9, 31, 15, 231, 115, 37, 58, 53, 24, 49, 197, 56, 120, 172, 48, 21, 214,
        129, 111, 11, 50, 187, 196, 34, 60, 103, 71, 144, 47, 203, 77, 80, 232,
        140, 222, 250, 206, 166, 247, 139, 249, 221, 72, 106, 27, 199, 117, 54,
        219, 135, 118, 40, 79, 41, 251, 46, 93, 212, 92, 233, 148, 28, 121, 63,
        123, 158, 105, 59, 29, 42, 143, 23, 0, 107, 176, 87, 104, 183, 156, 193,
        189, 90, 188, 65, 190, 17, 198, 7, 186, 161, 1, 124, 78, 125, 170, 133,
        174, 218, 67, 157, 75, 101, 89, 217, 62, 33, 141, 228, 25, 35, 91, 230, 4,
        2, 13, 73, 86, 167, 237, 84, 243, 44, 185, 66, 130, 110, 150, 142, 216, 88,
        112, 36, 224, 136, 202, 76, 94, 98, 175, 213
    };

    static const skcms_ICCProfile XYZD50 = {
        .buffer           = NULL,
        .size             = 0,
        .data_color_space = 0x52474220, // 'RGB '
        .pcs              = 0x58595A20, // 'XYZ '
        .tag_count        = 0,
        .has_trc          = true,
        .has_toXYZD50     = true,
        .has_A2B          = false,

        .trc = {
            {{{0, {1,1,0,0,0,0,0}}}},
            {{{0, {1,1,0,0,0,0,0}}}},
            {{{0, {1,1,0,0,0,0,0}}}},
        },

        .toXYZD50 = {{
            {1,0,0},
            {0,1,0},
            {0,0,1},
        }},
    };

    // Interpret as RGB_888 if data color space is RGB or GRAY, RGBA_8888 if CMYK.
    skcms_PixelFormat fmt = skcms_PixelFormat_RGB_888;
    size_t npixels = 84;
    if (profile->data_color_space == 0x434D594B/*CMYK*/) {
        fmt = skcms_PixelFormat_RGBA_8888;
        npixels = 63;
    }

    uint8_t dst[252];

    if (!skcms_Transform(k252_bytes,                fmt, skcms_AlphaFormat_Unpremul, profile,
                         dst, skcms_PixelFormat_RGB_888, skcms_AlphaFormat_Unpremul, &XYZD50,
                         npixels)) {
        fprintf(fp, "We can parse this profile, but not transform it XYZD50!\n");
        return;
    }

    fprintf(fp, "252 random bytes transformed to linear XYZD50 bytes:\n");
    // 252 = 3 * 3 * 7 * 4, so we will print either 9 or 12 rows of 7 XYZ values here.
    for (size_t i = 0; i < npixels; i += 7) {
        fprintf(fp, "\t"
                    "%02x%02x%02x %02x%02x%02x %02x%02x%02x %02x%02x%02x "
                    "%02x%02x%02x %02x%02x%02x %02x%02x%02x\n",
                dst[3*i+ 0], dst[3*i+ 1], dst[3*i+ 2],
                dst[3*i+ 3], dst[3*i+ 4], dst[3*i+ 5],
                dst[3*i+ 6], dst[3*i+ 7], dst[3*i+ 8],
                dst[3*i+ 9], dst[3*i+10], dst[3*i+11],
                dst[3*i+12], dst[3*i+13], dst[3*i+14],
                dst[3*i+15], dst[3*i+16], dst[3*i+17],
                dst[3*i+18], dst[3*i+19], dst[3*i+20]);
    }
}


static void signature_to_string(uint32_t sig, char* str) {
    str[0] = (char)((sig >> 24) & 0xFF);
    str[1] = (char)((sig >> 16) & 0xFF);
    str[2] = (char)((sig >>  8) & 0xFF);
    str[3] = (char)((sig >>  0) & 0xFF);
    str[4] = 0;
}

static void dump_sig_field(FILE* fp, const char* name, uint32_t val) {
    char valStr[5];
    signature_to_string(val, valStr);
    fprintf(fp, "%20s : 0x%08X : '%s'\n", name, val, valStr);
}

static bool is_sRGB(const skcms_TransferFunction* tf) {
    return tf->g == 157286 / 65536.0f
        && tf->a ==  62119 / 65536.0f
        && tf->b ==   3417 / 65536.0f
        && tf->c ==   5072 / 65536.0f
        && tf->d ==   2651 / 65536.0f
        && tf->e ==      0 / 65536.0f
        && tf->f ==      0 / 65536.0f;
}

static bool is_linear(const skcms_TransferFunction* tf) {
    return tf->g == 1.0f
        && tf->a == 1.0f
        && tf->b == 0.0f
        && tf->c == 0.0f
        && tf->d == 0.0f
        && tf->e == 0.0f
        && tf->f == 0.0f;
}

static void dump_transfer_function(FILE* fp, const char* name, const skcms_TransferFunction* tf) {
    fprintf(fp, "%4s : %.9g, %.9g, %.9g, %.9g, %.9g, %.9g, %.9g", name,
           (double)tf->g, (double)tf->a, (double)tf->b, (double)tf->c,
           (double)tf->d, (double)tf->e, (double)tf->f);
    if (is_sRGB(tf)) {
        fprintf(fp, " (sRGB)");
    } else if (is_linear(tf)) {
        fprintf(fp, " (Linear)");
    }
    fprintf(fp, "\n");
}

static void dump_approx_transfer_function(FILE* fp, const skcms_TransferFunction* tf,
                                          float max_error, bool for_unit_test) {
    if (for_unit_test) {
        fprintf(fp, "  ~= : %.6g, %.6g, %.6g, %.6g, %.6g, %.6g, %.6g  (Max error: %.2g)",
                (double)tf->g, (double)tf->a, (double)tf->b, (double)tf->c,
                (double)tf->d, (double)tf->e, (double)tf->f, (double)max_error);
    } else {
        fprintf(fp, "  ~= : %.9g, %.9g, %.9g, %.9g, %.9g, %.9g, %.9g  (Max error: %.9g)",
                (double)tf->g, (double)tf->a, (double)tf->b, (double)tf->c,
                (double)tf->d, (double)tf->e, (double)tf->f, (double)max_error);
    }
    if (tf->d > 0) {
        // Has both linear and nonlinear sections, include the discontinuity at D
        float l_at_d = (tf->c * tf->d + tf->f);
        float n_at_d = powf_(tf->a * tf->d + tf->b, tf->g) + tf->e;
        fprintf(fp, " (D-gap: %.*g)", for_unit_test ? 2 : 9, (double)(n_at_d - l_at_d));
    }
    if (is_linear(tf)) {
        fprintf(fp, " (Linear)");
    }
    fprintf(fp, "\n");
}

static void dump_curve(FILE* fp, const char* name, const skcms_Curve* curve, bool for_unit_test) {
    if (curve->table_entries) {
        fprintf(fp, "%4s : %d-bit table with %u entries\n", name,
                curve->table_8 ? 8 : 16, curve->table_entries);
        skcms_TransferFunction tf;
        float max_error;
        if (skcms_ApproximateCurve(curve, &tf, &max_error)) {
            dump_approx_transfer_function(fp, &tf, max_error, for_unit_test);
        }
    } else {
        dump_transfer_function(fp, name, &curve->parametric);
    }
}

static bool has_single_transfer_function(const skcms_ICCProfile* profile,
                                         skcms_TransferFunction* tf) {
    const skcms_Curve* trc = profile->trc;
    if (profile->has_trc &&
            trc[0].table_entries == 0 &&
            trc[1].table_entries == 0 &&
            trc[2].table_entries == 0) {

        if (0 != memcmp(&trc[0].parametric, &trc[1].parametric, sizeof(skcms_TransferFunction)) ||
            0 != memcmp(&trc[0].parametric, &trc[2].parametric, sizeof(skcms_TransferFunction))) {
            return false;
        }

        memcpy(tf, &trc[0].parametric, sizeof(skcms_TransferFunction));
        return true;
    }
    return false;
}

void dump_profile(const skcms_ICCProfile* profile, FILE* fp, bool for_unit_test) {
    fprintf(fp, "%20s : 0x%08X : %u\n", "Size", profile->size, profile->size);
    dump_sig_field(fp, "Data color space", profile->data_color_space);
    dump_sig_field(fp, "PCS", profile->pcs);
    fprintf(fp, "%20s : 0x%08X : %u\n", "Tag count", profile->tag_count, profile->tag_count);

    fprintf(fp, "\n");

    fprintf(fp, " Tag    : Type   : Size   : Offset\n");
    fprintf(fp, " ------ : ------ : ------ : --------\n");
    for (uint32_t i = 0; i < profile->tag_count; ++i) {
        skcms_ICCTag tag;
        skcms_GetTagByIndex(profile, i, &tag);
        char tagSig[5];
        char typeSig[5];
        signature_to_string(tag.signature, tagSig);
        signature_to_string(tag.type, typeSig);
        fprintf(fp, " '%s' : '%s' : %6u : %u\n", tagSig, typeSig, tag.size,
                (uint32_t)(tag.buf - profile->buffer));
    }

    fprintf(fp, "\n");

    skcms_TransferFunction tf;
    if (has_single_transfer_function(profile, &tf)) {
        dump_transfer_function(fp, "TRC", &tf);
    } else if (profile->has_trc) {
        const char* trcNames[3] = { "rTRC", "gTRC", "bTRC" };
        for (int i = 0; i < 3; ++i) {
            dump_curve(fp, trcNames[i], &profile->trc[i], for_unit_test);
        }
    }

    if (profile->has_toXYZD50) {
        skcms_Matrix3x3 toXYZ = profile->toXYZD50;
        fprintf(fp, " XYZ : | %.9f %.9f %.9f |\n"
                    "       | %.9f %.9f %.9f |\n"
                    "       | %.9f %.9f %.9f |\n",
               (double)toXYZ.vals[0][0], (double)toXYZ.vals[0][1], (double)toXYZ.vals[0][2],
               (double)toXYZ.vals[1][0], (double)toXYZ.vals[1][1], (double)toXYZ.vals[1][2],
               (double)toXYZ.vals[2][0], (double)toXYZ.vals[2][1], (double)toXYZ.vals[2][2]);
    }

    if (profile->has_A2B) {
        const skcms_A2B* a2b = &profile->A2B;
        fprintf(fp, " A2B : %s%s\"B\"\n", a2b->input_channels ? "\"A\", CLUT, " : "",
                                          a2b->matrix_channels ? "\"M\", Matrix, " : "");
        if (a2b->input_channels) {
            fprintf(fp, "%4s : %u inputs\n", "\"A\"", a2b->input_channels);
            const char* curveNames[4] = { "A0", "A1", "A2", "A3" };
            for (uint32_t i = 0; i < a2b->input_channels; ++i) {
                dump_curve(fp, curveNames[i], &a2b->input_curves[i], for_unit_test);
            }
            fprintf(fp, "%4s : ", "CLUT");
            const char* sep = "";
            for (uint32_t i = 0; i < a2b->input_channels; ++i) {
                fprintf(fp, "%s%u", sep, a2b->grid_points[i]);
                sep = " x ";
            }
            fprintf(fp, " (%d bpp)\n", a2b->grid_8 ? 8 : 16);
        }

        if (a2b->matrix_channels) {
            fprintf(fp, "%4s : %u inputs\n", "\"M\"", a2b->matrix_channels);
            const char* curveNames[4] = { "M0", "M1", "M2" };
            for (uint32_t i = 0; i < a2b->matrix_channels; ++i) {
                dump_curve(fp, curveNames[i], &a2b->matrix_curves[i], for_unit_test);
            }
            const skcms_Matrix3x4* m = &a2b->matrix;
            fprintf(fp, "Mtrx : | %.9f %.9f %.9f %.9f |\n"
                        "       | %.9f %.9f %.9f %.9f |\n"
                        "       | %.9f %.9f %.9f %.9f |\n",
                   (double)m->vals[0][0], (double)m->vals[0][1], (double)m->vals[0][2], (double)m->vals[0][3],
                   (double)m->vals[1][0], (double)m->vals[1][1], (double)m->vals[1][2], (double)m->vals[1][3],
                   (double)m->vals[2][0], (double)m->vals[2][1], (double)m->vals[2][2], (double)m->vals[2][3]);
        }

        {
            fprintf(fp, "%4s : %u outputs\n", "\"B\"", a2b->output_channels);
            const char* curveNames[3] = { "B0", "B1", "B2" };
            for (uint32_t i = 0; i < a2b->output_channels; ++i) {
                dump_curve(fp, curveNames[i], &a2b->output_curves[i], for_unit_test);
            }
        }
    }

    dump_transform_to_XYZD50(fp, profile);
}

bool load_file_fp(FILE* fp, void** buf, size_t* len) {
    if (fseek(fp, 0L, SEEK_END) != 0) {
        return false;
    }
    long size = ftell(fp);
    if (size <= 0) {
        return false;
    }
    *len = (size_t)size;
    rewind(fp);

    *buf = malloc(*len);
    if (!*buf) {
        return false;
    }

    if (fread(*buf, 1, *len, fp) != *len) {
        free(*buf);
        return false;
    }
    return true;
}

bool load_file(const char* filename, void** buf, size_t* len) {
    FILE* fp = fopen(filename, "rb");
    if (!fp) {
        return false;
    }
    bool result = load_file_fp(fp, buf, len);
    fclose(fp);
    return result;
}

bool write_file(const char* filename, void* buf, size_t len) {
    FILE* fp = fopen(filename, "wb");
    if (!fp) {
        return false;
    }
    bool result = (fwrite(buf, 1, len, fp) == len);
    fclose(fp);
    return result;
}
