16997ebbe5cf06c938cc893e1d0217dc4048edf82reed@google.com/* 26997ebbe5cf06c938cc893e1d0217dc4048edf82reed@google.com * Copyright 2012 Google Inc. 36997ebbe5cf06c938cc893e1d0217dc4048edf82reed@google.com * 46997ebbe5cf06c938cc893e1d0217dc4048edf82reed@google.com * Use of this source code is governed by a BSD-style license that can be 56997ebbe5cf06c938cc893e1d0217dc4048edf82reed@google.com * found in the LICENSE file. 66997ebbe5cf06c938cc893e1d0217dc4048edf82reed@google.com */ 76997ebbe5cf06c938cc893e1d0217dc4048edf82reed@google.com 8f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com#include "SkBitmap.h" 970e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org#include "SkCanvas.h" 107def5e1630d47cdbfa4b58a9c86bc060693c4d79scroggo@google.com#include "SkImagePriv.h" 117def5e1630d47cdbfa4b58a9c86bc060693c4d79scroggo@google.com#include "SkImage_Base.h" 12f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com 137def5e1630d47cdbfa4b58a9c86bc060693c4d79scroggo@google.comstatic SkImage_Base* as_IB(SkImage* image) { 14f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com return static_cast<SkImage_Base*>(image); 15f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com} 16f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com 177def5e1630d47cdbfa4b58a9c86bc060693c4d79scroggo@google.comstatic const SkImage_Base* as_IB(const SkImage* image) { 187def5e1630d47cdbfa4b58a9c86bc060693c4d79scroggo@google.com return static_cast<const SkImage_Base*>(image); 197def5e1630d47cdbfa4b58a9c86bc060693c4d79scroggo@google.com} 207def5e1630d47cdbfa4b58a9c86bc060693c4d79scroggo@google.com 21f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.comuint32_t SkImage::NextUniqueID() { 22f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com static int32_t gUniqueID; 23f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com 24f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com // never return 0; 25f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com uint32_t id; 26f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com do { 27f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com id = sk_atomic_inc(&gUniqueID) + 1; 28f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com } while (0 == id); 29f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com return id; 30f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com} 31f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com 32f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.comvoid SkImage::draw(SkCanvas* canvas, SkScalar x, SkScalar y, 33f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com const SkPaint* paint) { 347def5e1630d47cdbfa4b58a9c86bc060693c4d79scroggo@google.com as_IB(this)->onDraw(canvas, x, y, paint); 35f6627b78f933b77b358ac0791c520f99b0e79fcareed@google.com} 36da90474b5fcc019fb0971d12360bd05213ad4dc8junov@chromium.org 37dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.orgvoid SkImage::draw(SkCanvas* canvas, const SkRect* src, const SkRect& dst, 38dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org const SkPaint* paint) { 39dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org as_IB(this)->onDrawRectToRect(canvas, src, dst, paint); 40dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org} 41dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org 424f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.comconst void* SkImage::peekPixels(SkImageInfo* info, size_t* rowBytes) const { 434f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com SkImageInfo infoStorage; 444f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com size_t rowBytesStorage; 454f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com if (NULL == info) { 464f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com info = &infoStorage; 474f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com } 484f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com if (NULL == rowBytes) { 494f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com rowBytes = &rowBytesStorage; 504f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com } 514f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com return as_IB(this)->onPeekPixels(info, rowBytes); 524f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com} 534f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com 544f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.combool SkImage::readPixels(SkBitmap* bitmap, const SkIRect* subset) const { 554f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com if (NULL == bitmap) { 564f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com return false; 574f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com } 585e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org 594f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com SkIRect bounds = SkIRect::MakeWH(this->width(), this->height()); 604f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com 614f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com // trim against the bitmap, if its already been allocated 624f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com if (bitmap->pixelRef()) { 634f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com bounds.fRight = SkMin32(bounds.fRight, bitmap->width()); 644f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com bounds.fBottom = SkMin32(bounds.fBottom, bitmap->height()); 654f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com if (bounds.isEmpty()) { 664f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com return false; 674f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com } 684f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com } 694f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com 704f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com if (subset && !bounds.intersect(*subset)) { 714f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com // perhaps we could return true + empty-bitmap? 724f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com return false; 734f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com } 744f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com return as_IB(this)->onReadPixels(bitmap, bounds); 754f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com} 764f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com 77da90474b5fcc019fb0971d12360bd05213ad4dc8junov@chromium.orgGrTexture* SkImage::getTexture() { 787def5e1630d47cdbfa4b58a9c86bc060693c4d79scroggo@google.com return as_IB(this)->onGetTexture(); 797def5e1630d47cdbfa4b58a9c86bc060693c4d79scroggo@google.com} 807def5e1630d47cdbfa4b58a9c86bc060693c4d79scroggo@google.com 817def5e1630d47cdbfa4b58a9c86bc060693c4d79scroggo@google.comSkData* SkImage::encode(SkImageEncoder::Type type, int quality) const { 827def5e1630d47cdbfa4b58a9c86bc060693c4d79scroggo@google.com SkBitmap bm; 837def5e1630d47cdbfa4b58a9c86bc060693c4d79scroggo@google.com if (as_IB(this)->getROPixels(&bm)) { 847def5e1630d47cdbfa4b58a9c86bc060693c4d79scroggo@google.com return SkImageEncoder::EncodeData(bm, type, quality); 857def5e1630d47cdbfa4b58a9c86bc060693c4d79scroggo@google.com } 867def5e1630d47cdbfa4b58a9c86bc060693c4d79scroggo@google.com return NULL; 87da90474b5fcc019fb0971d12360bd05213ad4dc8junov@chromium.org} 884f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com 894f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com/////////////////////////////////////////////////////////////////////////////// 904f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com 914f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.comstatic bool raster_canvas_supports(const SkImageInfo& info) { 924f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com switch (info.fColorType) { 9328fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org case kN32_SkColorType: 944f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com return kUnpremul_SkAlphaType != info.fAlphaType; 954f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com case kRGB_565_SkColorType: 964f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com return true; 974f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com case kAlpha_8_SkColorType: 984f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com return true; 994f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com default: 1004f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com break; 1014f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com } 1024f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com return false; 1034f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com} 1044f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com 1054f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.combool SkImage_Base::onReadPixels(SkBitmap* bitmap, const SkIRect& subset) const { 1064f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com if (bitmap->pixelRef()) { 107466f5f3e44e703ca58b43ac1c4ac3bfa0e1ff024commit-bot@chromium.org const SkImageInfo info = bitmap->info(); 108466f5f3e44e703ca58b43ac1c4ac3bfa0e1ff024commit-bot@chromium.org if (kUnknown_SkColorType == info.colorType()) { 1094f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com return false; 1104f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com } 1114f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com if (!raster_canvas_supports(info)) { 1124f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com return false; 1134f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com } 1144f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com } else { 115466f5f3e44e703ca58b43ac1c4ac3bfa0e1ff024commit-bot@chromium.org const SkImageInfo info = SkImageInfo::MakeN32Premul(subset.width(), subset.height()); 1164f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com SkBitmap tmp; 1174f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com if (!tmp.allocPixels(info)) { 1184f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com return false; 1194f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com } 1204f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com *bitmap = tmp; 1214f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com } 1224f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com 1234f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com SkRect srcR, dstR; 1244f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com srcR.set(subset); 1254f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com dstR = srcR; 1264f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com dstR.offset(-dstR.left(), -dstR.top()); 1275e0995e4b36178e1e4465a9f50114ed39f038c27commit-bot@chromium.org 1284f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com SkCanvas canvas(*bitmap); 1294f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com 1304f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com SkPaint paint; 1314f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com paint.setXfermodeMode(SkXfermode::kClear_Mode); 1324f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com canvas.drawRect(dstR, paint); 1334f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com 1344f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com const_cast<SkImage_Base*>(this)->onDrawRectToRect(&canvas, &srcR, dstR, NULL); 1354f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com return true; 1364f7c61583b16e3056cf3350fcef42dcc6d3483b7reed@google.com} 137