Add the ability to provide function pointers to SkPicture serialization
and deserialization for encoding and decoding bitmaps.
Remove kForceFlattenBitmapPixels_Flag, which is no longer used.
When an SkOrderedReadBuffer needs to read a bitmap, if it does not
have an image decoder, use a dummy bitmap.
In GM, add a tolerance option for color differences, used when
testing picture serialization, so it can assume two images are the
same even though PNG encoding/decoding may have resulted in small
differences.
Create dummy implementations for SkImageDecoder and SkImageEncoder
functions in SkImageDecoder_empty so that a project that does not
want to include the images project it can still build.
Allow ports to build without images project.
In Mac's image encoder, copy 4444 to 8888 before encoding.
Add SkWriter32::reservePad, to provide a pointer to write non 4 byte
aligned data, padded with zeroes.
In bench_ and render_ pictures, pass decode function to SkPicture
creation from a stream.
BUG=https://code.google.com/p/skia/issues/detail?id=842
Review URL: https://codereview.appspot.com/6551071
git-svn-id: http://skia.googlecode.com/svn/trunk@5818 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gm/gmmain.cpp b/gm/gmmain.cpp
index f0de5bd..2d341e9 100644
--- a/gm/gmmain.cpp
+++ b/gm/gmmain.cpp
@@ -171,7 +171,7 @@
static ErrorBitfield compare(const SkBitmap& target, const SkBitmap& base,
const SkString& name,
const char* renderModeDescriptor,
- SkBitmap* diff) {
+ SkBitmap* diff, uint32_t tolerance) {
SkBitmap copy;
const SkBitmap* bm = ⌖
if (target.config() != SkBitmap::kARGB_8888_Config) {
@@ -206,16 +206,20 @@
SkPMColor c0 = *bp->getAddr32(x, y);
SkPMColor c1 = *bm->getAddr32(x, y);
if (c0 != c1) {
- SkDebugf(
+ SkPMColor trueDiff = compute_diff_pmcolor(c0, c1);
+ if (SkGetPackedR32(trueDiff) > tolerance || SkGetPackedG32(trueDiff) > tolerance
+ || SkGetPackedB32(trueDiff) > tolerance) {
+ SkDebugf(
"----- %s pixel mismatch for %s at [%d %d] base 0x%08X current 0x%08X\n",
renderModeDescriptor, name.c_str(), x, y, c0, c1);
- if (diff) {
- diff->setConfig(SkBitmap::kARGB_8888_Config, w, h);
- diff->allocPixels();
- compute_diff(*bm, *bp, diff);
+ if (diff) {
+ diff->setConfig(SkBitmap::kARGB_8888_Config, w, h);
+ diff->allocPixels();
+ compute_diff(*bm, *bp, diff);
+ }
+ return ERROR_PIXEL_MISMATCH;
}
- return ERROR_PIXEL_MISMATCH;
}
}
}
@@ -438,11 +442,12 @@
SkBitmap &bitmap,
const SkBitmap& comparisonBitmap,
const char diffPath [],
- const char renderModeDescriptor []) {
+ const char renderModeDescriptor [],
+ uint32_t tolerance = 0) {
ErrorBitfield errors;
SkBitmap diffBitmap;
errors = compare(bitmap, comparisonBitmap, name, renderModeDescriptor,
- diffPath ? &diffBitmap : NULL);
+ diffPath ? &diffBitmap : NULL, tolerance);
if ((ERROR_NONE != errors) && diffPath) {
// write out the generated image
SkString genName = make_filename(diffPath, "", name, "png");
@@ -482,7 +487,8 @@
const char renderModeDescriptor [],
SkBitmap& bitmap,
SkDynamicMemoryWStream* pdf,
- const SkBitmap* comparisonBitmap) {
+ const SkBitmap* comparisonBitmap,
+ uint32_t tolerance = 0) {
SkString name = make_name(gm->shortName(), gRec.fName);
ErrorBitfield retval = ERROR_NONE;
@@ -497,7 +503,7 @@
if (comparisonBitmap) {
retval |= compare_to_reference_image(name, bitmap,
*comparisonBitmap, diffPath,
- renderModeDescriptor);
+ renderModeDescriptor, tolerance);
}
return retval;
}
@@ -513,6 +519,10 @@
return pict;
}
+static bool EncodeBitmap(SkWStream* wStream, const SkBitmap& bitmap) {
+ return SkImageEncoder::EncodeStream(wStream, bitmap, SkImageEncoder::kPNG_Type, 100);
+}
+
static SkPicture* stream_to_new_picture(const SkPicture& src) {
// To do in-memory commiunications with a stream, we need to:
@@ -522,7 +532,7 @@
// ?!?!
SkDynamicMemoryWStream storage;
- src.serialize(&storage);
+ src.serialize(&storage, &EncodeBitmap);
int streamSize = storage.getOffset();
SkAutoMalloc dstStorage(streamSize);
@@ -531,7 +541,7 @@
//@todo thudson 22 April 2011 when can we safely delete [] dst?
storage.copyTo(dst);
SkMemoryStream pictReadback(dst, streamSize);
- SkPicture* retval = new SkPicture (&pictReadback);
+ SkPicture* retval = SkNEW_ARGS(SkPicture, (&pictReadback, NULL, &SkImageDecoder::DecodeStream));
return retval;
}
@@ -623,8 +633,11 @@
if (kRaster_Backend == gRec.fBackend) {
SkBitmap bitmap;
generate_image_from_picture(gm, gRec, repict, &bitmap);
+ // Allow for slight differences in color due to PNG encoding bitmaps, which does not restore
+ // our premultiplied alpha properly.
+ static const uint32_t tolerance = 50;
return handle_test_results(gm, gRec, NULL, NULL, diffPath,
- "-serialize", bitmap, NULL, &comparisonBitmap);
+ "-serialize", bitmap, NULL, &comparisonBitmap, tolerance);
} else {
return ERROR_NONE;
}