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

#include "Resources.h"

#include "SkBitmap.h"
#include "SkCanvas.h"
#include "SkCodec.h"
#include "SkColorSpacePriv.h"
#include "SkColorSpace_A2B.h"
#include "SkColorSpace_XYZ.h"
#include "SkCommandLineFlags.h"
#include "SkICCPriv.h"
#include "SkImageEncoder.h"
#include "SkMatrix44.h"
#include "SkOSFile.h"
#include "SkRasterPipeline.h"
#include "../src/jumper/SkJumper.h"

#include "sk_tool_utils.h"

#include <sstream>
#include <string>
#include <vector>

DEFINE_string(input, "input.png", "A path to the input image (or icc profile with --icc).");
DEFINE_string(output, ".", "A path to the output image directory.");
DEFINE_bool(icc, false, "Indicates that the input is an icc profile.");
DEFINE_bool(sRGB_gamut, false, "Draws the sRGB gamut on the gamut visualization.");
DEFINE_bool(adobeRGB, false, "Draws the Adobe RGB gamut on the gamut visualization.");
DEFINE_bool(sRGB_gamma, false, "Draws the sRGB gamma on all gamma output images.");
DEFINE_string(uncorrected, "", "A path to reencode the uncorrected input image.");


//-------------------------------------------------------------------------------------------------
//------------------------------------ Gamma visualizations ---------------------------------------

static const char* kRGBChannelNames[3] = {
    "Red  ",
    "Green",
    "Blue "
};
static const SkColor kRGBChannelColors[3] = {
    SkColorSetARGB(128, 255, 0, 0),
    SkColorSetARGB(128, 0, 255, 0),
    SkColorSetARGB(128, 0, 0, 255)
};

static const char* kGrayChannelNames[1] = { "Gray"};
static const SkColor kGrayChannelColors[1] = { SkColorSetRGB(128, 128, 128) };

static const char* kCMYKChannelNames[4] = {
    "Cyan   ",
    "Magenta",
    "Yellow ",
    "Black  "
};
static const SkColor kCMYKChannelColors[4] = {
    SkColorSetARGB(128, 0, 255, 255),
    SkColorSetARGB(128, 255, 0, 255),
    SkColorSetARGB(128, 255, 255, 0),
    SkColorSetARGB(128, 16, 16, 16)
};

static const char*const*const kChannelNames[4] = {
    kGrayChannelNames,
    kRGBChannelNames,
    kRGBChannelNames,
    kCMYKChannelNames
};
static const SkColor*const kChannelColors[4] = {
    kGrayChannelColors,
    kRGBChannelColors,
    kRGBChannelColors,
    kCMYKChannelColors
};

static void dump_transfer_fn(SkGammaNamed gammaNamed) {
    switch (gammaNamed) {
        case kSRGB_SkGammaNamed:
            SkDebugf("Transfer Function: sRGB\n");
            return;
        case k2Dot2Curve_SkGammaNamed:
            SkDebugf("Exponential Transfer Function: Exponent 2.2\n");
            return;
        case kLinear_SkGammaNamed:
            SkDebugf("Transfer Function: Linear\n");
            return;
        default:
            break;
    }

}

static constexpr int kGammaImageWidth = 500;
static constexpr int kGammaImageHeight = 500;

static void dump_transfer_fn(const SkGammas& gammas) {
    SkASSERT(gammas.channels() <= 4);
    const char*const*const channels = kChannelNames[gammas.channels() - 1];
    for (int i = 0; i < gammas.channels(); i++) {
        if (gammas.isNamed(i)) {
            switch (gammas.data(i).fNamed) {
                case kSRGB_SkGammaNamed:
                    SkDebugf("%s Transfer Function: sRGB\n", channels[i]);
                    return;
                case k2Dot2Curve_SkGammaNamed:
                    SkDebugf("%s Transfer Function: Exponent 2.2\n", channels[i]);
                    return;
                case kLinear_SkGammaNamed:
                    SkDebugf("%s Transfer Function: Linear\n", channels[i]);
                    return;
                default:
                    SkASSERT(false);
                    continue;
            }
        } else if (gammas.isValue(i)) {
            SkDebugf("%s Transfer Function: Exponent %.3f\n", channels[i], gammas.data(i).fValue);
        } else if (gammas.isParametric(i)) {
            const SkColorSpaceTransferFn& fn = gammas.data(i).params(&gammas);
            SkDebugf("%s Transfer Function: Parametric A = %.3f, B = %.3f, C = %.3f, D = %.3f, "
                     "E = %.3f, F = %.3f, G = %.3f\n", channels[i], fn.fA, fn.fB, fn.fC, fn.fD,
                     fn.fE, fn.fF, fn.fG);
        } else {
            SkASSERT(gammas.isTable(i));
            SkDebugf("%s Transfer Function: Table (%d entries)\n", channels[i],
                    gammas.data(i).fTable.fSize);
        }
    }
}

