SkImagePriv.cpp revision d28ba8010c6058bf073f7e815d5b2d7fdf698601
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 8889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com#include "SkImagePriv.h" 970e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org#include "SkCanvas.h" 1070e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org#include "SkPicture.h" 11889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com 12889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.comSkBitmap::Config SkImageInfoToBitmapConfig(const SkImage::Info& info, 13889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com bool* isOpaque) { 14889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com switch (info.fColorType) { 15889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com case SkImage::kAlpha_8_ColorType: 16889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com switch (info.fAlphaType) { 17d28ba8010c6058bf073f7e815d5b2d7fdf698601reed@google.com case kIgnore_SkAlphaType: 18889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com // makes no sense 19889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com return SkBitmap::kNo_Config; 20889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com 21d28ba8010c6058bf073f7e815d5b2d7fdf698601reed@google.com case kOpaque_SkAlphaType: 22889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com *isOpaque = true; 23889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com return SkBitmap::kA8_Config; 24889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com 25d28ba8010c6058bf073f7e815d5b2d7fdf698601reed@google.com case kPremul_SkAlphaType: 26d28ba8010c6058bf073f7e815d5b2d7fdf698601reed@google.com case kUnpremul_SkAlphaType: 27889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com *isOpaque = false; 28889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com return SkBitmap::kA8_Config; 29889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com } 30889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com break; 31889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com 32889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com case SkImage::kRGB_565_ColorType: 33889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com // we ignore fAlpahType, though some would not make sense 34889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com *isOpaque = true; 35889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com return SkBitmap::kRGB_565_Config; 36889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com 37889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com case SkImage::kPMColor_ColorType: 38889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com switch (info.fAlphaType) { 39d28ba8010c6058bf073f7e815d5b2d7fdf698601reed@google.com case kIgnore_SkAlphaType: 40d28ba8010c6058bf073f7e815d5b2d7fdf698601reed@google.com case kUnpremul_SkAlphaType: 41889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com // not supported yet 42889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com return SkBitmap::kNo_Config; 43d28ba8010c6058bf073f7e815d5b2d7fdf698601reed@google.com case kOpaque_SkAlphaType: 44889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com *isOpaque = true; 45889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com return SkBitmap::kARGB_8888_Config; 46d28ba8010c6058bf073f7e815d5b2d7fdf698601reed@google.com case kPremul_SkAlphaType: 47889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com *isOpaque = false; 48889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com return SkBitmap::kARGB_8888_Config; 49889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com } 50889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com break; 51d28ba8010c6058bf073f7e815d5b2d7fdf698601reed@google.com 52d28ba8010c6058bf073f7e815d5b2d7fdf698601reed@google.com default: 53d28ba8010c6058bf073f7e815d5b2d7fdf698601reed@google.com // break for unsupported colortypes 54d28ba8010c6058bf073f7e815d5b2d7fdf698601reed@google.com break; 55889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com } 56889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com return SkBitmap::kNo_Config; 57889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com} 58889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com 59889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.comint SkImageBytesPerPixel(SkImage::ColorType ct) { 60889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com static const uint8_t gColorTypeBytesPerPixel[] = { 61889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com 1, // kAlpha_8_ColorType 62889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com 2, // kRGB_565_ColorType 63889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com 4, // kRGBA_8888_ColorType 64889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com 4, // kBGRA_8888_ColorType 65889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com 4, // kPMColor_ColorType 66889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com }; 67889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com 68889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com SkASSERT((size_t)ct < SK_ARRAY_COUNT(gColorTypeBytesPerPixel)); 69889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com return gColorTypeBytesPerPixel[ct]; 70889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com} 71889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com 72889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.combool SkBitmapToImageInfo(const SkBitmap& bm, SkImage::Info* info) { 73889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com switch (bm.config()) { 74889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com case SkBitmap::kA8_Config: 75889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com info->fColorType = SkImage::kAlpha_8_ColorType; 76889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com break; 77889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com 78889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com case SkBitmap::kRGB_565_Config: 79889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com info->fColorType = SkImage::kRGB_565_ColorType; 80889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com break; 81fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 82889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com case SkBitmap::kARGB_8888_Config: 83889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com info->fColorType = SkImage::kPMColor_ColorType; 84889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com break; 85fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 86889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com default: 87889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com return false; 88889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com } 89fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 90889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com info->fWidth = bm.width(); 91889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com info->fHeight = bm.height(); 92d28ba8010c6058bf073f7e815d5b2d7fdf698601reed@google.com info->fAlphaType = bm.isOpaque() ? kOpaque_SkAlphaType : 93d28ba8010c6058bf073f7e815d5b2d7fdf698601reed@google.com kPremul_SkAlphaType; 94889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com return true; 95889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com} 96889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com 9797af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.comSkImage* SkNewImageFromBitmap(const SkBitmap& bm, bool canSharePixelRef) { 98889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com SkImage::Info info; 99889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com if (!SkBitmapToImageInfo(bm, &info)) { 100889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com return NULL; 101889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com } 102889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com 103889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com SkImage* image = NULL; 10497af1a64ae6bdddd346d8babfd9f188279dd6644reed@google.com if (canSharePixelRef || bm.isImmutable()) { 105889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com image = SkNewImageFromPixelRef(info, bm.pixelRef(), bm.rowBytes()); 106889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com } else { 107889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com bm.lockPixels(); 10870e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org if (bm.getPixels()) { 109b947625800a26194fcf63d7b57dadb1a63677f6amike@reedtribe.org image = SkImage::NewRasterCopy(info, bm.getPixels(), bm.rowBytes()); 110889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com } 111889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com bm.unlockPixels(); 112889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com } 113889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com return image; 114889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com} 115889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com 11670e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.orgstatic bool needs_layer(const SkPaint& paint) { 11770e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org return 0xFF != paint.getAlpha() || 11870e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org paint.getColorFilter() || 11970e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org paint.getImageFilter() || 12070e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode); 12170e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org} 12270e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org 12370e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.orgvoid SkImagePrivDrawPicture(SkCanvas* canvas, SkPicture* picture, 12470e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org SkScalar x, SkScalar y, const SkPaint* paint) { 12570e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org int saveCount = canvas->getSaveCount(); 126fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 12770e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org if (paint && needs_layer(*paint)) { 12870e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org SkRect bounds; 12970e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org bounds.set(x, y, 13070e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org x + SkIntToScalar(picture->width()), 13170e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org y + SkIntToScalar(picture->height())); 13270e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org canvas->saveLayer(&bounds, paint); 1339ea5a3bc7361cb88d37280b5922fba9430fed328reed@google.com canvas->translate(x, y); 13470e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org } else if (x || y) { 13570e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org canvas->save(); 1369ea5a3bc7361cb88d37280b5922fba9430fed328reed@google.com canvas->translate(x, y); 13770e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org } 138fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 13970e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org canvas->drawPicture(*picture); 14070e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org canvas->restoreToCount(saveCount); 14170e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org} 142dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org 143dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.orgvoid SkImagePrivDrawPicture(SkCanvas* canvas, SkPicture* picture, 1447f1af501f206da48a7ff791af53432c9c1c89d08skia.committer@gmail.com const SkRect* src, const SkRect& dst, const SkPaint* paint) { 1457f1af501f206da48a7ff791af53432c9c1c89d08skia.committer@gmail.com int saveCount = canvas->getSaveCount(); 146dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org 147dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org SkMatrix matrix; 148dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org SkRect tmpSrc; 149dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org 150dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org if (NULL != src) { 151dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org tmpSrc = *src; 152dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org } else { 153dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org tmpSrc.set(0, 0, 154dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org SkIntToScalar(picture->width()), 155dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org SkIntToScalar(picture->height())); 156dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org } 157dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org 158dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org matrix.setRectToRect(tmpSrc, dst, SkMatrix::kFill_ScaleToFit); 159dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org if (paint && needs_layer(*paint)) { 160dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org canvas->saveLayer(&dst, paint); 161dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org } else { 162dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org canvas->save(); 163dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org } 164dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org canvas->concat(matrix); 165dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org if (!paint || !needs_layer(*paint)) { 166dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org canvas->clipRect(tmpSrc); 167dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org } 1687f1af501f206da48a7ff791af53432c9c1c89d08skia.committer@gmail.com 169dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org canvas->drawPicture(*picture); 170dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org canvas->restoreToCount(saveCount); 171dfec28d4a9e05d1d525f377b380b4df3c5e07c7bcommit-bot@chromium.org} 172