From 648161bb0edfc3d43db63caed5cc5213bc6cb78f Mon Sep 17 00:00:00 2001 From: The Android Open Source Project Date: Tue, 3 Mar 2009 18:28:41 -0800 Subject: auto import from //depot/cupcake/@135843 --- WebKitTools/DumpRenderTree/cg/ImageDiffCG.cpp | 253 --------------------- .../DumpRenderTree/cg/PixelDumpSupportCG.cpp | 134 ----------- WebKitTools/DumpRenderTree/cg/PixelDumpSupportCG.h | 80 ------- 3 files changed, 467 deletions(-) delete mode 100644 WebKitTools/DumpRenderTree/cg/ImageDiffCG.cpp delete mode 100644 WebKitTools/DumpRenderTree/cg/PixelDumpSupportCG.cpp delete mode 100644 WebKitTools/DumpRenderTree/cg/PixelDumpSupportCG.h (limited to 'WebKitTools/DumpRenderTree/cg') diff --git a/WebKitTools/DumpRenderTree/cg/ImageDiffCG.cpp b/WebKitTools/DumpRenderTree/cg/ImageDiffCG.cpp deleted file mode 100644 index 1e55e78..0000000 --- a/WebKitTools/DumpRenderTree/cg/ImageDiffCG.cpp +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Copyright (C) 2005, 2007 Apple Inc. All rights reserved. - * Copyright (C) 2005 Ben La Monica . All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#define min min - -#include -#include -#include -#include -#include -#include - -#if PLATFORM(WIN) -#include -#include -#include -#endif - -#if PLATFORM(MAC) -#include -#endif - -#ifndef CGFLOAT_DEFINED -#ifdef __LP64__ -typedef double CGFloat; -#else -typedef float CGFloat; -#endif -#define CGFLOAT_DEFINED 1 -#endif - -using namespace std; - -#if PLATFORM(WIN) -static inline float strtof(const char *nptr, char **endptr) -{ - return strtod(nptr, endptr); -} -static const CFStringRef kUTTypePNG = CFSTR("public.png"); -#endif - -static RetainPtr createImageFromStdin(int bytesRemaining) -{ - unsigned char buffer[2048]; - RetainPtr data(AdoptCF, CFDataCreateMutable(0, bytesRemaining)); - - while (bytesRemaining > 0) { - size_t bytesToRead = min(bytesRemaining, 2048); - size_t bytesRead = fread(buffer, 1, bytesToRead, stdin); - CFDataAppendBytes(data.get(), buffer, static_cast(bytesRead)); - bytesRemaining -= static_cast(bytesRead); - } - RetainPtr dataProvider(AdoptCF, CGDataProviderCreateWithCFData(data.get())); - return RetainPtr(AdoptCF, CGImageCreateWithPNGDataProvider(dataProvider.get(), 0, false, kCGRenderingIntentDefault)); -} - -static void releaseMallocBuffer(void* info, const void* data, size_t size) -{ - free((void*)data); -} - -static RetainPtr createDifferenceImage(CGImageRef baseImage, CGImageRef testImage, float& difference) -{ - static RetainPtr colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB()); - RetainPtr diffImage; - - size_t width = CGImageGetWidth(baseImage); - size_t height = CGImageGetHeight(baseImage); - size_t rowBytes = width * 4; - - // Draw base image in bitmap context - void* baseBuffer = calloc(height, rowBytes); - CGContextRef baseContext = CGBitmapContextCreate(baseBuffer, width, height, 8, rowBytes, colorSpace.get(), kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host); - CGContextDrawImage(baseContext, CGRectMake(0, 0, width, height), baseImage); - CGContextRelease(baseContext); - - // Draw test image in bitmap context - void* buffer = calloc(height, rowBytes); - CGContextRef context = CGBitmapContextCreate(buffer, width, height, 8, rowBytes, colorSpace.get(), kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host); - CGContextDrawImage(context, CGRectMake(0, 0, width, height), testImage); - CGContextRelease(context); - - // Compare the content of the 2 bitmaps - void* diffBuffer = malloc(width * height); - float count = 0.0f; - float sum = 0.0f; - float maxDistance = 0.0f; - unsigned char* basePixel = (unsigned char*)baseBuffer; - unsigned char* pixel = (unsigned char*)buffer; - unsigned char* diff = (unsigned char*)diffBuffer; - for (size_t y = 0; y < height; ++y) { - for (size_t x = 0; x < width; ++x) { - float red = (pixel[0] - basePixel[0]) / max(255 - basePixel[0], basePixel[0]); - float green = (pixel[1] - basePixel[1]) / max(255 - basePixel[1], basePixel[1]); - float blue = (pixel[2] - basePixel[2]) / max(255 - basePixel[2], basePixel[2]); - float alpha = (pixel[3] - basePixel[3]) / max(255 - basePixel[3], basePixel[3]); - float distance = sqrtf(red * red + green * green + blue * blue + alpha * alpha) / 2.0f; - - *diff++ = (unsigned char)(distance * 255.0f); - - if (distance >= 1.0f / 255.0f) { - count += 1.0f; - sum += distance; - if (distance > maxDistance) - maxDistance = distance; - } - - basePixel += 4; - pixel += 4; - } - } - - // Compute the difference as a percentage combining both the number of different pixels and their difference amount i.e. the average distance over the entire image - if (count > 0.0f) - difference = 100.0f * sum / (height * width); - else - difference = 0.0f; - - // Generate a normalized diff image if there is any difference - if (difference > 0.0f) { - if (maxDistance < 1.0f) { - diff = (unsigned char*)diffBuffer; - for(size_t p = 0; p < height * width; ++p) - diff[p] = diff[p] / maxDistance; - } - - CGDataProviderRef provider = CGDataProviderCreateWithData(0, diffBuffer, width * height, releaseMallocBuffer); - CGColorSpaceRef diffColorspace = CGColorSpaceCreateDeviceGray(); - diffImage.adoptCF(CGImageCreate(width, height, 8, 8, width, diffColorspace, 0, provider, 0, false, kCGRenderingIntentDefault)); - CGColorSpaceRelease(diffColorspace); - CGDataProviderRelease(provider); - } - else - free(diffBuffer); - - // Destroy drawing buffers - if (buffer) - free(buffer); - if (baseBuffer) - free(baseBuffer); - - return diffImage; -} - -static inline bool imageHasAlpha(CGImageRef image) -{ - CGImageAlphaInfo info = CGImageGetAlphaInfo(image); - - return (info >= kCGImageAlphaPremultipliedLast) && (info <= kCGImageAlphaFirst); -} - -int main(int argc, const char* argv[]) -{ -#if PLATFORM(WIN) - _setmode(0, _O_BINARY); - _setmode(1, _O_BINARY); -#endif - - float tolerance = 0.0f; - - for (int i = 1; i < argc; ++i) { - if (!strcmp(argv[i], "-t") || !strcmp(argv[i], "--tolerance")) { - if (i >= argc - 1) - exit(1); - tolerance = strtof(argv[i + 1], 0); - ++i; - continue; - } - } - - char buffer[2048]; - RetainPtr actualImage; - RetainPtr baselineImage; - - while (fgets(buffer, sizeof(buffer), stdin)) { - // remove the CR - char* newLineCharacter = strchr(buffer, '\n'); - if (newLineCharacter) - *newLineCharacter = '\0'; - - if (!strncmp("Content-Length: ", buffer, 16)) { - strtok(buffer, " "); - int imageSize = strtol(strtok(0, " "), 0, 10); - - if (imageSize > 0 && !actualImage) - actualImage = createImageFromStdin(imageSize); - else if (imageSize > 0 && !baselineImage) - baselineImage = createImageFromStdin(imageSize); - else - fputs("error, image size must be specified.\n", stdout); - } - - if (actualImage && baselineImage) { - RetainPtr diffImage; - float difference = 100.0f; - - if ((CGImageGetWidth(actualImage.get()) == CGImageGetWidth(baselineImage.get())) && (CGImageGetHeight(actualImage.get()) == CGImageGetHeight(baselineImage.get())) && (imageHasAlpha(actualImage.get()) == imageHasAlpha(baselineImage.get()))) { - diffImage = createDifferenceImage(actualImage.get(), baselineImage.get(), difference); // difference is passed by reference - if (difference <= tolerance) - difference = 0.0f; - else { - difference = roundf(difference * 100.0f) / 100.0f; - difference = max(difference, 0.01f); // round to 2 decimal places - } - } else - fputs("error, test and reference image have different properties.\n", stderr); - - if (difference > 0.0f) { - if (diffImage) { - RetainPtr imageData(AdoptCF, CFDataCreateMutable(0, 0)); - RetainPtr imageDest(AdoptCF, CGImageDestinationCreateWithData(imageData.get(), kUTTypePNG, 1, 0)); - CGImageDestinationAddImage(imageDest.get(), diffImage.get(), 0); - CGImageDestinationFinalize(imageDest.get()); - printf("Content-Length: %lu\n", CFDataGetLength(imageData.get())); - fwrite(CFDataGetBytePtr(imageData.get()), 1, CFDataGetLength(imageData.get()), stdout); - } - - fprintf(stdout, "diff: %01.2f%% failed\n", difference); - } else - fprintf(stdout, "diff: %01.2f%% passed\n", difference); - - actualImage = 0; - baselineImage = 0; - } - - fflush(stdout); - } - - return 0; -} diff --git a/WebKitTools/DumpRenderTree/cg/PixelDumpSupportCG.cpp b/WebKitTools/DumpRenderTree/cg/PixelDumpSupportCG.cpp deleted file mode 100644 index 2320e19..0000000 --- a/WebKitTools/DumpRenderTree/cg/PixelDumpSupportCG.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved. - * (C) 2007 Graham Dennis (graham.dennis@gmail.com) - * (C) 2007 Eric Seidel - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "PixelDumpSupportCG.h" - -#include "DumpRenderTree.h" -#include "LayoutTestController.h" -#include -#include -#include -#include -#include -#include -#include - -#if PLATFORM(WIN) -#include "MD5.h" -#elif PLATFORM(MAC) -#include -#define COMMON_DIGEST_FOR_OPENSSL -#include -#endif - -#if PLATFORM(WIN) -static const CFStringRef kUTTypePNG = CFSTR("public.png"); -#endif - -static void printPNG(CGImageRef image) -{ - RetainPtr imageData(AdoptCF, CFDataCreateMutable(0, 0)); - RetainPtr imageDest(AdoptCF, CGImageDestinationCreateWithData(imageData.get(), kUTTypePNG, 1, 0)); - CGImageDestinationAddImage(imageDest.get(), image, 0); - CGImageDestinationFinalize(imageDest.get()); - - printf("Content-Type: %s\n", "image/png"); - printf("Content-Length: %lu\n", CFDataGetLength(imageData.get())); - - fwrite(CFDataGetBytePtr(imageData.get()), 1, CFDataGetLength(imageData.get()), stdout); -} - -static void computeMD5HashStringForBitmapContext(CGContextRef bitmapContext, char hashString[33]) -{ - ASSERT(CGBitmapContextGetBitsPerPixel(bitmapContext) == 32); // ImageDiff assumes 32 bit RGBA, we must as well. - size_t pixelsHigh = CGBitmapContextGetHeight(bitmapContext); - size_t pixelsWide = CGBitmapContextGetWidth(bitmapContext); - size_t bytesPerRow = CGBitmapContextGetBytesPerRow(bitmapContext); - - // We need to swap the bytes to ensure consistent hashes independently of endianness - MD5_CTX md5Context; - MD5_Init(&md5Context); - unsigned char* bitmapData = static_cast(CGBitmapContextGetData(bitmapContext)); -#if PLATFORM(MAC) - if ((CGBitmapContextGetBitmapInfo(bitmapContext) & kCGBitmapByteOrderMask) == kCGBitmapByteOrder32Big) { - for (unsigned row = 0; row < pixelsHigh; row++) { - uint32_t buffer[pixelsWide]; - for (unsigned column = 0; column < pixelsWide; column++) - buffer[column] = OSReadLittleInt32(bitmapData, 4 * column); - MD5_Update(&md5Context, buffer, 4 * pixelsWide); - bitmapData += bytesPerRow; - } - } else -#endif - { - for (unsigned row = 0; row < pixelsHigh; row++) { - MD5_Update(&md5Context, bitmapData, 4 * pixelsWide); - bitmapData += bytesPerRow; - } - } - unsigned char hash[16]; - MD5_Final(hash, &md5Context); - - hashString[0] = '\0'; - for (int i = 0; i < 16; i++) - snprintf(hashString, 33, "%s%02x", hashString, hash[i]); -} - -void dumpWebViewAsPixelsAndCompareWithExpected(const std::string& expectedHash) -{ - RefPtr context; - -#if PLATFORM(MAC) - context = createBitmapContextFromWebView(gLayoutTestController->testOnscreen(), gLayoutTestController->testRepaint(), gLayoutTestController->testRepaintSweepHorizontally(), gLayoutTestController->dumpSelectionRect()); -#endif - ASSERT(context); - - // Compute the hash of the bitmap context pixels - char actualHash[33]; - computeMD5HashStringForBitmapContext(context->cgContext(), actualHash); - printf("\nActualHash: %s\n", actualHash); - - // Check the computed hash against the expected one and dump image on mismatch - bool dumpImage = true; - if (expectedHash.length() > 0) { - ASSERT(expectedHash.length() == 32); - - printf("\nExpectedHash: %s\n", expectedHash.c_str()); - - if (expectedHash == actualHash) // FIXME: do case insensitive compare - dumpImage = false; - } - - if (dumpImage) { - RetainPtr image(AdoptCF, CGBitmapContextCreateImage(context->cgContext())); - printPNG(image.get()); - } -} diff --git a/WebKitTools/DumpRenderTree/cg/PixelDumpSupportCG.h b/WebKitTools/DumpRenderTree/cg/PixelDumpSupportCG.h deleted file mode 100644 index 84350e8..0000000 --- a/WebKitTools/DumpRenderTree/cg/PixelDumpSupportCG.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved. - * (C) 2007 Graham Dennis (graham.dennis@gmail.com) - * (C) 2007 Eric Seidel - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef PixelDumpSupportCG_h -#define PixelDumpSupportCG_h - -#include -#include -#include - -typedef struct CGContext* CGContextRef; - -#if PLATFORM(MAC) -typedef void* PlatformBitmapBuffer; -#elif PLATFORM(WIN) -typedef HBITMAP PlatformBitmapBuffer; -#endif - -class BitmapContext : public RefCounted { -public: - static PassRefPtr createByAdoptingBitmapAndContext(PlatformBitmapBuffer buffer, CGContextRef context) - { - return adoptRef(new BitmapContext(buffer, context)); - } - - ~BitmapContext() - { - if (m_buffer) -#if PLATFORM(MAC) - free(m_buffer); -#elif PLATFORM(WIN) - DeleteObject(m_buffer); -#endif - } - - CGContextRef cgContext() const { return m_context.get(); } - -private: - - BitmapContext(PlatformBitmapBuffer buffer, CGContextRef context) - : m_buffer(buffer) - , m_context(AdoptCF, context) - { - } - - PlatformBitmapBuffer m_buffer; - RetainPtr m_context; - -}; - -PassRefPtr createBitmapContextFromWebView(bool onscreen, bool incrementalRepaint, bool sweepHorizontally, bool drawSelectionRect); - -#endif // PixelDumpSupportCG_h -- cgit v1.1