static inline float parametric(const SkColorSpaceTransferFn& fn, float x) {
    return x >= fn.fD ? powf(fn.fA*x + fn.fB, fn.fG) + fn.fE
                      : fn.fC*x + fn.fF;
}

static void draw_transfer_fn(SkCanvas* canvas, SkGammaNamed gammaNamed, const SkGammas* gammas,
                             SkColor color) {
    SkColorSpaceTransferFn fn[4];
    struct TableInfo {
        const float* fTable;
        int          fSize;
    };
    TableInfo table[4];
    bool isTable[4] = {false, false, false, false};
    const int channels = gammas ? gammas->channels() : 1;
    SkASSERT(channels <= 4);
    if (kNonStandard_SkGammaNamed != gammaNamed) {
        dump_transfer_fn(gammaNamed);
        for (int i = 0; i < channels; ++i) {
            named_to_parametric(&fn[i], gammaNamed);
        }
    } else {
        SkASSERT(gammas);
        dump_transfer_fn(*gammas);
        for (int i = 0; i < channels; ++i) {
            if (gammas->isTable(i)) {
                table[i].fTable = gammas->table(i);
                table[i].fSize = gammas->data(i).fTable.fSize;
                isTable[i] = true;
            } else {
                switch (gammas->type(i)) {
                    case SkGammas::Type::kNamed_Type:
                        named_to_parametric(&fn[i], gammas->data(i).fNamed);
                        break;
                    case SkGammas::Type::kValue_Type:
                        value_to_parametric(&fn[i], gammas->data(i).fValue);
                        break;
                    case SkGammas::Type::kParam_Type:
                        fn[i] = gammas->params(i);
                        break;
                    default:
                        SkASSERT(false);
                }
            }
        }
    }
    SkPaint paint;
    paint.setStyle(SkPaint::kStroke_Style);
    paint.setColor(color);
    paint.setStrokeWidth(2.0f);
    // note: gamma has positive values going up in this image so this origin is
    //       the bottom left and we must subtract y instead of adding.
    const float gap         = 16.0f;
    const float gammaWidth  = kGammaImageWidth - 2 * gap;
    const float gammaHeight = kGammaImageHeight - 2 * gap;
    // gamma origin point
    const float ox = gap;
    const float oy = gap + gammaHeight;
    for (int i = 0; i < channels; ++i) {
        if (kNonStandard_SkGammaNamed == gammaNamed) {
            paint.setColor(kChannelColors[channels - 1][i]);
        } else {
            paint.setColor(color);
        }
        if (isTable[i]) {
            auto tx = [&table,i](int index) {
                return index / (table[i].fSize - 1.0f);
            };
            for (int ti = 1; ti < table[i].fSize; ++ti) {
                canvas->drawLine(ox + gammaWidth * tx(ti - 1),
                                 oy - gammaHeight * table[i].fTable[ti - 1],
                                 ox + gammaWidth * tx(ti),
                                 oy - gammaHeight * table[i].fTable[ti],
                                 paint);
            }
        } else {
            const float step = 0.01f;
            float yPrev = parametric(fn[i], 0.0f);
            for (float x = step; x <= 1.0f; x += step) {
                const float y = parametric(fn[i], x);
                canvas->drawLine(ox + gammaWidth * (x - step), oy - gammaHeight * yPrev,
                                 ox + gammaWidth * x, oy - gammaHeight * y,
                                 paint);
                yPrev = y;
            }
        }
    }
    paint.setColor(0xFF000000);
    paint.setStrokeWidth(3.0f);
    canvas->drawRect({ ox, oy - gammaHeight, ox + gammaWidth, oy }, paint);
}

