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

#include "picture_utils.h"
#include "SkBitmap.h"
#include "SkColorPriv.h"
#include "SkHalf.h"
#include "SkImageEncoder.h"
#include "SkOSFile.h"
#include "SkOSPath.h"
#include "SkPM4fPriv.h"
#include "SkPicture.h"
#include "SkStream.h"
#include "SkString.h"

#include "sk_tool_utils.h"

namespace sk_tools {
    void force_all_opaque(const SkBitmap& bitmap) {
        SkASSERT(kN32_SkColorType == bitmap.colorType());
        if (kN32_SkColorType == bitmap.colorType()) {
            return;
        }

        SkAutoLockPixels lock(bitmap);
        for (int y = 0; y < bitmap.height(); y++) {
            for (int x = 0; x < bitmap.width(); x++) {
                *bitmap.getAddr32(x, y) |= (SK_A32_MASK << SK_A32_SHIFT);
            }
        }
    }

    void replace_char(SkString* str, const char oldChar, const char newChar) {
        if (nullptr == str) {
            return;
        }
        for (size_t i = 0; i < str->size(); ++i) {
            if (oldChar == str->operator[](i)) {
                str->operator[](i) = newChar;
            }
        }
    }

    bool is_percentage(const char* const string) {
        SkString skString(string);
        return skString.endsWith("%");
    }

    void setup_bitmap(SkBitmap* bitmap, int width, int height) {
        bitmap->allocN32Pixels(width, height);
        bitmap->eraseColor(SK_ColorTRANSPARENT);
    }

    bool write_bitmap_to_disk(const SkBitmap& bm, const SkString& dirPath,
                              const char *subdirOrNull, const SkString& baseName) {
        SkString partialPath;
        if (subdirOrNull) {
            partialPath = SkOSPath::Join(dirPath.c_str(), subdirOrNull);
            sk_mkdir(partialPath.c_str());
        } else {
            partialPath.set(dirPath);
        }
        SkString fullPath = SkOSPath::Join(partialPath.c_str(), baseName.c_str());
        if (sk_tool_utils::EncodeImageToFile(fullPath.c_str(), bm, SkEncodedImageFormat::kPNG, 100)) {
            return true;
        } else {
            SkDebugf("Failed to write the bitmap to %s.\n", fullPath.c_str());
            return false;
        }
    }

    sk_sp<SkData> encode_bitmap_for_png(SkBitmap bitmap) {
        const int w = bitmap.width(),
                h = bitmap.height();
        // PNG wants unpremultiplied 8-bit RGBA pixels (16-bit could work fine too).
        // We leave the gamma of these bytes unspecified, to continue the status quo,
        // which we think generally is to interpret them as sRGB.

        SkAutoTMalloc<uint32_t> rgba(w*h);

        auto srgbColorSpace = SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named);
        if (bitmap. colorType() ==  kN32_SkColorType &&
            bitmap.colorSpace() == srgbColorSpace.get()) {
            // These are premul sRGB 8-bit pixels in SkPMColor order.
            // We want unpremul sRGB 8-bit pixels in RGBA order.  We'll get there via floats.
            bitmap.lockPixels();
            auto px = (const uint32_t*)bitmap.getPixels();
            if (!px) {
                return nullptr;
            }
            for (int i = 0; i < w*h; i++) {
                Sk4f fs = Sk4f_fromS32(px[i]);         // Convert up to linear floats.
#if defined(SK_PMCOLOR_IS_BGRA)
                fs = SkNx_shuffle<2,1,0,3>(fs);        // Shuffle to RGBA, if not there already.
#endif
                float invA = 1.0f / fs[3];
                fs = fs * Sk4f(invA, invA, invA, 1);   // Unpremultiply.
                rgba[i] = Sk4f_toS32(fs);              // Pack down to sRGB bytes.
            }

        } else if (bitmap.colorType() == kRGBA_F16_SkColorType) {
            // These are premul linear half-float pixels in RGBA order.
            // We want unpremul sRGB 8-bit pixels in RGBA order.  We'll get there via floats.
            bitmap.lockPixels();
            auto px = (const uint64_t*)bitmap.getPixels();
            if (!px) {
                return nullptr;
            }
            for (int i = 0; i < w*h; i++) {
                // Convert up to linear floats.
                Sk4f fs(SkHalfToFloat(static_cast<SkHalf>(px[i] >> (0 * 16))),
                        SkHalfToFloat(static_cast<SkHalf>(px[i] >> (1 * 16))),
                        SkHalfToFloat(static_cast<SkHalf>(px[i] >> (2 * 16))),
                        SkHalfToFloat(static_cast<SkHalf>(px[i] >> (3 * 16))));
                fs = Sk4f::Max(0.0f, Sk4f::Min(fs, 1.0f));  // Clamp
                float invA = 1.0f / fs[3];
                fs = fs * Sk4f(invA, invA, invA, 1);  // Unpremultiply.
                rgba[i] = Sk4f_toS32(fs);             // Pack down to sRGB bytes.
            }

        } else {
            // We "should" gamma correct in here but we don't.
            // We want Gold to show exactly what our clients are seeing, broken gamma.

            // Convert smaller formats up to premul linear 8-bit (in SkPMColor order).
            if (bitmap.colorType() != kN32_SkColorType) {
                SkBitmap n32;
                if (!bitmap.copyTo(&n32, kN32_SkColorType)) {
                    return nullptr;
                }
                bitmap = n32;
            }

            // Convert premul linear 8-bit to unpremul linear 8-bit RGBA.
            if (!bitmap.readPixels(SkImageInfo::Make(w,h, kRGBA_8888_SkColorType,
                                                     kUnpremul_SkAlphaType),
                                   rgba, 4*w, 0,0)) {
                return nullptr;
            }
        }

        return SkData::MakeFromMalloc(rgba.release(), w*h*sizeof(uint32_t));
    }

} // namespace sk_tools
