/*
 * 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 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,  SkSurface::kYes_Budgeted, 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::CreateRadial(SkPoint::Make(0,0), r, kColors,
                                                   nullptr, SK_ARRAY_COUNT(kColors),
                                                   SkShader::kMirror_TileMode))->unref();

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

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();
    SkAutoTUnref<SkImage> rgbImage(create_image(context, kImageSize, kImageSize));
    if (!rgbImage) {
        return;
    }

    canvas->drawImage(rgbImage, 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;
    }
}
