SkImagePriv.cpp revision 6997ebbe5cf06c938cc893e1d0217dc4048edf82
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) { 17889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com case SkImage::kIgnore_AlphaType: 18889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com // makes no sense 19889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com return SkBitmap::kNo_Config; 20889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com 21889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com case SkImage::kOpaque_AlphaType: 22889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com *isOpaque = true; 23889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com return SkBitmap::kA8_Config; 24889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com 25889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com case SkImage::kPremul_AlphaType: 26889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com case SkImage::kUnpremul_AlphaType: 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::kRGBA_8888_ColorType: 38889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com case SkImage::kBGRA_8888_ColorType: 39889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com // not supported yet 40889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com return SkBitmap::kNo_Config; 41889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com 42889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com case SkImage::kPMColor_ColorType: 43889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com switch (info.fAlphaType) { 44889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com case SkImage::kIgnore_AlphaType: 45889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com case SkImage::kUnpremul_AlphaType: 46889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com // not supported yet 47889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com return SkBitmap::kNo_Config; 48889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com case SkImage::kOpaque_AlphaType: 49889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com *isOpaque = true; 50889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com return SkBitmap::kARGB_8888_Config; 51889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com case SkImage::kPremul_AlphaType: 52889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com *isOpaque = false; 53889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com return SkBitmap::kARGB_8888_Config; 54889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com } 55889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com break; 56889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com } 57889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com SkASSERT(!"how did we get here"); 58889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com return SkBitmap::kNo_Config; 59889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com} 60889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com 61889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.comint SkImageBytesPerPixel(SkImage::ColorType ct) { 62889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com static const uint8_t gColorTypeBytesPerPixel[] = { 63889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com 1, // kAlpha_8_ColorType 64889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com 2, // kRGB_565_ColorType 65889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com 4, // kRGBA_8888_ColorType 66889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com 4, // kBGRA_8888_ColorType 67889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com 4, // kPMColor_ColorType 68889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com }; 69889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com 70889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com SkASSERT((size_t)ct < SK_ARRAY_COUNT(gColorTypeBytesPerPixel)); 71889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com return gColorTypeBytesPerPixel[ct]; 72889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com} 73889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com 74889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.combool SkBitmapToImageInfo(const SkBitmap& bm, SkImage::Info* info) { 75889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com switch (bm.config()) { 76889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com case SkBitmap::kA8_Config: 77889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com info->fColorType = SkImage::kAlpha_8_ColorType; 78889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com break; 79889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com 80889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com case SkBitmap::kRGB_565_Config: 81889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com info->fColorType = SkImage::kRGB_565_ColorType; 82889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com break; 83889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com 84889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com case SkBitmap::kARGB_8888_Config: 85889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com info->fColorType = SkImage::kPMColor_ColorType; 86889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com break; 87889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com 88889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com default: 89889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com return false; 90889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com } 91889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com 92889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com info->fWidth = bm.width(); 93889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com info->fHeight = bm.height(); 94889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com info->fAlphaType = bm.isOpaque() ? SkImage::kOpaque_AlphaType : 95889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com SkImage::kPremul_AlphaType; 96889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com return true; 97889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com} 98889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com 99889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.comSkImage* SkNewImageFromBitmap(const SkBitmap& bm) { 100889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com SkImage::Info info; 101889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com if (!SkBitmapToImageInfo(bm, &info)) { 102889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com return NULL; 103889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com } 104889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com 105889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com SkImage* image = NULL; 106889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com if (bm.isImmutable()) { 107889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com image = SkNewImageFromPixelRef(info, bm.pixelRef(), bm.rowBytes()); 108889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com } else { 109889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com bm.lockPixels(); 11070e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org if (bm.getPixels()) { 111889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com image = SkImage::NewRasterCopy(info, NULL, bm.getPixels(), 112889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com bm.rowBytes()); 113889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com } 114889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com bm.unlockPixels(); 115889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com } 116889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com return image; 117889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com} 118889b09edfeb5f461ca283dfd08ee6b23560a7859reed@google.com 11970e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.orgstatic bool needs_layer(const SkPaint& paint) { 12070e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org return 0xFF != paint.getAlpha() || 12170e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org paint.getColorFilter() || 12270e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org paint.getImageFilter() || 12370e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode); 12470e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org} 12570e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org 12670e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.orgvoid SkImagePrivDrawPicture(SkCanvas* canvas, SkPicture* picture, 12770e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org SkScalar x, SkScalar y, const SkPaint* paint) { 12870e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org int saveCount = canvas->getSaveCount(); 12970e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org 13070e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org if (paint && needs_layer(*paint)) { 13170e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org SkRect bounds; 13270e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org bounds.set(x, y, 13370e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org x + SkIntToScalar(picture->width()), 13470e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org y + SkIntToScalar(picture->height())); 13570e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org canvas->saveLayer(&bounds, paint); 13670e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org } else if (x || y) { 13770e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org canvas->save(); 13870e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org } 13970e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org 14070e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org canvas->drawPicture(*picture); 14170e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org canvas->restoreToCount(saveCount); 14270e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org} 14370e359055240d0de93da4ba71bf5833164fb394cmike@reedtribe.org 144