//-------------------------------------------------------------------------------------------------
//------------------------------------ CLUT visualizations ----------------------------------------
static void dump_clut(const SkColorLookUpTable& clut) {
    SkDebugf("CLUT: ");
    for (int i = 0; i < clut.inputChannels(); ++i) {
        SkDebugf("[%d]", clut.gridPoints(i));
    }
    SkDebugf(" -> [%d]\n", clut.outputChannels());
}

constexpr int kClutGap = 8;
constexpr float kClutCanvasSize = 2000;

static inline int usedGridPoints(const SkColorLookUpTable& clut, int dimension) {
    const int gp = clut.gridPoints(dimension);
    return gp <= 16 ? gp : 16;
}

// how many rows of cross-section cuts to display
static inline int cut_rows(const SkColorLookUpTable& clut, int dimOrder[4]) {
    // and vertical ones for the 4th dimension (if applicable)
    return clut.inputChannels() >= 4 ? usedGridPoints(clut, dimOrder[3]) : 1;
}

// how many columns of cross-section cuts to display
static inline int cut_cols(const SkColorLookUpTable& clut, int dimOrder[4]) {
    // do horizontal cuts for the 3rd dimension (if applicable)
    return clut.inputChannels() >= 3 ? usedGridPoints(clut, dimOrder[2]) : 1;
}

// gets the width/height to use for cross-sections of a CLUT
static int cut_size(const SkColorLookUpTable& clut, int dimOrder[4]) {
    const int rows = cut_rows(clut, dimOrder);
    const int cols = cut_cols(clut, dimOrder);
    // make sure the cross-section CLUT cuts are square still by using the
    // smallest of the width/height, then adjust the gaps between accordingly
    const int cutWidth = (kClutCanvasSize - kClutGap * (1 + cols)) / cols;
    const int cutHeight = (kClutCanvasSize - kClutGap * (1 + rows)) / rows;
    return cutWidth < cutHeight ? cutWidth : cutHeight;
}

static void clut_interp(const SkColorLookUpTable& clut, float out[3], const float in[4]) {
    // This is kind of a toy implementation.
    // You generally wouldn't want to do this 1 pixel at a time.

    SkJumper_ColorLookupTableCtx ctx;
    ctx.table = clut.table();
    for (int i = 0; i < clut.inputChannels(); i++) {
        ctx.limits[i] = clut.gridPoints(i);
    }

    SkSTArenaAlloc<256> alloc;
    SkRasterPipeline p(&alloc);
    p.append_constant_color(&alloc, in);
    p.append(clut.inputChannels() == 3 ? SkRasterPipeline::clut_3D
                                       : SkRasterPipeline::clut_4D, &ctx);
    p.append(SkRasterPipeline::clamp_0);
    p.append(SkRasterPipeline::clamp_1);
    p.append(SkRasterPipeline::store_f32, &out);
    p.run(0,0, 1,1);
}

static void draw_clut(SkCanvas* canvas, const SkColorLookUpTable& clut, int dimOrder[4]) {
    dump_clut(clut);

    const int cutSize = cut_size(clut, dimOrder);
    const int rows = cut_rows(clut, dimOrder);
    const int cols = cut_cols(clut, dimOrder);
    const int cutHorizGap = (kClutCanvasSize - cutSize * cols) / (1 + cols);
    const int cutVertGap = (kClutCanvasSize - cutSize * rows) / (1 + rows);

    SkPaint paint;
    for (int row = 0; row < rows; ++row) {
        for (int col = 0; col < cols; ++col) {
            // make sure to move at least one pixel, but otherwise move per-gridpoint
            const float xStep = 1.0f / (SkTMin(cutSize, clut.gridPoints(dimOrder[0])) - 1);
            const float yStep = 1.0f / (SkTMin(cutSize, clut.gridPoints(dimOrder[1])) - 1);
            const float ox = clut.inputChannels() >= 3 ? (1 + col) * cutHorizGap + col * cutSize
                                                       : kClutGap;
            const float oy = clut.inputChannels() >= 4 ? (1 + row) * cutVertGap + row * cutSize
                                                       : kClutGap;
            // for each cross-section cut, draw a bunch of squares whose colour is the top-left's
            // colour in the CLUT (usually this will just draw the gridpoints)
            for (float x = 0.0f; x < 1.0f; x += xStep) {
                for (float y = 0.0f; y < 1.0f; y += yStep) {
                    const float z = col / (cols - 1.0f);
                    const float w = row / (rows - 1.0f);
                    const float input[4] = {x, y, z, w};
                    float output[3];
                    clut_interp(clut, output, input);
                    paint.setColor(SkColorSetRGB(255*output[0], 255*output[1], 255*output[2]));
                    canvas->drawRect(SkRect::MakeLTRB(ox + cutSize * x, oy + cutSize * y,
                                                      ox + cutSize * (x + xStep),
                                                      oy + cutSize * (y + yStep)), paint);
                }
            }
        }
    }
}


