/*
* Copyright 2012 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "SkBitmap.h"
#include "SkBitmapTransformer.h"
#include "SkColorPriv.h"
#include "SkTypes.h"
bool SkBitmapTransformer::isValid(bool logReason) const {
bool retval = true;
switch(fPixelFormat) {
case kARGB_8888_Premul_PixelFormat:
break;
default:
if (logReason) {
SkDEBUGF(("PixelFormat %d not supported\n", fPixelFormat));
}
retval = false;
}
SkBitmap::Config bitmapConfig = fBitmap.config();
switch(bitmapConfig) {
case SkBitmap::kARGB_8888_Config:
break;
default:
if (logReason) {
SkDEBUGF(("SkBitmap::Config %d not supported\n", bitmapConfig));
}
retval = false;
}
return retval;
}
/**
* Transform from kARGB_8888_Config to kARGB_8888_Premul_PixelFormat.
*
* Similar to the various scanline transformers in
* src/images/transform_scanline.h .
*/
static void transform_scanline(const char* SK_RESTRICT src, int width,
char* SK_RESTRICT dst) {
const SkPMColor* SK_RESTRICT srcP = reinterpret_cast<const SkPMColor*>(src);
for (int i = 0; i < width; i++) {
SkPMColor c = *srcP++;
unsigned a = SkGetPackedA32(c);
unsigned r = SkGetPackedR32(c);
unsigned g = SkGetPackedG32(c);
unsigned b = SkGetPackedB32(c);
*dst++ = a;
*dst++ = r;
*dst++ = g;
*dst++ = b;
}
}
bool SkBitmapTransformer::copyBitmapToPixelBuffer(void *dstBuffer,
size_t dstBufferSize) const {
if (!this->isValid(true)) {
return false;
}
size_t bytesNeeded = this->bytesNeededTotal();
if (dstBufferSize < bytesNeeded) {
SkDEBUGF(("dstBufferSize %d must be >= %d\n", dstBufferSize, bytesNeeded));
return false;
}
fBitmap.lockPixels();
int width = fBitmap.width();
size_t srcRowBytes = fBitmap.rowBytes();
size_t dstRowBytes = this->bytesNeededPerRow();
const char *srcBytes = const_cast<const char *>(static_cast<char*>(fBitmap.getPixels()));
char *dstBytes = static_cast<char *>(dstBuffer);
for (int y = 0; y < fBitmap.height(); y++) {
transform_scanline(srcBytes, width, dstBytes);
srcBytes += srcRowBytes;
dstBytes += dstRowBytes;
}
fBitmap.unlockPixels();
return true;
}