/*
 * 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 <SkSurface.h>
#include "gm.h"
#include "SkBitmap.h"
#include "SkGradientShader.h"
#include "SkImage.h"

static sk_sp<SkImage> create_image(GrContext* context, int width, int height) {
    SkAutoTUnref<SkSurface> surface;
    SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
    if (context) {
        surface.reset(SkSurface::NewRenderTarget(context,  SkBudgeted::kYes, info, 0));
    } else {
        surface.reset(SkSurface::NewRaster(info));
    }
    if (!surface) {
        return nullptr;
    }
    // Create an RGB image from which we will extract planes
    SkPaint paint;
    static const SkColor kColors[] =
            { SK_ColorBLUE, SK_ColorYELLOW, SK_ColorGREEN, SK_ColorWHITE };
    SkScalar r = (width + height) / 4.f;
    paint.setShader(SkGradientShader::MakeRadial(SkPoint::Make(0,0), r, kColors,
                                                 nullptr, SK_ARRAY_COUNT(kColors),
                                                 SkShader::kMirror_TileMode));

    surface->getCanvas()->drawPaint(paint);
    return surface->makeImageSnapshot();
}

DEF_SIMPLE_GM(image_to_yuv_planes, canvas, 120, 525) {
    static const SkScalar kPad = 5.f;
    static const int kImageSize = 32;

    GrContext *context = canvas->getGrContext();
    sk_sp<SkImage> rgbImage(create_image(context, kImageSize, kImageSize));
    if (!rgbImage) {
        return;
    }

    canvas->drawImage(rgbImage.get(), kPad, kPad);
    // Test cases where all three planes are the same size, where just u and v are the same size,
    // and where all differ.
    static const SkISize kSizes[][3] = {
        {{kImageSize, kImageSize}, {kImageSize  , kImageSize  }, {kImageSize,   kImageSize  }},
        {{kImageSize, kImageSize}, {kImageSize/2, kImageSize/2}, {kImageSize/2, kImageSize/2}},
        {{kImageSize, kImageSize}, {kImageSize/2, kImageSize/2}, {kImageSize/3, kImageSize/3}}
    };

    // A mix of rowbytes triples to go with the above sizes.
    static const size_t kRowBytes[][3] {
        {0, 0, 0},
        {kImageSize, kImageSize/2 + 1, kImageSize},
        {kImageSize + 13, kImageSize, kImageSize/3 + 8}
    };


    SkScalar x = kPad;
    for (size_t s = 0; s < SK_ARRAY_COUNT(kSizes); ++s) {
        SkScalar y = rgbImage->height() + 2 * kPad;

        const SkISize *sizes = kSizes[s];
        size_t realRowBytes[3];
        for (int i = 0; i < 3; ++i) {
            realRowBytes[i] = kRowBytes[s][i] ? kRowBytes[s][i] : kSizes[s][i].fWidth;
        }
        SkAutoTDeleteArray<uint8_t> yPlane(new uint8_t[realRowBytes[0] * sizes[0].fHeight]);
        SkAutoTDeleteArray<uint8_t> uPlane(new uint8_t[realRowBytes[1] * sizes[1].fHeight]);
        SkAutoTDeleteArray<uint8_t> vPlane(new uint8_t[realRowBytes[2] * sizes[2].fHeight]);

        void *planes[3] = {yPlane.get(), uPlane.get(), vPlane.get()};

        // Convert the RGB image to YUV planes using each YUV color space and draw the YUV planes
        // to the canvas.
        SkBitmap yuvBmps[3];
        yuvBmps[0].setInfo(SkImageInfo::MakeA8(sizes[0].fWidth, sizes[0].fHeight), kRowBytes[s][0]);
        yuvBmps[1].setInfo(SkImageInfo::MakeA8(sizes[1].fWidth, sizes[1].fHeight), kRowBytes[s][1]);
        yuvBmps[2].setInfo(SkImageInfo::MakeA8(sizes[2].fWidth, sizes[2].fHeight), kRowBytes[s][2]);
        yuvBmps[0].setPixels(yPlane.get());
        yuvBmps[1].setPixels(uPlane.get());
        yuvBmps[2].setPixels(vPlane.get());

        for (int space = kJPEG_SkYUVColorSpace; space <= kLastEnum_SkYUVColorSpace; ++space) {
            // Clear the planes so we don't accidentally see the old values if there is a bug in
            // readYUV8Planes().
            memset(yPlane.get(), 0, realRowBytes[0] * sizes[0].fHeight);
            memset(uPlane.get(), 0, realRowBytes[1] * sizes[1].fHeight);
            memset(vPlane.get(), 0, realRowBytes[2] * sizes[2].fHeight);
            if (rgbImage->readYUV8Planes(sizes, planes, kRowBytes[s],
                                         static_cast<SkYUVColorSpace>(space))) {
                yuvBmps[0].notifyPixelsChanged();
                yuvBmps[1].notifyPixelsChanged();
                yuvBmps[2].notifyPixelsChanged();
                for (int i = 0; i < 3; ++i) {
                    canvas->drawBitmap(yuvBmps[i], x, y);
                    y += kPad + yuvBmps[i].height();
                }
            }
        }

        x += rgbImage->width() + kPad;
    }
}
