Skip to content

Commit 0abe6fc

Browse files
committed
Fix ImageSlice.cgImage which contains the last row of the original image
1 parent 0c80c35 commit 0abe6fc

2 files changed

Lines changed: 57 additions & 6 deletions

File tree

Sources/EasyImagy/ImageSlice.swift

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,24 @@ extension ImageSlice { // Gray or PremultipliedRGBA
5656
bitmapInfo: CGBitmapInfo,
5757
componentType: Component.Type
5858
) -> CGImage {
59-
let length = slice.image.width * slice.height * MemoryLayout<Pixel>.size
59+
let imageCount = slice.image.count
60+
let pixelCount = slice.image.width * slice.height
61+
let length = pixelCount * MemoryLayout<Pixel>.size
62+
let offset = slice.yRange.lowerBound * slice.image.width + slice.xRange.lowerBound
6063

61-
let bytes: UnsafeMutablePointer<Pixel> = UnsafeMutablePointer(mutating: slice.image.pixels) + (slice.yRange.lowerBound * slice.image.width + slice.xRange.lowerBound)
62-
let provider: CGDataProvider = CGDataProvider(data: Data(
63-
bytes: bytes,
64-
count: length
65-
) as CFData)!
64+
var data: Data
65+
if offset + pixelCount <= imageCount {
66+
let bytes: UnsafeMutablePointer<Pixel> = UnsafeMutablePointer(mutating: slice.image.pixels) + (slice.yRange.lowerBound * slice.image.width + slice.xRange.lowerBound)
67+
data = Data(bytes: bytes, count: length)
68+
} else {
69+
let bytes: UnsafeMutablePointer<Pixel> = UnsafeMutablePointer(mutating: slice.image.pixels) + (slice.yRange.lowerBound * slice.image.width + slice.xRange.lowerBound)
70+
let pointer: UnsafeMutablePointer<UInt8> = UnsafeMutableRawPointer(bytes).bindMemory(to: UInt8.self, capacity: length)
71+
data = Data(capacity: pixelCount * MemoryLayout<Pixel>.size)
72+
data.append(pointer, count: (imageCount - offset) * MemoryLayout<Pixel>.size)
73+
data.append(pointer, count: (offset + pixelCount - imageCount) * MemoryLayout<Pixel>.size)
74+
}
75+
76+
let provider: CGDataProvider = CGDataProvider(data: data as CFData)!
6677

6778
return CGImage(
6879
width: slice.width,

Tests/EasyImagyTests/ImageCoreGraphicsTest.swift

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,46 @@ import EasyImagy
201201
XCTAssertEqual(restored[0, 0], PremultipliedRGBA<UInt8>(red: 24, green: 49, blue: 99, alpha: 127))
202202
XCTAssertEqual(restored[0, 1], PremultipliedRGBA<UInt8>(red: 1, green: 2, blue: 3, alpha: 4))
203203
}
204+
205+
do { // slices which contains the last row of the original images
206+
let slice: ImageSlice<UInt8> = Image<UInt8>(width: 4, height: 3, pixels: [
207+
0, 0, 0, 0,
208+
0, 1, 2, 3,
209+
0, 4, 5, 6,
210+
])[1...3, 1...2]
211+
212+
let cgImage = slice.cgImage
213+
let restored = Image<UInt8>(cgImage: cgImage)
214+
215+
XCTAssertEqual(restored.width, 3)
216+
XCTAssertEqual(restored.height, 2)
217+
218+
XCTAssertEqual(restored[0, 0], 1)
219+
XCTAssertEqual(restored[1, 0], 2)
220+
XCTAssertEqual(restored[2, 0], 3)
221+
222+
XCTAssertEqual(restored[0, 1], 4)
223+
XCTAssertEqual(restored[1, 1], 5)
224+
XCTAssertEqual(restored[2, 1], 6)
225+
}
226+
227+
do { // slices which contains the last row of the original images
228+
let transparent = PremultipliedRGBA<UInt8>(red: 0, green: 0, blue: 0, alpha: 0)
229+
let slice: ImageSlice<PremultipliedRGBA<UInt8>> = Image<PremultipliedRGBA<UInt8>>(width: 2, height: 3, pixels: [
230+
transparent, transparent,
231+
transparent, PremultipliedRGBA<UInt8>(red: 24, green: 49, blue: 99, alpha: 127),
232+
transparent, PremultipliedRGBA<UInt8>(red: 1, green: 2, blue: 3, alpha: 4),
233+
])[1...1, 1...2]
234+
235+
let cgImage = slice.cgImage
236+
let restored = Image<PremultipliedRGBA<UInt8>>(cgImage: cgImage)
237+
238+
XCTAssertEqual(restored.width, 1)
239+
XCTAssertEqual(restored.height, 2)
240+
241+
XCTAssertEqual(restored[0, 0], PremultipliedRGBA<UInt8>(red: 24, green: 49, blue: 99, alpha: 127))
242+
XCTAssertEqual(restored[0, 1], PremultipliedRGBA<UInt8>(red: 1, green: 2, blue: 3, alpha: 4))
243+
}
204244
}
205245

206246
func testWithCGImage() {

0 commit comments

Comments
 (0)