//-------------------------------------------------------------------------------------------------
//------------------------------------ Gamut visualizations ---------------------------------------
static void dump_matrix(const SkMatrix44& m) {
    for (int r = 0; r < 4; ++r) {
        SkDebugf("|");
        for (int c = 0; c < 4; ++c) {
            SkDebugf(" %f ", m.get(r, c));
        }
        SkDebugf("|\n");
    }
}

/**
 *  Loads the triangular gamut as a set of three points.
 */
static void load_gamut(SkPoint rgb[], const SkMatrix44& xyz) {
    // rx = rX / (rX + rY + rZ)
    // ry = rX / (rX + rY + rZ)
    // gx, gy, bx, and gy are calulcated similarly.
    float rSum = xyz.get(0, 0) + xyz.get(1, 0) + xyz.get(2, 0);
    float gSum = xyz.get(0, 1) + xyz.get(1, 1) + xyz.get(2, 1);
    float bSum = xyz.get(0, 2) + xyz.get(1, 2) + xyz.get(2, 2);
    rgb[0].fX = xyz.get(0, 0) / rSum;
    rgb[0].fY = xyz.get(1, 0) / rSum;
    rgb[1].fX = xyz.get(0, 1) / gSum;
    rgb[1].fY = xyz.get(1, 1) / gSum;
    rgb[2].fX = xyz.get(0, 2) / bSum;
    rgb[2].fY = xyz.get(1, 2) / bSum;
}

/**
 *  Calculates the area of the triangular gamut.
 */
static float calculate_area(SkPoint abc[]) {
    SkPoint a = abc[0];
    SkPoint b = abc[1];
    SkPoint c = abc[2];
    return 0.5f * SkTAbs(a.fX*b.fY + b.fX*c.fY - a.fX*c.fY - c.fX*b.fY - b.fX*a.fY);
}

static void draw_gamut(SkCanvas* canvas, const SkMatrix44& xyz, const char* name, SkColor color,
                       bool label) {
    // Report the XYZ values.
    SkDebugf("%s\n", name);
    SkDebugf("       R     G     B\n");
    SkDebugf("X  %.3f %.3f %.3f\n", xyz.get(0, 0), xyz.get(0, 1), xyz.get(0, 2));
    SkDebugf("Y  %.3f %.3f %.3f\n", xyz.get(1, 0), xyz.get(1, 1), xyz.get(1, 2));
    SkDebugf("Z  %.3f %.3f %.3f\n", xyz.get(2, 0), xyz.get(2, 1), xyz.get(2, 2));

    // Calculate the points in the gamut from the XYZ values.
    SkPoint rgb[4];
    load_gamut(rgb, xyz);

    // Report the area of the gamut.
    SkDebugf("Area of Gamut: %.3f\n\n", calculate_area(rgb));

    // Magic constants that help us place the gamut triangles in the appropriate position
    // on the canvas.
    const float xScale = 2071.25f;  // Num pixels from 0 to 1 in x
    const float xOffset = 241.0f;   // Num pixels until start of x-axis
    const float yScale = 2067.78f;  // Num pixels from 0 to 1 in y
    const float yOffset = -144.78f; // Num pixels until start of y-axis
                                    // (negative because y extends beyond image bounds)

    // Now transform the points so they can be drawn on our canvas.
    // Note that y increases as we move down the canvas.
    rgb[0].fX = xOffset + xScale * rgb[0].fX;
    rgb[0].fY = yOffset + yScale * (1.0f - rgb[0].fY);
    rgb[1].fX = xOffset + xScale * rgb[1].fX;
    rgb[1].fY = yOffset + yScale * (1.0f - rgb[1].fY);
    rgb[2].fX = xOffset + xScale * rgb[2].fX;
    rgb[2].fY = yOffset + yScale * (1.0f - rgb[2].fY);

    // Repeat the first point to connect the polygon.
    rgb[3] = rgb[0];
    SkPaint paint;
    paint.setColor(color);
    paint.setStrokeWidth(6.0f);
    paint.setTextSize(75.0f);
    canvas->drawPoints(SkCanvas::kPolygon_PointMode, 4, rgb, paint);
    if (label) {
        canvas->drawString("R", rgb[0].fX + 5.0f, rgb[0].fY + 75.0f, paint);
        canvas->drawString("G", rgb[1].fX + 5.0f, rgb[1].fY - 5.0f, paint);
        canvas->drawString("B", rgb[2].fX - 75.0f, rgb[2].fY - 5.0f, paint);
    }
}


