void computeMD5HashStringForContext(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 md5; unsigned char* bitmapData = static_cast<unsigned char*>(CGBitmapContextGetData(bitmapContext)); #if PLATFORM(MAC) if ((CGBitmapContextGetBitmapInfo(bitmapContext) & kCGBitmapByteOrderMask) == kCGBitmapByteOrder32Big) { for (unsigned row = 0; row < pixelsHigh; row++) { Vector<uint8_t> buffer(4 * pixelsWide); for (unsigned column = 0; column < pixelsWide; column++) buffer[column] = OSReadLittleInt32(bitmapData, 4 * column); md5.addBytes(buffer); bitmapData += bytesPerRow; } } else #endif { for (unsigned row = 0; row < pixelsHigh; row++) { md5.addBytes(bitmapData, 4 * pixelsWide); bitmapData += bytesPerRow; } } Vector<uint8_t, 16> hash; md5.checksum(hash); hashString[0] = '\0'; for (int i = 0; i < 16; i++) snprintf(hashString, 33, "%s%02x", hashString, hash[i]); }
CGBitmapInfo myCGContextGetBitmapInfo(CGContextRef c) { if(&CGBitmapContextGetBitmapInfo != NULL) return CGBitmapContextGetBitmapInfo(c); else return CGBitmapContextGetAlphaInfo(c); }
static cairo_status_t _cairo_quartz_surface_acquire_source_image(void *abstract_surface, cairo_image_surface_t **image_out, void **image_extra) { cairo_quartz_surface_t *surface = abstract_surface; if (CGBitmapContextGetBitmapInfo (surface->context) != 0) { /* XXX: We can create an image out of the bitmap here */ } return CAIRO_INT_STATUS_UNSUPPORTED; }