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