static void hashString(MD5& md5, const String& string) { const uint8_t zero = 0; if (string.is8Bit() && string.containsOnlyASCII()) { md5.addBytes(string.characters8(), string.length()); md5.addBytes(&zero, 1); return; } auto cString = string.utf8(); md5.addBytes(reinterpret_cast<const uint8_t*>(cString.data()), cString.length()); md5.addBytes(&zero, 1); }
void TestShell::dumpImage(skia::PlatformCanvas* canvas) const { skia::BitmapPlatformDevice& device = static_cast<skia::BitmapPlatformDevice&>(canvas->getTopPlatformDevice()); const SkBitmap& sourceBitmap = device.accessBitmap(false); SkAutoLockPixels sourceBitmapLock(sourceBitmap); // Fix the alpha. The expected PNGs on Mac have an alpha channel, so we want // to keep it. On Windows, the alpha channel is wrong since text/form control // drawing may have erased it in a few places. So on Windows we force it to // opaque and also don't write the alpha channel for the reference. Linux // doesn't have the wrong alpha like Windows, but we match Windows. #if OS(MAC_OS_X) bool discardTransparency = false; #else bool discardTransparency = true; device.makeOpaque(0, 0, sourceBitmap.width(), sourceBitmap.height()); #endif // Compute MD5 sum. MD5 digester; Vector<uint8_t, 16> digestValue; digester.addBytes(reinterpret_cast<const uint8_t*>(sourceBitmap.getPixels()), sourceBitmap.getSize()); digester.checksum(digestValue); string md5hash; md5hash.reserve(16 * 2); for (unsigned i = 0; i < 16; ++i) { char hex[3]; // Use "x", not "X". The string must be lowercased. sprintf(hex, "%02x", digestValue[i]); md5hash.append(hex); } // Only encode and dump the png if the hashes don't match. Encoding the image // is really expensive. if (md5hash.compare(m_params.pixelHash)) { std::vector<unsigned char> png; webkit_support::EncodeBGRAPNG( reinterpret_cast<const unsigned char*>(sourceBitmap.getPixels()), sourceBitmap.width(), sourceBitmap.height(), static_cast<int>(sourceBitmap.rowBytes()), discardTransparency, &png); m_printer->handleImage(md5hash.c_str(), m_params.pixelHash.c_str(), &png[0], png.size(), m_params.pixelFileName.c_str()); } else m_printer->handleImage(md5hash.c_str(), m_params.pixelHash.c_str(), 0, 0, m_params.pixelFileName.c_str()); }
void TestShell::dumpImage(SkCanvas* canvas) const { // Fix the alpha. The expected PNGs on Mac have an alpha channel, so we want // to keep it. On Windows, the alpha channel is wrong since text/form control // drawing may have erased it in a few places. So on Windows we force it to // opaque and also don't write the alpha channel for the reference. Linux // doesn't have the wrong alpha like Windows, but we match Windows. #if OS(MAC_OS_X) bool discardTransparency = false; #else bool discardTransparency = true; makeCanvasOpaque(canvas); #endif const SkBitmap& sourceBitmap = canvas->getTopDevice()->accessBitmap(false); SkAutoLockPixels sourceBitmapLock(sourceBitmap); // Compute MD5 sum. MD5 digester; Vector<uint8_t, 16> digestValue; #if OS(ANDROID) // On Android, pixel layout is RGBA (see third_party/skia/include/core/SkColorPriv.h); // however, other Chrome platforms use BGRA (see skia/config/SkUserConfig.h). // To match the checksum of other Chrome platforms, we need to reorder the layout of pixels. // NOTE: The following code assumes we use SkBitmap::kARGB_8888_Config, // which has been checked in device.makeOpaque() (see above). const uint8_t* rawPixels = reinterpret_cast<const uint8_t*>(sourceBitmap.getPixels()); size_t bitmapSize = sourceBitmap.getSize(); OwnArrayPtr<uint8_t> reorderedPixels = adoptArrayPtr(new uint8_t[bitmapSize]); for (size_t i = 0; i < bitmapSize; i += 4) { reorderedPixels[i] = rawPixels[i + 2]; // R reorderedPixels[i + 1] = rawPixels[i + 1]; // G reorderedPixels[i + 2] = rawPixels[i]; // B reorderedPixels[i + 3] = rawPixels[i + 3]; // A } digester.addBytes(reorderedPixels.get(), bitmapSize); reorderedPixels.clear(); #else digester.addBytes(reinterpret_cast<const uint8_t*>(sourceBitmap.getPixels()), sourceBitmap.getSize()); #endif digester.checksum(digestValue); string md5hash; md5hash.reserve(16 * 2); for (unsigned i = 0; i < 16; ++i) { char hex[3]; // Use "x", not "X". The string must be lowercased. sprintf(hex, "%02x", digestValue[i]); md5hash.append(hex); } // Only encode and dump the png if the hashes don't match. Encoding the // image is really expensive. if (md5hash.compare(m_params.pixelHash)) { std::vector<unsigned char> png; #if OS(ANDROID) webkit_support::EncodeRGBAPNGWithChecksum(reinterpret_cast<const unsigned char*>(sourceBitmap.getPixels()), sourceBitmap.width(), sourceBitmap.height(), static_cast<int>(sourceBitmap.rowBytes()), discardTransparency, md5hash, &png); #else webkit_support::EncodeBGRAPNGWithChecksum(reinterpret_cast<const unsigned char*>(sourceBitmap.getPixels()), sourceBitmap.width(), sourceBitmap.height(), static_cast<int>(sourceBitmap.rowBytes()), discardTransparency, md5hash, &png); #endif m_printer->handleImage(md5hash.c_str(), m_params.pixelHash.c_str(), &png[0], png.size(), m_params.pixelFileName.c_str()); } else m_printer->handleImage(md5hash.c_str(), m_params.pixelHash.c_str(), 0, 0, m_params.pixelFileName.c_str()); }