/*
 * 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 "skcms_internal.h"
#include "test_only.h"
#include <stdlib.h>
#include <string.h>

static void print_shortest_float(FILE* fp, float x) {
    char buf[80];
    int chars = 0;
    for (int digits = 0; digits < 12; digits++) {
        chars = snprintf(buf, sizeof(buf), "%.*f", digits, x);
        float back;
        if (1 != sscanf(buf, "%f", &back) || back == x) {
            break;
        }
    }

    // We've found the smallest number of digits that roundtrips our float.
    // That'd be the ideal thing to print, but sadly fprintf() rounding is
    // implementation specific, so results vary in the last digit.
    //
    // We compromise by dropping that last digit.
    //
    // E.g. glibc prints 0x1.7p-6 == 0x3cb80000 as 0.022460938 in 11 digits,
    // while newlib prints as 0.022460937.  We print 0.02246094.

    bool is_fractional = NULL != strchr(buf, '.');
    if (is_fractional) {
        chars--;
    }
    fprintf(fp, "%.*s", chars, buf);
}

static void dump_transform_to_XYZD50(FILE* fp,
                                     const skcms_ICCProfile* profile) {
    // 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(
                skcms_252_random_bytes,    fmt, skcms_AlphaFormat_Unpremul, profile,
                dst, skcms_PixelFormat_RGB_888, skcms_AlphaFormat_Unpremul, skcms_XYZD50_profile(),
                npixels)) {
        fprintf(fp, "We can parse this profile, but not transform it to 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 dump_transform_to_sRGBA(FILE* fp,
                                    const skcms_ICCProfile* profile) {
    // Let's just transform all combinations of 0x00, 0x7f, and 0xff inputs to 32-bit sRGB.
    // This helps catch issues with alpha, and is mildly interesting on its own.

    uint32_t src[81],
             dst[81];
    for (int i = 0; i < 81; i++) {
        src[i] = (uint32_t)((i/1   % 3) * 127.5f) <<  0
               | (uint32_t)((i/3   % 3) * 127.5f) <<  8
               | (uint32_t)((i/9   % 3) * 127.5f) << 16
               | (uint32_t)((i/27  % 3) * 127.5f) << 24;
    }

    // No matter profile->data_color_space, this should be fine, either RGBA itself or CMYK.
    const skcms_PixelFormat pf = skcms_PixelFormat_RGBA_8888;
    const skcms_AlphaFormat af = skcms_AlphaFormat_Unpremul;

    if (!skcms_Transform(src, pf,af, profile,
                         dst, pf,af, skcms_sRGB_profile(), 81)) {
        fprintf(fp, "We can parse this profile, but not transform it to sRGB!\n");
        return;
    }
    fprintf(fp, "81 edge-case pixels transformed to sRGB 8888 (unpremul):\n");

    for (int i = 0; i < 9; i++) {
        fprintf(fp, "\t%08x %08x %08x  %08x %08x %08x  %08x %08x %08x\n",
                dst[9*i+0], dst[9*i+1], dst[9*i+2],
                dst[9*i+3], dst[9*i+4], dst[9*i+5],
                dst[9*i+6], dst[9*i+7], dst[9*i+8]);
    }
}


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 void dump_transfer_function(FILE* fp, const char* name,
                                   const skcms_TransferFunction* tf, float max_error) {
    fprintf(fp, "%4s : %.7g, %.7g, %.7g, %.7g, %.7g, %.7g, %.7g", name,
            tf->g, tf->a, tf->b, tf->c, tf->d, tf->e, tf->f);

    if (max_error > 0) {
        fprintf(fp, " (Max error: %.6g)", 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: %.6g)", (n_at_d - l_at_d));
    }

    fprintf(fp, " (f(1) = %.6g)", skcms_TransferFunction_eval(tf, 1.0f));

    skcms_Curve curve;
    curve.table_entries = 0;
    curve.parametric = *tf;

    if (skcms_AreApproximateInverses(&curve, skcms_sRGB_Inverse_TransferFunction())) {
        fprintf(fp, " (~sRGB)");
    } else if (skcms_AreApproximateInverses(&curve, skcms_Identity_TransferFunction())) {
        fprintf(fp, " (~Identity)");
    }
    fprintf(fp, "\n");
}

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

void dump_profile(const skcms_ICCProfile* profile, FILE* fp) {
    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");

    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]);
        }
        if (skcms_TRCs_AreApproximateInverse(profile, skcms_sRGB_Inverse_TransferFunction())) {
            fprintf(fp, "TRCs ≈ sRGB\n");
        }
    }

    skcms_ICCProfile best_single_curve = *profile;
    if (skcms_MakeUsableAsDestinationWithSingleCurve(&best_single_curve)) {
        dump_transfer_function(fp, "Best", &best_single_curve.trc[0].parametric, 0.0f);

        skcms_TransferFunction inv;
        if (skcms_TransferFunction_invert(&best_single_curve.trc[0].parametric, &inv)) {
            dump_transfer_function(fp, "Inv ", &inv, 0.0f);

            fprintf(fp, "Best Error: | %.6g %.6g %.6g |\n",
                skcms_MaxRoundtripError(&profile->trc[0], &inv),
                skcms_MaxRoundtripError(&profile->trc[1], &inv),
                skcms_MaxRoundtripError(&profile->trc[2], &inv));
        } else {
            fprintf(fp, "*** could not invert Best ***\n");
        }
    }

    if (profile->has_toXYZD50) {
        skcms_Matrix3x3 toXYZ = profile->toXYZD50;

        fprintf(fp, " XYZ : | ");
        print_shortest_float(fp, toXYZ.vals[0][0]); fprintf(fp, " ");
        print_shortest_float(fp, toXYZ.vals[0][1]); fprintf(fp, " ");
        print_shortest_float(fp, toXYZ.vals[0][2]); fprintf(fp, " |\n");

        fprintf(fp, "       | ");
        print_shortest_float(fp, toXYZ.vals[1][0]); fprintf(fp, " ");
        print_shortest_float(fp, toXYZ.vals[1][1]); fprintf(fp, " ");
        print_shortest_float(fp, toXYZ.vals[1][2]); fprintf(fp, " |\n");

        fprintf(fp, "       | ");
        print_shortest_float(fp, toXYZ.vals[2][0]); fprintf(fp, " ");
        print_shortest_float(fp, toXYZ.vals[2][1]); fprintf(fp, " ");
        print_shortest_float(fp, toXYZ.vals[2][2]); fprintf(fp, " |\n");

        float white_x = toXYZ.vals[0][0] + toXYZ.vals[0][1] + toXYZ.vals[0][2],
              white_y = toXYZ.vals[1][0] + toXYZ.vals[1][1] + toXYZ.vals[1][2],
              white_z = toXYZ.vals[2][0] + toXYZ.vals[2][1] + toXYZ.vals[2][2];
        if (fabsf_(white_x - 0.964f) > 0.01f ||
            fabsf_(white_y - 1.000f) > 0.01f ||
            fabsf_(white_z - 0.825f) > 0.01f) {
            fprintf(fp, " !!! This does not appear to use a D50 whitepoint, rather [%g %g %g]\n",
                    white_x, white_y, white_z);
        }
    }

    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]);
            }
            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]);
            }
            const skcms_Matrix3x4* m = &a2b->matrix;
            fprintf(fp, "Mtrx : | %.9g %.9g %.9g %.9g |\n"
                        "       | %.9g %.9g %.9g %.9g |\n"
                        "       | %.9g %.9g %.9g %.9g |\n",
                   m->vals[0][0], m->vals[0][1], m->vals[0][2], m->vals[0][3],
                   m->vals[1][0], m->vals[1][1], m->vals[1][2], m->vals[1][3],
                   m->vals[2][0], m->vals[2][1], m->vals[2][2], 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]);
            }
        }
    }

    skcms_Matrix3x3 chad;
    if (skcms_GetCHAD(profile, &chad)) {
        fprintf(fp, "CHAD : | ");
        print_shortest_float(fp, chad.vals[0][0]); fprintf(fp, " ");
        print_shortest_float(fp, chad.vals[0][1]); fprintf(fp, " ");
        print_shortest_float(fp, chad.vals[0][2]); fprintf(fp, " |\n");

        fprintf(fp, "       | ");
        print_shortest_float(fp, chad.vals[1][0]); fprintf(fp, " ");
        print_shortest_float(fp, chad.vals[1][1]); fprintf(fp, " ");
        print_shortest_float(fp, chad.vals[1][2]); fprintf(fp, " |\n");

        fprintf(fp, "       | ");
        print_shortest_float(fp, chad.vals[2][0]); fprintf(fp, " ");
        print_shortest_float(fp, chad.vals[2][1]); fprintf(fp, " ");
        print_shortest_float(fp, chad.vals[2][2]); fprintf(fp, " |\n");
    }

    float wtpt[3];
    if (skcms_GetWTPT(profile, wtpt)) {
        fprintf(fp, "WTPT : | ");
        print_shortest_float(fp, wtpt[0]); fprintf(fp, " ");
        print_shortest_float(fp, wtpt[1]); fprintf(fp, " ");
        print_shortest_float(fp, wtpt[2]); fprintf(fp, " |\n");
    }

    dump_transform_to_XYZD50(fp, profile);
    dump_transform_to_sRGBA (fp, profile);
    if (skcms_ApproximatelyEqualProfiles(profile, skcms_sRGB_profile())) {
        fprintf(fp, "This profile ≈ sRGB.\n");
    }
}

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;
}
