// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ui/libgtk2ui/skia_utils_gtk2.h"

#include <gdk/gdk.h>

#include "base/basictypes.h"
#include "base/logging.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkUnPreMultiply.h"

namespace libgtk2ui {

const int kSkiaToGDKMultiplier = 257;

// GDK_COLOR_RGB multiplies by 257 (= 0x10001) to distribute the bits evenly
// See: http://www.mindcontrol.org/~hplus/graphics/expand-bits.html
// To get back, we can just right shift by eight
// (or, formulated differently, i == (i*257)/256 for all i < 256).

SkColor GdkColorToSkColor(GdkColor color) {
  return SkColorSetRGB(color.red >> 8, color.green >> 8, color.blue >> 8);
}

GdkColor SkColorToGdkColor(SkColor color) {
  GdkColor gdk_color = {
      0,
      static_cast<guint16>(SkColorGetR(color) * kSkiaToGDKMultiplier),
      static_cast<guint16>(SkColorGetG(color) * kSkiaToGDKMultiplier),
      static_cast<guint16>(SkColorGetB(color) * kSkiaToGDKMultiplier)
  };
  return gdk_color;
}

const SkBitmap GdkPixbufToImageSkia(GdkPixbuf* pixbuf) {
  // TODO(erg): What do we do in the case where the pixbuf fails these dchecks?
  // I would prefer to use our gtk based canvas, but that would require
  // recompiling half of our skia extensions with gtk support, which we can't
  // do in this build.
  DCHECK_EQ(GDK_COLORSPACE_RGB, gdk_pixbuf_get_colorspace(pixbuf));

  int n_channels = gdk_pixbuf_get_n_channels(pixbuf);
  int w = gdk_pixbuf_get_width(pixbuf);
  int h = gdk_pixbuf_get_height(pixbuf);

  SkBitmap ret;
  ret.setConfig(SkBitmap::kARGB_8888_Config, w, h);
  ret.allocPixels();
  ret.eraseColor(0);

  uint32_t* skia_data = static_cast<uint32_t*>(ret.getAddr(0, 0));

  if (n_channels == 4) {
    int total_length = w * h;
    guchar* gdk_pixels = gdk_pixbuf_get_pixels(pixbuf);

    // Now here's the trick: we need to convert the gdk data (which is RGBA and
    // isn't premultiplied) to skia (which can be anything and premultiplied).
    for (int i = 0; i < total_length; ++i, gdk_pixels += 4) {
      const unsigned char& red = gdk_pixels[0];
      const unsigned char& green = gdk_pixels[1];
      const unsigned char& blue = gdk_pixels[2];
      const unsigned char& alpha = gdk_pixels[3];

      skia_data[i] = SkPreMultiplyARGB(alpha, red, green, blue);
    }
  } else if (n_channels == 3) {
    // Because GDK makes rowstrides word aligned, we need to do something a bit
    // more complex when a pixel isn't perfectly a word of memory.
    int rowstride = gdk_pixbuf_get_rowstride(pixbuf);
    guchar* gdk_pixels = gdk_pixbuf_get_pixels(pixbuf);
    for (int y = 0; y < h; ++y) {
      int row = y * rowstride;

      for (int x = 0; x < w; ++x) {
        guchar* pixel = gdk_pixels + row + (x * 3);
        const unsigned char& red = pixel[0];
        const unsigned char& green = pixel[1];
        const unsigned char& blue = pixel[2];

        skia_data[y * w + x] = SkPreMultiplyARGB(255, red, green, blue);
      }
    }
  } else {
    NOTREACHED();
  }

  return ret;
}

GdkPixbuf* GdkPixbufFromSkBitmap(const SkBitmap& bitmap) {
  if (bitmap.isNull())
    return NULL;

  SkAutoLockPixels lock_pixels(bitmap);

  int width = bitmap.width();
  int height = bitmap.height();

  GdkPixbuf* pixbuf =
      gdk_pixbuf_new(GDK_COLORSPACE_RGB,  // The only colorspace gtk supports.
                     TRUE,                // There is an alpha channel.
                     8,
                     width,
                     height);

  // SkBitmaps are premultiplied, we need to unpremultiply them.
  const int kBytesPerPixel = 4;
  uint8* divided = gdk_pixbuf_get_pixels(pixbuf);

  for (int y = 0, i = 0; y < height; y++) {
    for (int x = 0; x < width; x++) {
      uint32 pixel = bitmap.getAddr32(0, y)[x];

      int alpha = SkColorGetA(pixel);
      if (alpha != 0 && alpha != 255) {
        SkColor unmultiplied = SkUnPreMultiply::PMColorToColor(pixel);
        divided[i + 0] = SkColorGetR(unmultiplied);
        divided[i + 1] = SkColorGetG(unmultiplied);
        divided[i + 2] = SkColorGetB(unmultiplied);
        divided[i + 3] = alpha;
      } else {
        divided[i + 0] = SkColorGetR(pixel);
        divided[i + 1] = SkColorGetG(pixel);
        divided[i + 2] = SkColorGetB(pixel);
        divided[i + 3] = alpha;
      }
      i += kBytesPerPixel;
    }
  }

  return pixbuf;
}

}  // namespace libgtk2ui
