180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/* 280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2012 Google Inc. 380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be 580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file. 680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkImagePriv.h" 980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkCanvas.h" 1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkPicture.h" 1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkBitmap::Config SkImageInfoToBitmapConfig(const SkImage::Info& info, 1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool* isOpaque) { 1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru switch (info.fColorType) { 1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case SkImage::kAlpha_8_ColorType: 1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru switch (info.fAlphaType) { 1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case SkImage::kIgnore_AlphaType: 1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // makes no sense 1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkBitmap::kNo_Config; 2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case SkImage::kOpaque_AlphaType: 2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *isOpaque = true; 2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkBitmap::kA8_Config; 2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case SkImage::kPremul_AlphaType: 2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case SkImage::kUnpremul_AlphaType: 2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *isOpaque = false; 2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkBitmap::kA8_Config; 2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case SkImage::kRGB_565_ColorType: 3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // we ignore fAlpahType, though some would not make sense 3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *isOpaque = true; 3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkBitmap::kRGB_565_Config; 3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case SkImage::kRGBA_8888_ColorType: 3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case SkImage::kBGRA_8888_ColorType: 3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // not supported yet 4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkBitmap::kNo_Config; 4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case SkImage::kPMColor_ColorType: 4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru switch (info.fAlphaType) { 4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case SkImage::kIgnore_AlphaType: 4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case SkImage::kUnpremul_AlphaType: 4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // not supported yet 4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkBitmap::kNo_Config; 4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case SkImage::kOpaque_AlphaType: 4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *isOpaque = true; 5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkBitmap::kARGB_8888_Config; 5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case SkImage::kPremul_AlphaType: 5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *isOpaque = false; 5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkBitmap::kARGB_8888_Config; 5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(!"how did we get here"); 5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkBitmap::kNo_Config; 5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruint SkImageBytesPerPixel(SkImage::ColorType ct) { 6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static const uint8_t gColorTypeBytesPerPixel[] = { 6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1, // kAlpha_8_ColorType 6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2, // kRGB_565_ColorType 6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4, // kRGBA_8888_ColorType 6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4, // kBGRA_8888_ColorType 6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4, // kPMColor_ColorType 6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru }; 6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT((size_t)ct < SK_ARRAY_COUNT(gColorTypeBytesPerPixel)); 7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return gColorTypeBytesPerPixel[ct]; 7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkBitmapToImageInfo(const SkBitmap& bm, SkImage::Info* info) { 7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru switch (bm.config()) { 7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case SkBitmap::kA8_Config: 7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru info->fColorType = SkImage::kAlpha_8_ColorType; 7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case SkBitmap::kRGB_565_Config: 8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru info->fColorType = SkImage::kRGB_565_ColorType; 8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case SkBitmap::kARGB_8888_Config: 8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru info->fColorType = SkImage::kPMColor_ColorType; 8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru default: 8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru info->fWidth = bm.width(); 9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru info->fHeight = bm.height(); 9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru info->fAlphaType = bm.isOpaque() ? SkImage::kOpaque_AlphaType : 9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkImage::kPremul_AlphaType; 9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkImage* SkNewImageFromBitmap(const SkBitmap& bm, bool canSharePixelRef) { 10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkImage::Info info; 10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!SkBitmapToImageInfo(bm, &info)) { 10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return NULL; 10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkImage* image = NULL; 10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (canSharePixelRef || bm.isImmutable()) { 10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru image = SkNewImageFromPixelRef(info, bm.pixelRef(), bm.rowBytes()); 10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bm.lockPixels(); 11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (bm.getPixels()) { 111363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger image = SkImage::NewRasterCopy(info, bm.getPixels(), bm.rowBytes()); 11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bm.unlockPixels(); 11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return image; 11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic bool needs_layer(const SkPaint& paint) { 11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return 0xFF != paint.getAlpha() || 12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru paint.getColorFilter() || 12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru paint.getImageFilter() || 12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode); 12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkImagePrivDrawPicture(SkCanvas* canvas, SkPicture* picture, 12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar x, SkScalar y, const SkPaint* paint) { 12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int saveCount = canvas->getSaveCount(); 12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 12980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (paint && needs_layer(*paint)) { 13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkRect bounds; 13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bounds.set(x, y, 13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru x + SkIntToScalar(picture->width()), 13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru y + SkIntToScalar(picture->height())); 13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru canvas->saveLayer(&bounds, paint); 13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru canvas->translate(x, y); 13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else if (x || y) { 13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru canvas->save(); 13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru canvas->translate(x, y); 13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru canvas->drawPicture(*picture); 14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru canvas->restoreToCount(saveCount); 14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 14458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 14558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergervoid SkImagePrivDrawPicture(SkCanvas* canvas, SkPicture* picture, 14658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger const SkRect* src, const SkRect& dst, const SkPaint* paint) { 14758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger int saveCount = canvas->getSaveCount(); 14858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 14958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkMatrix matrix; 15058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkRect tmpSrc; 15158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 15258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (NULL != src) { 15358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger tmpSrc = *src; 15458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } else { 15558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger tmpSrc.set(0, 0, 15658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkIntToScalar(picture->width()), 15758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkIntToScalar(picture->height())); 15858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 15958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 16058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger matrix.setRectToRect(tmpSrc, dst, SkMatrix::kFill_ScaleToFit); 16158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (paint && needs_layer(*paint)) { 16258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->saveLayer(&dst, paint); 16358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } else { 16458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->save(); 16558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 16658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->concat(matrix); 16758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (!paint || !needs_layer(*paint)) { 16858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->clipRect(tmpSrc); 16958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 17058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 17158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->drawPicture(*picture); 17258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger canvas->restoreToCount(saveCount); 17358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger} 174