1
2/*
3 * Copyright 2012 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9#include "SkBitmap.h"
10#include "SkBitmapTransformer.h"
11#include "SkColorPriv.h"
12#include "SkTypes.h"
13
14bool SkBitmapTransformer::isValid(bool logReason) const {
15    bool retval = true;
16
17    switch(fPixelFormat) {
18    case kARGB_8888_Premul_PixelFormat:
19        break;
20    default:
21        if (logReason) {
22            SkDEBUGF(("PixelFormat %d not supported\n", fPixelFormat));
23        }
24        retval = false;
25    }
26
27    SkBitmap::Config bitmapConfig = fBitmap.config();
28    switch(bitmapConfig) {
29    case SkBitmap::kARGB_8888_Config:
30        break;
31    default:
32        if (logReason) {
33            SkDEBUGF(("SkBitmap::Config %d not supported\n", bitmapConfig));
34        }
35        retval = false;
36    }
37
38    return retval;
39}
40
41/**
42 * Transform from kARGB_8888_Config to kARGB_8888_Premul_PixelFormat.
43 *
44 * Similar to the various scanline transformers in
45 * src/images/transform_scanline.h .
46 */
47static void transform_scanline(const char* SK_RESTRICT src, int width,
48                               char* SK_RESTRICT dst) {
49    const SkPMColor* SK_RESTRICT srcP = reinterpret_cast<const SkPMColor*>(src);
50    for (int i = 0; i < width; i++) {
51        SkPMColor c = *srcP++;
52        unsigned a = SkGetPackedA32(c);
53        unsigned r = SkGetPackedR32(c);
54        unsigned g = SkGetPackedG32(c);
55        unsigned b = SkGetPackedB32(c);
56        *dst++ = a;
57        *dst++ = r;
58        *dst++ = g;
59        *dst++ = b;
60    }
61}
62
63bool SkBitmapTransformer::copyBitmapToPixelBuffer(void *dstBuffer,
64                                                  size_t dstBufferSize) const {
65    if (!this->isValid(true)) {
66        return false;
67    }
68    size_t bytesNeeded = this->bytesNeededTotal();
69    if (dstBufferSize < bytesNeeded) {
70        SkDEBUGF(("dstBufferSize %d must be >= %d\n", dstBufferSize, bytesNeeded));
71        return false;
72    }
73
74    fBitmap.lockPixels();
75    int width = fBitmap.width();
76    size_t srcRowBytes = fBitmap.rowBytes();
77    size_t dstRowBytes = this->bytesNeededPerRow();
78    const char *srcBytes = const_cast<const char *>(static_cast<char*>(fBitmap.getPixels()));
79    char *dstBytes = static_cast<char *>(dstBuffer);
80    for (int y = 0; y < fBitmap.height(); y++) {
81        transform_scanline(srcBytes, width, dstBytes);
82        srcBytes += srcRowBytes;
83        dstBytes += dstRowBytes;
84    }
85    fBitmap.unlockPixels();
86    return true;
87}
88