@@ -32,8 +32,8 @@ extension Diffing where Value == UIImage {
32
32
)
33
33
}
34
34
}
35
-
36
-
35
+
36
+
37
37
/// Used when the image size has no width or no height to generated the default empty image
38
38
private static func emptyImage( ) -> UIImage {
39
39
let label = UILabel ( frame: CGRect ( x: 0 , y: 0 , width: 400 , height: 80 ) )
@@ -62,6 +62,11 @@ extension Snapshotting where Value == UIImage, Format == UIImage {
62
62
}
63
63
}
64
64
65
+ // remap snapshot & reference to same colorspace
66
+ let imageContextColorSpace = CGColorSpace ( name: CGColorSpace . sRGB)
67
+ let imageContextBitsPerComponent = 8
68
+ let imageContextBytesPerPixel = 4
69
+
65
70
private func compare( _ old: UIImage , _ new: UIImage , precision: Float ) -> Bool {
66
71
guard let oldCgImage = old. cgImage else { return false }
67
72
guard let newCgImage = new. cgImage else { return false }
@@ -71,23 +76,18 @@ private func compare(_ old: UIImage, _ new: UIImage, precision: Float) -> Bool {
71
76
guard oldCgImage. height != 0 else { return false }
72
77
guard newCgImage. height != 0 else { return false }
73
78
guard oldCgImage. height == newCgImage. height else { return false }
74
- // Values between images may differ due to padding to multiple of 64 bytes per row,
75
- // because of that a freshly taken view snapshot may differ from one stored as PNG.
76
- // At this point we're sure that size of both images is the same, so we can go with minimal `bytesPerRow` value
77
- // and use it to create contexts.
78
- let minBytesPerRow = min ( oldCgImage. bytesPerRow, newCgImage. bytesPerRow)
79
- let byteCount = minBytesPerRow * oldCgImage. height
80
79
80
+ let byteCount = imageContextBytesPerPixel * oldCgImage. width * oldCgImage. height
81
81
var oldBytes = [ UInt8] ( repeating: 0 , count: byteCount)
82
- guard let oldContext = context ( for: oldCgImage, bytesPerRow : minBytesPerRow , data: & oldBytes) else { return false }
82
+ guard let oldContext = context ( for: oldCgImage, data: & oldBytes) else { return false }
83
83
guard let oldData = oldContext. data else { return false }
84
- if let newContext = context ( for: newCgImage, bytesPerRow : minBytesPerRow ) , let newData = newContext. data {
84
+ if let newContext = context ( for: newCgImage) , let newData = newContext. data {
85
85
if memcmp ( oldData, newData, byteCount) == 0 { return true }
86
86
}
87
87
let newer = UIImage ( data: new. pngData ( ) !) !
88
88
guard let newerCgImage = newer. cgImage else { return false }
89
89
var newerBytes = [ UInt8] ( repeating: 0 , count: byteCount)
90
- guard let newerContext = context ( for: newerCgImage, bytesPerRow : minBytesPerRow , data: & newerBytes) else { return false }
90
+ guard let newerContext = context ( for: newerCgImage, data: & newerBytes) else { return false }
91
91
guard let newerData = newerContext. data else { return false }
92
92
if memcmp ( oldData, newerData, byteCount) == 0 { return true }
93
93
if precision >= 1 { return false }
@@ -100,16 +100,17 @@ private func compare(_ old: UIImage, _ new: UIImage, precision: Float) -> Bool {
100
100
return true
101
101
}
102
102
103
- private func context( for cgImage: CGImage , bytesPerRow: Int , data: UnsafeMutableRawPointer ? = nil ) -> CGContext ? {
103
+ private func context( for cgImage: CGImage , data: UnsafeMutableRawPointer ? = nil ) -> CGContext ? {
104
+ let bytesPerRow = cgImage. width * imageContextBytesPerPixel
104
105
guard
105
- let space = cgImage . colorSpace ,
106
+ let colorSpace = imageContextColorSpace ,
106
107
let context = CGContext (
107
108
data: data,
108
109
width: cgImage. width,
109
110
height: cgImage. height,
110
- bitsPerComponent: cgImage . bitsPerComponent ,
111
+ bitsPerComponent: imageContextBitsPerComponent ,
111
112
bytesPerRow: bytesPerRow,
112
- space: space ,
113
+ space: colorSpace ,
113
114
bitmapInfo: CGImageAlphaInfo . premultipliedLast. rawValue
114
115
)
115
116
else { return nil }
0 commit comments