//-------------------------------------------------------------------------------------------------
//----------------------------------------- Main code ---------------------------------------------
static SkBitmap transparentBitmap(int width, int height) {
    SkBitmap bitmap;
    bitmap.allocN32Pixels(width, height);
    bitmap.eraseColor(SkColorSetARGB(0, 0, 0, 0));
    return bitmap;
}

class OutputCanvas {
public:
    OutputCanvas(SkBitmap&& bitmap)
        :fBitmap(bitmap)
        ,fCanvas(fBitmap)
    {}

    bool save(std::vector<std::string>* output, const std::string& filename) {
        // Finally, encode the result to the output file.
        sk_sp<SkData> out = sk_tool_utils::EncodeImageToData(fBitmap, SkEncodedImageFormat::kPNG,
                                                             100);
        if (!out) {
            SkDebugf("Failed to encode %s output.\n", filename.c_str());
            return false;
        }
        SkFILEWStream stream(filename.c_str());
        if (!stream.write(out->data(), out->size())) {
            SkDebugf("Failed to write %s output.\n", filename.c_str());
            return false;
        }
        // record name of canvas
        output->push_back(filename);
        return true;
    }

    SkCanvas* canvas() { return &fCanvas; }

private:
    SkBitmap fBitmap;
    SkCanvas fCanvas;
};

