Skip to content
This repository has been archived by the owner on Sep 22, 2024. It is now read-only.

Commit

Permalink
add scale factor in decoder
Browse files Browse the repository at this point in the history
  • Loading branch information
Maxim Kolesnik committed Oct 26, 2022
1 parent 830040e commit 2349bc0
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 94 deletions.
125 changes: 75 additions & 50 deletions Sources/NukeWebP/NukeWebP.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,72 +7,97 @@ import UIKit.UIImage
import AppKit.NSImage
#endif

#if !os(macOS)
public typealias ImageType = UIImage
#else
public typealias ImageType = NSImage
#if os(watchOS)
import ImageIO
import CoreGraphics
import WatchKit.WKInterfaceDevice
#endif

public protocol WebPDecoding: Sendable {
func decode(data: Data) throws -> ImageType
func decodei(data: Data) throws -> ImageType
func decode(data: Data) throws -> CGImage
func decodei(data: Data) throws -> CGImage
}

private let _queue = DispatchQueue(label: "com.webp.decoder", autoreleaseFrequency: .workItem)

public final class WebPImageDecoder: ImageDecoding, @unchecked Sendable {

private let decoder: WebPDecoding

public init(decoder: WebPDecoding) {
self.decoder = decoder
}

public func decode(_ data: Data) throws -> ImageContainer {
return try _queue.sync(execute: {
let image = try decoder.decode(data: data)
return ImageContainer(image: image, type: .webp, data: data)
})

}

private let decoder: WebPDecoding
private let context: ImageDecodingContext

public init(decoder: WebPDecoding, context: ImageDecodingContext) {
self.decoder = decoder
self.context = context
}
private var defaultScale: CGFloat {
#if os(iOS) || os(tvOS)
return UIScreen.main.scale
#elseif os(watchOS)
return WKInterfaceDevice.current().screenScale
#elseif os(macOS)
return 1
#endif
}

private var scale: CGFloat {
context.request.userInfo[.scaleKey] as? CGFloat ?? defaultScale
}

public func decode(_ data: Data) throws -> ImageContainer {
return try _queue.sync(execute: {
let cgImage = try decoder.decode(data: data)
#if !os(macOS)
let image = PlatformImage(cgImage: cgImage, scale: scale, orientation: .up)
#else
let image = PlatformImage(cgImage: cgImage, size: NSSize(width: cgImage.width, height: cgImage.height))
#endif
return ImageContainer(image: image, type: .webp, data: data)
})

public func decodePartiallyDownloadedData(_ data: Data) -> ImageContainer? {
do {
return try _queue.sync(execute: {
let image = try decoder.decodei(data: data)
return ImageContainer(image: image, type: .webp, data: data)
})
} catch {
return nil
}
}

public func decodePartiallyDownloadedData(_ data: Data) -> ImageContainer? {
do {
return try _queue.sync(execute: {
let cgImage = try decoder.decodei(data: data)
#if !os(macOS)
let image = PlatformImage(cgImage: cgImage, scale: scale, orientation: .up)
#else
let image = PlatformImage(cgImage: cgImage, size: NSSize(width: cgImage.width, height: cgImage.height))
#endif
return ImageContainer(image: image, type: .webp, data: data)
})
} catch {
return nil
}
}
}

// MARK: - check webp format data.
extension WebPImageDecoder {

public static func enable(closure: @escaping () -> WebPDecoding) {
Nuke.ImageDecoderRegistry.shared.register { (context) -> ImageDecoding? in
WebPImageDecoder.enable(context: context, closure: closure)
}

public static func enable(closure: @escaping () -> WebPDecoding) {
Nuke.ImageDecoderRegistry.shared.register { (context) -> ImageDecoding? in
WebPImageDecoder.enable(context: context, closure: closure)
}
public static func enable(auto closure: @escaping @autoclosure () -> WebPDecoding) {
Nuke.ImageDecoderRegistry.shared.register { (context) -> ImageDecoding? in
WebPImageDecoder.enable(context: context, closure: closure)
}
}

public static func enable(auto closure: @escaping @autoclosure () -> WebPDecoding) {
Nuke.ImageDecoderRegistry.shared.register { (context) -> ImageDecoding? in
WebPImageDecoder.enable(context: context, closure: closure)
}
public static func enable(context: ImageDecodingContext, closure: @escaping () -> WebPDecoding) -> Nuke.ImageDecoding? {
/// Use native WebP decoder for decode image
if #available(OSX 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *) {
return nil
} else {
let type = AssetType(context.data)
if type == .webp {
return WebPImageDecoder(decoder: closure())
}
}
return nil
}
public static func enable(context: ImageDecodingContext, closure: @escaping () -> WebPDecoding) -> Nuke.ImageDecoding? {
/// Use native WebP decoder for decode image
if #available(OSX 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *) {
return nil
} else {
let type = AssetType(context.data)
if type == .webp {
return WebPImageDecoder(decoder: closure(), context: context)
}
}
return nil
}
}

23 changes: 5 additions & 18 deletions Sources/NukeWebPAdvanced/AdvancedWebPDecoder.swift
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
import libwebp
import NukeWebP
import Foundation

#if !os(macOS)
import UIKit.UIImage
#else
import AppKit.NSImage
#endif
import CoreGraphics

public final class AdvancedWebPDecoder: WebPDecoding, @unchecked Sendable {

Expand All @@ -17,19 +12,11 @@ public final class AdvancedWebPDecoder: WebPDecoding, @unchecked Sendable {
self.options = options
}

public func decode(data: Data) throws -> ImageType {
#if !os(macOS)
return try decoder.decode(toUImage: data, options: options)
#else
return try decoder.decode(toNSImage: data, options: options)
#endif
public func decode(data: Data) throws -> CGImage {
return try decoder.decode(data, options: options)
}

public func decodei(data: Data) throws -> ImageType {
#if !os(macOS)
return try decoder.decodei(toUImage: data, options: options)
#else
return try decoder.decodei(toNSImage: data, options: options)
#endif
public func decodei(data: Data) throws -> CGImage {
return try decoder.decodei(data, options: options)
}
}
2 changes: 1 addition & 1 deletion Sources/NukeWebPAdvanced/WebPDecoder+Platform.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Foundation
import libwebp

#if os(macOS) || os(iOS)
#if os(macOS) || os(iOS) || os(watchOS)
import CoreGraphics

extension WebPDecoder {
Expand Down
32 changes: 7 additions & 25 deletions Sources/NukeWebPBasic/BasicWebPDecoder.swift
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
import libwebp
import NukeWebP
import Foundation

#if !os(macOS)
import UIKit.UIImage
#else
import AppKit.NSImage
#endif
import CoreGraphics

public enum BasicWebPDecoderError: Error {
case unknownError
case underlyingError(Error)
}

public final class BasicWebPDecoder: WebPDecoding {
public final class BasicWebPDecoder: WebPDecoding, @unchecked Sendable {

deinit {
if idec != nil {
Expand All @@ -23,29 +18,16 @@ public final class BasicWebPDecoder: WebPDecoding {

public init() { }

public func decode(data: Data) throws -> ImageType {
let image = try decodeCGImage(data: data)

#if !os(macOS)
return UIImage(cgImage: image)
#else
return NSImage(cgImage: image, size: NSSize(width: image.width, height: image.height))
#endif
public func decode(data: Data) throws -> CGImage {
return try decodeCGImage(data: data)
}

public func decodei(data: Data) throws -> ImageType {
let image = try decodeiCGImage(data: data)
public func decodei(data: Data) throws -> CGImage {
return try decodeiCGImage(data: data)

#if !os(macOS)
return UIImage(cgImage: image)
#else
return NSImage(cgImage: image, size: NSSize(width: image.width, height: image.height))
#endif
}

var idec: OpaquePointer?


private var idec: OpaquePointer?

private func decodeiCGImage(data webPData: Data) throws -> CGImage {
var mutableWebPData = webPData
Expand Down

0 comments on commit 2349bc0

Please sign in to comment.