1557152d10b1fcac78e82e8db946e1c998879be60reed@google.com/* 2557152d10b1fcac78e82e8db946e1c998879be60reed@google.com * Copyright 2012 Google Inc. 3557152d10b1fcac78e82e8db946e1c998879be60reed@google.com * 4557152d10b1fcac78e82e8db946e1c998879be60reed@google.com * Use of this source code is governed by a BSD-style license that can be 5557152d10b1fcac78e82e8db946e1c998879be60reed@google.com * found in the LICENSE file. 6557152d10b1fcac78e82e8db946e1c998879be60reed@google.com */ 7557152d10b1fcac78e82e8db946e1c998879be60reed@google.com 8248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com#include "SkImagePriv.h" 9843d95b34a971e0cbaf3deb695fd5989e0c1dfdemike@reedtribe.org#include "SkCanvas.h" 10843d95b34a971e0cbaf3deb695fd5989e0c1dfdemike@reedtribe.org#include "SkPicture.h" 11248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com 12248ec25fa948c09fec34883bf673e56c2048bd3freed@google.comSkBitmap::Config SkImageInfoToBitmapConfig(const SkImage::Info& info, 13248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com bool* isOpaque) { 14248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com switch (info.fColorType) { 15248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com case SkImage::kAlpha_8_ColorType: 16248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com switch (info.fAlphaType) { 17248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com case SkImage::kIgnore_AlphaType: 18248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com // makes no sense 19248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com return SkBitmap::kNo_Config; 20248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com 21248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com case SkImage::kOpaque_AlphaType: 22248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com *isOpaque = true; 23248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com return SkBitmap::kA8_Config; 24248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com 25248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com case SkImage::kPremul_AlphaType: 26248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com case SkImage::kUnpremul_AlphaType: 27248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com *isOpaque = false; 28248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com return SkBitmap::kA8_Config; 29248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com } 30248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com break; 31248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com 32248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com case SkImage::kRGB_565_ColorType: 33248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com // we ignore fAlpahType, though some would not make sense 34248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com *isOpaque = true; 35248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com return SkBitmap::kRGB_565_Config; 36248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com 37248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com case SkImage::kRGBA_8888_ColorType: 38248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com case SkImage::kBGRA_8888_ColorType: 39248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com // not supported yet 40248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com return SkBitmap::kNo_Config; 41248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com 42248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com case SkImage::kPMColor_ColorType: 43248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com switch (info.fAlphaType) { 44248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com case SkImage::kIgnore_AlphaType: 45248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com case SkImage::kUnpremul_AlphaType: 46248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com // not supported yet 47248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com return SkBitmap::kNo_Config; 48248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com case SkImage::kOpaque_AlphaType: 49248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com *isOpaque = true; 50248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com return SkBitmap::kARGB_8888_Config; 51248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com case SkImage::kPremul_AlphaType: 52248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com *isOpaque = false; 53248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com return SkBitmap::kARGB_8888_Config; 54248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com } 55248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com break; 56248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com } 57248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com SkASSERT(!"how did we get here"); 58248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com return SkBitmap::kNo_Config; 59248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com} 60248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com 61248ec25fa948c09fec34883bf673e56c2048bd3freed@google.comint SkImageBytesPerPixel(SkImage::ColorType ct) { 62248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com static const uint8_t gColorTypeBytesPerPixel[] = { 63248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com 1, // kAlpha_8_ColorType 64248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com 2, // kRGB_565_ColorType 65248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com 4, // kRGBA_8888_ColorType 66248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com 4, // kBGRA_8888_ColorType 67248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com 4, // kPMColor_ColorType 68248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com }; 69248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com 70248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com SkASSERT((size_t)ct < SK_ARRAY_COUNT(gColorTypeBytesPerPixel)); 71248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com return gColorTypeBytesPerPixel[ct]; 72248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com} 73248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com 74248ec25fa948c09fec34883bf673e56c2048bd3freed@google.combool SkBitmapToImageInfo(const SkBitmap& bm, SkImage::Info* info) { 75248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com switch (bm.config()) { 76248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com case SkBitmap::kA8_Config: 77248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com info->fColorType = SkImage::kAlpha_8_ColorType; 78248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com break; 79248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com 80248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com case SkBitmap::kRGB_565_Config: 81248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com info->fColorType = SkImage::kRGB_565_ColorType; 82248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com break; 83935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com 84248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com case SkBitmap::kARGB_8888_Config: 85248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com info->fColorType = SkImage::kPMColor_ColorType; 86248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com break; 87935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com 88248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com default: 89248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com return false; 90248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com } 91935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com 92248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com info->fWidth = bm.width(); 93248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com info->fHeight = bm.height(); 94248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com info->fAlphaType = bm.isOpaque() ? SkImage::kOpaque_AlphaType : 95248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com SkImage::kPremul_AlphaType; 96248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com return true; 97248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com} 98248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com 992ffcbf828d03b8e32ffc93b1b0ee8a98faeaa51ereed@google.comSkImage* SkNewImageFromBitmap(const SkBitmap& bm, bool canSharePixelRef) { 100248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com SkImage::Info info; 101248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com if (!SkBitmapToImageInfo(bm, &info)) { 102248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com return NULL; 103248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com } 104248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com 105248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com SkImage* image = NULL; 1062ffcbf828d03b8e32ffc93b1b0ee8a98faeaa51ereed@google.com if (canSharePixelRef || bm.isImmutable()) { 107248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com image = SkNewImageFromPixelRef(info, bm.pixelRef(), bm.rowBytes()); 108248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com } else { 109248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com bm.lockPixels(); 110843d95b34a971e0cbaf3deb695fd5989e0c1dfdemike@reedtribe.org if (bm.getPixels()) { 111b42b493aef62c04c5cbdacdffe984bec5c76648cmike@reedtribe.org image = SkImage::NewRasterCopy(info, bm.getPixels(), bm.rowBytes()); 112248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com } 113248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com bm.unlockPixels(); 114248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com } 115248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com return image; 116248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com} 117248ec25fa948c09fec34883bf673e56c2048bd3freed@google.com 118843d95b34a971e0cbaf3deb695fd5989e0c1dfdemike@reedtribe.orgstatic bool needs_layer(const SkPaint& paint) { 119843d95b34a971e0cbaf3deb695fd5989e0c1dfdemike@reedtribe.org return 0xFF != paint.getAlpha() || 120843d95b34a971e0cbaf3deb695fd5989e0c1dfdemike@reedtribe.org paint.getColorFilter() || 121843d95b34a971e0cbaf3deb695fd5989e0c1dfdemike@reedtribe.org paint.getImageFilter() || 122843d95b34a971e0cbaf3deb695fd5989e0c1dfdemike@reedtribe.org SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode); 123843d95b34a971e0cbaf3deb695fd5989e0c1dfdemike@reedtribe.org} 124843d95b34a971e0cbaf3deb695fd5989e0c1dfdemike@reedtribe.org 125843d95b34a971e0cbaf3deb695fd5989e0c1dfdemike@reedtribe.orgvoid SkImagePrivDrawPicture(SkCanvas* canvas, SkPicture* picture, 126843d95b34a971e0cbaf3deb695fd5989e0c1dfdemike@reedtribe.org SkScalar x, SkScalar y, const SkPaint* paint) { 127843d95b34a971e0cbaf3deb695fd5989e0c1dfdemike@reedtribe.org int saveCount = canvas->getSaveCount(); 128935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com 129843d95b34a971e0cbaf3deb695fd5989e0c1dfdemike@reedtribe.org if (paint && needs_layer(*paint)) { 130843d95b34a971e0cbaf3deb695fd5989e0c1dfdemike@reedtribe.org SkRect bounds; 131843d95b34a971e0cbaf3deb695fd5989e0c1dfdemike@reedtribe.org bounds.set(x, y, 132843d95b34a971e0cbaf3deb695fd5989e0c1dfdemike@reedtribe.org x + SkIntToScalar(picture->width()), 133843d95b34a971e0cbaf3deb695fd5989e0c1dfdemike@reedtribe.org y + SkIntToScalar(picture->height())); 134843d95b34a971e0cbaf3deb695fd5989e0c1dfdemike@reedtribe.org canvas->saveLayer(&bounds, paint); 13521f61024c088345bbdf306c9dcfdcef7096752bereed@google.com canvas->translate(x, y); 136843d95b34a971e0cbaf3deb695fd5989e0c1dfdemike@reedtribe.org } else if (x || y) { 137843d95b34a971e0cbaf3deb695fd5989e0c1dfdemike@reedtribe.org canvas->save(); 13821f61024c088345bbdf306c9dcfdcef7096752bereed@google.com canvas->translate(x, y); 139843d95b34a971e0cbaf3deb695fd5989e0c1dfdemike@reedtribe.org } 140935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com 141843d95b34a971e0cbaf3deb695fd5989e0c1dfdemike@reedtribe.org canvas->drawPicture(*picture); 142843d95b34a971e0cbaf3deb695fd5989e0c1dfdemike@reedtribe.org canvas->restoreToCount(saveCount); 143843d95b34a971e0cbaf3deb695fd5989e0c1dfdemike@reedtribe.org} 144b71e1b41724c00f4b4b52b371e4254674fb4a027commit-bot@chromium.org 145b71e1b41724c00f4b4b52b371e4254674fb4a027commit-bot@chromium.orgvoid SkImagePrivDrawPicture(SkCanvas* canvas, SkPicture* picture, 146fb9ab0f1780a8cf15fc886fad439e95818d264d6skia.committer@gmail.com const SkRect* src, const SkRect& dst, const SkPaint* paint) { 147fb9ab0f1780a8cf15fc886fad439e95818d264d6skia.committer@gmail.com int saveCount = canvas->getSaveCount(); 148b71e1b41724c00f4b4b52b371e4254674fb4a027commit-bot@chromium.org 149b71e1b41724c00f4b4b52b371e4254674fb4a027commit-bot@chromium.org SkMatrix matrix; 150b71e1b41724c00f4b4b52b371e4254674fb4a027commit-bot@chromium.org SkRect tmpSrc; 151b71e1b41724c00f4b4b52b371e4254674fb4a027commit-bot@chromium.org 152b71e1b41724c00f4b4b52b371e4254674fb4a027commit-bot@chromium.org if (NULL != src) { 153b71e1b41724c00f4b4b52b371e4254674fb4a027commit-bot@chromium.org tmpSrc = *src; 154b71e1b41724c00f4b4b52b371e4254674fb4a027commit-bot@chromium.org } else { 155b71e1b41724c00f4b4b52b371e4254674fb4a027commit-bot@chromium.org tmpSrc.set(0, 0, 156b71e1b41724c00f4b4b52b371e4254674fb4a027commit-bot@chromium.org SkIntToScalar(picture->width()), 157b71e1b41724c00f4b4b52b371e4254674fb4a027commit-bot@chromium.org SkIntToScalar(picture->height())); 158b71e1b41724c00f4b4b52b371e4254674fb4a027commit-bot@chromium.org } 159b71e1b41724c00f4b4b52b371e4254674fb4a027commit-bot@chromium.org 160b71e1b41724c00f4b4b52b371e4254674fb4a027commit-bot@chromium.org matrix.setRectToRect(tmpSrc, dst, SkMatrix::kFill_ScaleToFit); 161b71e1b41724c00f4b4b52b371e4254674fb4a027commit-bot@chromium.org if (paint && needs_layer(*paint)) { 162b71e1b41724c00f4b4b52b371e4254674fb4a027commit-bot@chromium.org canvas->saveLayer(&dst, paint); 163b71e1b41724c00f4b4b52b371e4254674fb4a027commit-bot@chromium.org } else { 164b71e1b41724c00f4b4b52b371e4254674fb4a027commit-bot@chromium.org canvas->save(); 165b71e1b41724c00f4b4b52b371e4254674fb4a027commit-bot@chromium.org } 166b71e1b41724c00f4b4b52b371e4254674fb4a027commit-bot@chromium.org canvas->concat(matrix); 167b71e1b41724c00f4b4b52b371e4254674fb4a027commit-bot@chromium.org if (!paint || !needs_layer(*paint)) { 168b71e1b41724c00f4b4b52b371e4254674fb4a027commit-bot@chromium.org canvas->clipRect(tmpSrc); 169b71e1b41724c00f4b4b52b371e4254674fb4a027commit-bot@chromium.org } 170fb9ab0f1780a8cf15fc886fad439e95818d264d6skia.committer@gmail.com 171b71e1b41724c00f4b4b52b371e4254674fb4a027commit-bot@chromium.org canvas->drawPicture(*picture); 172b71e1b41724c00f4b4b52b371e4254674fb4a027commit-bot@chromium.org canvas->restoreToCount(saveCount); 173b71e1b41724c00f4b4b52b371e4254674fb4a027commit-bot@chromium.org} 174