int main(int argc, char** argv) {
    SkCommandLineFlags::SetUsage(
            "Usage: colorspaceinfo --input <path to input image (or icc profile with --icc)> "
                                  "--output <directory to output images> "
                                  "--icc <indicates that the input is an icc profile>"
                                  "--sRGB_gamut <draw canonical sRGB gamut> "
                                  "--adobeRGB <draw canonical Adobe RGB gamut> "
                                  "--sRGB_gamma <draw sRGB gamma> "
                                  "--uncorrected <path to reencoded, uncorrected input image>\n"
            "Description: Writes visualizations of the color space to the output image(s)  ."
                         "Also, if a path is provided, writes uncorrected bytes to an unmarked "
                         "png, for comparison with the input image.\n");
    SkCommandLineFlags::Parse(argc, argv);
    const char* input = FLAGS_input[0];
    const char* output = FLAGS_output[0];
    if (!input || !output) {
        SkCommandLineFlags::PrintUsage();
        return -1;
    }

    sk_sp<SkData> data(SkData::MakeFromFileName(input));
    if (!data) {
        SkDebugf("Cannot find input image.\n");
        return -1;
    }

    std::unique_ptr<SkCodec> codec = nullptr;
    sk_sp<SkColorSpace> colorSpace = nullptr;
    if (FLAGS_icc) {
        colorSpace = SkColorSpace::MakeICC(data->bytes(), data->size());
    } else {
        codec = SkCodec::MakeFromData(data);
        colorSpace = sk_ref_sp(codec->getInfo().colorSpace());
        SkDebugf("SkCodec would naturally decode as colorType=%s\n",
                 sk_tool_utils::colortype_name(codec->getInfo().colorType()));
    }

    if (!colorSpace) {
        SkDebugf("Cannot create codec or icc profile from input file.\n");
        return -1;
    }

    {
        SkColorSpaceTransferFn colorSpaceTransferFn;
        SkMatrix44 toXYZD50(SkMatrix44::kIdentity_Constructor);
        if (colorSpace->isNumericalTransferFn(&colorSpaceTransferFn) &&
            colorSpace->toXYZD50(&toXYZD50)) {
            SkString description = SkICCGetColorProfileTag(colorSpaceTransferFn, toXYZD50);
            SkDebugf("Color Profile Description: \"%s\"\n", description.c_str());
        }
    }

    // TODO: command line tweaking of this order
    int dimOrder[4] = {0, 1, 2, 3};

    std::vector<std::string> outputFilenames;

    auto createOutputFilename = [output](const char* category, int index) -> std::string {
        std::stringstream ss;
        ss << output << '/' << category << '_' << index << ".png";
        return ss.str();
    };

    if (colorSpace->toXYZD50()) {
        SkDebugf("XYZ/TRC color space\n");

        // Load a graph of the CIE XYZ color gamut.
        SkBitmap gamutCanvasBitmap;
        if (!GetResourceAsBitmap("images/gamut.png", &gamutCanvasBitmap)) {
            SkDebugf("Program failure (could not load gamut.png).\n");
            return -1;
        }
        OutputCanvas gamutCanvas(std::move(gamutCanvasBitmap));
        // Draw the sRGB gamut if requested.
        if (FLAGS_sRGB_gamut) {
            sk_sp<SkColorSpace> sRGBSpace = SkColorSpace::MakeSRGB();
            const SkMatrix44* mat = sRGBSpace->toXYZD50();
            SkASSERT(mat);
            draw_gamut(gamutCanvas.canvas(), *mat, "sRGB", 0xFFFF9394, false);
        }

        // Draw the Adobe RGB gamut if requested.
        if (FLAGS_adobeRGB) {
            sk_sp<SkColorSpace> adobeRGBSpace = SkColorSpace::MakeRGB(
                    SkColorSpace::kSRGB_RenderTargetGamma, SkColorSpace::kAdobeRGB_Gamut);
            const SkMatrix44* mat = adobeRGBSpace->toXYZD50();
            SkASSERT(mat);
            draw_gamut(gamutCanvas.canvas(), *mat, "Adobe RGB", 0xFF31a9e1, false);
        }
        const SkMatrix44* mat = colorSpace->toXYZD50();
        SkASSERT(mat);
        auto xyz = static_cast<SkColorSpace_XYZ*>(colorSpace.get());
        draw_gamut(gamutCanvas.canvas(), *mat, input, 0xFF000000, true);
        if (!gamutCanvas.save(&outputFilenames, createOutputFilename("gamut", 0))) {
            return -1;
        }

        OutputCanvas gammaCanvas(transparentBitmap(kGammaImageWidth, kGammaImageHeight));
        if (FLAGS_sRGB_gamma) {
            draw_transfer_fn(gammaCanvas.canvas(), kSRGB_SkGammaNamed, nullptr, 0xFFFF9394);
        }
        draw_transfer_fn(gammaCanvas.canvas(), colorSpace->gammaNamed(), xyz->gammas(), 0xFF000000);
        if (!gammaCanvas.save(&outputFilenames, createOutputFilename("gamma", 0))) {
            return -1;
        }
    } else {
        SkDebugf("A2B color space");
        SkColorSpace_A2B* a2b = static_cast<SkColorSpace_A2B*>(colorSpace.get());
        SkDebugf("Conversion type: ");
        switch (a2b->iccType()) {
            case SkColorSpace::kRGB_Type:
                SkDebugf("RGB");
                break;
            case SkColorSpace::kCMYK_Type:
                SkDebugf("CMYK");
                break;
            case SkColorSpace::kGray_Type:
                SkDebugf("Gray");
                break;
            default:
                SkASSERT(false);
                break;

        }
        SkDebugf(" -> ");
        switch (a2b->pcs()) {
            case SkColorSpace_A2B::PCS::kXYZ:
                SkDebugf("XYZ\n");
                break;
            case SkColorSpace_A2B::PCS::kLAB:
                SkDebugf("LAB\n");
                break;
        }
        int clutCount = 0;
        int gammaCount = 0;
        for (int i = 0; i < a2b->count(); ++i) {
            const SkColorSpace_A2B::Element& e = a2b->element(i);
            switch (e.type()) {
                case SkColorSpace_A2B::Element::Type::kGammaNamed: {
                    OutputCanvas gammaCanvas(transparentBitmap(kGammaImageWidth,
                                                               kGammaImageHeight));
                    if (FLAGS_sRGB_gamma) {
                        draw_transfer_fn(gammaCanvas.canvas(), kSRGB_SkGammaNamed, nullptr,
                                         0xFFFF9394);
                    }
                    draw_transfer_fn(gammaCanvas.canvas(), e.gammaNamed(), nullptr,
                                     0xFF000000);
                    if (!gammaCanvas.save(&outputFilenames,
                                          createOutputFilename("gamma", gammaCount++))) {
                        return -1;
                    }
                }
                break;
                case SkColorSpace_A2B::Element::Type::kGammas: {
                    OutputCanvas gammaCanvas(transparentBitmap(kGammaImageWidth,
                                                               kGammaImageHeight));
                    if (FLAGS_sRGB_gamma) {
                        draw_transfer_fn(gammaCanvas.canvas(), kSRGB_SkGammaNamed, nullptr,
                                         0xFFFF9394);
                    }
                    draw_transfer_fn(gammaCanvas.canvas(), kNonStandard_SkGammaNamed,
                                     &e.gammas(), 0xFF000000);
                    if (!gammaCanvas.save(&outputFilenames,
                                          createOutputFilename("gamma", gammaCount++))) {
                        return -1;
                    }
                }
                break;
                case SkColorSpace_A2B::Element::Type::kCLUT: {
                    const SkColorLookUpTable& clut = e.colorLUT();
                    const int cutSize = cut_size(clut, dimOrder);
                    const int clutWidth = clut.inputChannels() >= 3 ? kClutCanvasSize
                                                                    : 2 * kClutGap + cutSize;
                    const int clutHeight = clut.inputChannels() >= 4 ? kClutCanvasSize
                                                                     : 2 * kClutGap + cutSize;
                    OutputCanvas clutCanvas(transparentBitmap(clutWidth, clutHeight));
                    draw_clut(clutCanvas.canvas(), e.colorLUT(), dimOrder);
                    if (!clutCanvas.save(&outputFilenames,
                                         createOutputFilename("clut", clutCount++))) {
                        return -1;
                    }
                }
                break;
                case SkColorSpace_A2B::Element::Type::kMatrix:
                    dump_matrix(e.matrix());
                    break;
            }
        }
    }

    // marker to tell the web-tool the names of all images output
    SkDebugf("=========\n");
    for (const std::string& filename : outputFilenames) {
        SkDebugf("%s\n", filename.c_str());
    }
    if (!FLAGS_icc) {
        SkDebugf("%s\n", input);
    }
    // Also, if requested, decode and reencode the uncorrected input image.
    if (!FLAGS_uncorrected.isEmpty() && !FLAGS_icc) {
        SkBitmap bitmap;
        int width = codec->getInfo().width();
        int height = codec->getInfo().height();
        bitmap.allocN32Pixels(width, height, kOpaque_SkAlphaType == codec->getInfo().alphaType());
        SkImageInfo decodeInfo = SkImageInfo::MakeN32(width, height, kUnpremul_SkAlphaType);
        if (SkCodec::kSuccess != codec->getPixels(decodeInfo, bitmap.getPixels(),
                                                  bitmap.rowBytes())) {
            SkDebugf("Could not decode input image.\n");
            return -1;
        }
        sk_sp<SkData> out = sk_tool_utils::EncodeImageToData(bitmap, SkEncodedImageFormat::kPNG,
                                                             100);
        if (!out) {
            SkDebugf("Failed to encode uncorrected image.\n");
            return -1;
        }
        SkFILEWStream bitmapStream(FLAGS_uncorrected[0]);
        if (!bitmapStream.write(out->data(), out->size())) {
            SkDebugf("Failed to write uncorrected image output.\n");
            return -1;
        }
        SkDebugf("%s\n", FLAGS_uncorrected[0]);
    }

    return 0;
}
