1/* 2 * Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved. 3 * (C) 2007 Graham Dennis (graham.dennis@gmail.com) 4 * (C) 2007 Eric Seidel <eric@webkit.org> 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 16 * its contributors may be used to endorse or promote products derived 17 * from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31#include "config.h" 32#include "PixelDumpSupportCG.h" 33 34#include "DumpRenderTree.h" 35#include "PixelDumpSupport.h" 36#include <ImageIO/CGImageDestination.h> 37#include <algorithm> 38#include <ctype.h> 39#include <wtf/Assertions.h> 40#include <wtf/RefPtr.h> 41#include <wtf/RetainPtr.h> 42#include <wtf/StringExtras.h> 43 44#if PLATFORM(WIN) 45#include "MD5.h" 46#elif PLATFORM(MAC) 47#include <LaunchServices/UTCoreTypes.h> 48#define COMMON_DIGEST_FOR_OPENSSL 49#include <CommonCrypto/CommonDigest.h> 50#endif 51 52using namespace std; 53 54#if PLATFORM(WIN) 55static const CFStringRef kUTTypePNG = CFSTR("public.png"); 56#endif 57 58static void printPNG(CGImageRef image) 59{ 60 RetainPtr<CFMutableDataRef> imageData(AdoptCF, CFDataCreateMutable(0, 0)); 61 RetainPtr<CGImageDestinationRef> imageDest(AdoptCF, CGImageDestinationCreateWithData(imageData.get(), kUTTypePNG, 1, 0)); 62 CGImageDestinationAddImage(imageDest.get(), image, 0); 63 CGImageDestinationFinalize(imageDest.get()); 64 65 const UInt8* data = CFDataGetBytePtr(imageData.get()); 66 CFIndex dataLength = CFDataGetLength(imageData.get()); 67 68 printPNG(static_cast<const unsigned char*>(data), static_cast<size_t>(dataLength)); 69} 70 71void computeMD5HashStringForBitmapContext(BitmapContext* context, char hashString[33]) 72{ 73 CGContextRef bitmapContext = context->cgContext(); 74 75 ASSERT(CGBitmapContextGetBitsPerPixel(bitmapContext) == 32); // ImageDiff assumes 32 bit RGBA, we must as well. 76 size_t pixelsHigh = CGBitmapContextGetHeight(bitmapContext); 77 size_t pixelsWide = CGBitmapContextGetWidth(bitmapContext); 78 size_t bytesPerRow = CGBitmapContextGetBytesPerRow(bitmapContext); 79 80 // We need to swap the bytes to ensure consistent hashes independently of endianness 81 MD5_CTX md5Context; 82 MD5_Init(&md5Context); 83 unsigned char* bitmapData = static_cast<unsigned char*>(CGBitmapContextGetData(bitmapContext)); 84#if PLATFORM(MAC) 85 if ((CGBitmapContextGetBitmapInfo(bitmapContext) & kCGBitmapByteOrderMask) == kCGBitmapByteOrder32Big) { 86 for (unsigned row = 0; row < pixelsHigh; row++) { 87 uint32_t buffer[pixelsWide]; 88 for (unsigned column = 0; column < pixelsWide; column++) 89 buffer[column] = OSReadLittleInt32(bitmapData, 4 * column); 90 MD5_Update(&md5Context, buffer, 4 * pixelsWide); 91 bitmapData += bytesPerRow; 92 } 93 } else 94#endif 95 { 96 for (unsigned row = 0; row < pixelsHigh; row++) { 97 MD5_Update(&md5Context, bitmapData, 4 * pixelsWide); 98 bitmapData += bytesPerRow; 99 } 100 } 101 unsigned char hash[16]; 102 MD5_Final(hash, &md5Context); 103 104 hashString[0] = '\0'; 105 for (int i = 0; i < 16; i++) 106 snprintf(hashString, 33, "%s%02x", hashString, hash[i]); 107} 108 109void dumpBitmap(BitmapContext* context) 110{ 111 RetainPtr<CGImageRef> image(AdoptCF, CGBitmapContextCreateImage(context->cgContext())); 112 printPNG(image.get()); 113} 114