11import Foundation
22
33public struct AnyImage < Pixel> : ImageProtocol {
4+ public typealias SubImage = AnyImage < Pixel >
5+ public typealias Element = Pixel // FIXME: Remove this line in the future. Swift 4.1 needs it to build `AnyImage`.
6+
47 private var box : AnyImageBox < Pixel >
58 private let lock = NSLock ( )
69
7- public init < I : ImageProtocol > ( _ image: I ) where I. Pixel == Pixel {
8- box = ImageBox < I > ( image)
9- }
10+ public let xRange : CountableRange < Int >
11+ public let yRange : CountableRange < Int >
1012
11- public init ( width: Int , height: Int , pixels: [ Pixel ] ) {
12- self . init ( Image < Pixel > ( width: width, height: height, pixels: pixels) )
13+ private init ( box: AnyImageBox < Pixel > , xRange: CountableRange < Int > , yRange: CountableRange < Int > ) {
14+ self . box = box
15+ self . xRange = xRange
16+ self . yRange = yRange
1317 }
1418
15- public var xRange : CountableRange < Int > {
16- return box. xRange
19+ internal init < I : ImageProtocol > ( _ image: I , xRange: CountableRange < Int > , yRange: CountableRange < Int > ) where I. Pixel == Pixel {
20+ self . box = ImageBox < I > ( image)
21+ self . xRange = xRange
22+ self . yRange = yRange
23+ }
24+
25+ public init < I : ImageProtocol > ( _ image: I ) where I. Pixel == Pixel {
26+ self . init ( image, xRange: image. xRange, yRange: image. yRange)
1727 }
1828
19- public var yRange : CountableRange < Int > {
20- return box . yRange
29+ public init ( width : Int , height : Int , pixels : [ Pixel ] ) {
30+ self . init ( Image < Pixel > ( width : width , height : height , pixels : pixels ) )
2131 }
2232
2333 public subscript( x: Int , y: Int ) -> Pixel {
@@ -36,25 +46,21 @@ public struct AnyImage<Pixel> : ImageProtocol {
3646 }
3747 }
3848
39- public subscript( xRange: CountableRange < Int > , yRange: CountableRange < Int > ) -> ImageSlice < Pixel > {
40- return box [ xRange, yRange]
49+ public subscript( xRange: CountableRange < Int > , yRange: CountableRange < Int > ) -> AnyImage < Pixel > {
50+ return AnyImage ( box: self . box , xRange: xRange , yRange: yRange )
4151 }
42-
43- public func makeIterator( ) -> AnyIterator < Pixel > {
44- return box. makeIterator ( )
52+ }
53+
54+ extension AnyImage : Equatable where Pixel : Equatable {
55+ public static func == ( lhs: AnyImage < Pixel > , rhs: AnyImage < Pixel > ) -> Bool {
56+ guard lhs. width == rhs. width else { return false }
57+ guard lhs. height == rhs. height else { return false }
58+ return zip ( lhs, rhs) . reduce ( true ) { $0 && $1. 0 == $1. 1 }
4559 }
4660}
4761
4862extension AnyImage {
4963 private class AnyImageBox < Pixel> {
50- public var xRange : CountableRange < Int > {
51- fatalError ( " Abstract " )
52- }
53-
54- public var yRange : CountableRange < Int > {
55- fatalError ( " Abstract " )
56- }
57-
5864 public subscript( x: Int , y: Int ) -> Pixel {
5965 get {
6066 fatalError ( " Abstract " )
@@ -65,14 +71,6 @@ extension AnyImage {
6571 }
6672 }
6773
68- public subscript( xRange: CountableRange < Int > , yRange: CountableRange < Int > ) -> ImageSlice < Pixel > {
69- fatalError ( " Abstract " )
70- }
71-
72- public func makeIterator( ) -> AnyIterator < Pixel > {
73- fatalError ( " Abstract " )
74- }
75-
7674 public func copied( ) -> AnyImageBox < Pixel > {
7775 fatalError ( " Abstract " )
7876 }
@@ -85,14 +83,6 @@ extension AnyImage {
8583 self . base = base
8684 }
8785
88- override public var xRange : CountableRange < Int > {
89- return base. xRange
90- }
91-
92- override public var yRange : CountableRange < Int > {
93- return base. yRange
94- }
95-
9686 override public subscript( x: Int , y: Int ) -> I . Pixel {
9787 get {
9888 return base [ x, y]
@@ -103,14 +93,6 @@ extension AnyImage {
10393 }
10494 }
10595
106- override public subscript( xRange: CountableRange < Int > , yRange: CountableRange < Int > ) -> ImageSlice < I . Pixel > {
107- return base [ xRange, yRange]
108- }
109-
110- override public func makeIterator( ) -> AnyIterator < I . Pixel > {
111- return AnyIterator ( base. makeIterator ( ) )
112- }
113-
11496 override public func copied( ) -> ImageBox < I > {
11597 return ImageBox < I > ( base)
11698 }
0 commit comments