Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Nuke-Avif-Plugin/Buffer/BufferConversion.swift
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ func converter8(
ypBufferData1.deallocate()
}

var ypCrDiffBuffer = vImage_Buffer(data: ypCbDiffBufferData, height: yp.pointee.height, width: avif.vWidth / 2, rowBytes: Int(alignedWidth) / 2 * MemoryLayout<UInt8>.size)
var ypCrDiffBuffer = vImage_Buffer(data: ypCrDiffBufferData, height: yp.pointee.height, width: avif.vWidth / 2, rowBytes: Int(alignedWidth) / 2 * MemoryLayout<UInt8>.size)
let ypCrDiffBufferArray = UnsafeMutablePointer<UnsafePointer<vImage_Buffer>?>.allocate(capacity: 1)
ypCrDiffBufferArray.initialize(to: &ypCrDiffBuffer)
defer {
Expand Down
2 changes: 1 addition & 1 deletion Nuke-Avif-Plugin/Buffer/BufferExtraction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func extract8(avif: avifImage, chromaShift: (x: Int, y: Int), pixelRange: vImage
[]
)
} else {
let dummyCrData = UnsafeMutableRawPointer.allocate(byteCount: cbcrWidth * MemoryLayout<Int>.size, alignment: 0)
let dummyCrData = UnsafeMutableRawPointer.allocate(byteCount: cbcrWidth * MemoryLayout<UInt8>.size, alignment: 0)
dummyCrData.initializeMemory(as: UInt8.self, repeating: UInt8(pixelRange.CbCr_bias), count: cbcrWidth)
return (
.init(data: dummyCrData,
Expand Down
60 changes: 38 additions & 22 deletions Nuke-Avif-Plugin/ColorSpace.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,37 @@

import CoreGraphics
import Accelerate
import Foundation
import libavif

private enum ColorSpaceCache {
private static let lock = NSLock()
private static var rgbColorSpaces: [CFString: CGColorSpace] = [:]
private static var monochromeColorSpaces: [String: CGColorSpace] = [:]

static func rgb(identifier: CFString, create: () -> CGColorSpace) -> CGColorSpace {
lock.lock()
defer { lock.unlock() }
if let cached = rgbColorSpaces[identifier] {
return cached
}
let colorSpace = create()
rgbColorSpaces[identifier] = colorSpace
return colorSpace
}

static func monochrome(identifier: String, create: () throws -> CGColorSpace) throws -> CGColorSpace {
lock.lock()
defer { lock.unlock() }
if let cached = monochromeColorSpaces[identifier] {
return cached
}
let colorSpace = try create()
monochromeColorSpaces[identifier] = colorSpace
return colorSpace
}
}

func calcRGBPrimaries(colorPrimaries: avifColorPrimaries) -> vImageRGBPrimaries {
var primaries = [Float](repeating: 0, count: 8)
avifColorPrimariesGetValues(colorPrimaries, &primaries)
Expand Down Expand Up @@ -45,7 +74,6 @@ func createColorSpaceRGB(colorPrimaries: avifColorPrimaries, transferCharacteris
}

private let defaultColorSpaceRGB = CGColorSpaceCreateDeviceRGB()
private var rgbColorSpaces = [CFString : CGColorSpace]()
func calcColorSpaceRGB(avif: avifImage) throws -> CGColorSpace {
if avif.icc.data != nil && avif.icc.size > 0 {
guard let iccData = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, avif.icc.data, avif.icc.size, kCFAllocatorNull) else { throw ColorSpaceError(message: "cfdata creation failed.") }
Expand All @@ -54,20 +82,13 @@ func calcColorSpaceRGB(avif: avifImage) throws -> CGColorSpace {
}

func cachedColorSpace(identifier: CFString) -> CGColorSpace {
if let colorSpace = rgbColorSpaces[identifier] {
return colorSpace
} else {
let colorSpace = CGColorSpace(name: identifier)!
rgbColorSpaces[identifier] = colorSpace
return colorSpace
ColorSpaceCache.rgb(identifier: identifier) {
CGColorSpace(name: identifier)!
}
}

switch (avif.colorPrimaries, avif.transferCharacteristics) {
case (AVIF_COLOR_PRIMARIES_UNKNOWN, AVIF_TRANSFER_CHARACTERISTICS_UNKNOWN),
(AVIF_COLOR_PRIMARIES_UNKNOWN, AVIF_TRANSFER_CHARACTERISTICS_UNKNOWN),
(AVIF_COLOR_PRIMARIES_UNKNOWN, AVIF_TRANSFER_CHARACTERISTICS_UNKNOWN),
(AVIF_COLOR_PRIMARIES_UNKNOWN, AVIF_TRANSFER_CHARACTERISTICS_UNKNOWN):
case (AVIF_COLOR_PRIMARIES_UNKNOWN, AVIF_TRANSFER_CHARACTERISTICS_UNKNOWN):
return defaultColorSpaceRGB

case (AVIF_COLOR_PRIMARIES_BT709, AVIF_TRANSFER_CHARACTERISTICS_BT709):
Expand Down Expand Up @@ -130,7 +151,6 @@ func createColorSpaceMonochrome(colorPrimaries: avifColorPrimaries, transferChar
}

private let defaultColorSpaceMonochrome = CGColorSpaceCreateDeviceGray()
private var monochromeColorSpaces = [String : CGColorSpace]()
func calcColorSpaceMonochrome(avif: avifImage) throws -> CGColorSpace {
if avif.icc.data != nil && avif.icc.size > 0 {
guard let iccData = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, avif.icc.data, avif.icc.size, kCFAllocatorNull) else { throw ColorSpaceError(message: "cfdata creation failed.") }
Expand All @@ -139,20 +159,16 @@ func calcColorSpaceMonochrome(avif: avifImage) throws -> CGColorSpace {
}

func cachedColorSpace(identifier: String) throws -> CGColorSpace {
if let colorSpace = monochromeColorSpaces[identifier] {
return colorSpace
} else {
let colorSpace = try createColorSpaceMonochrome(colorPrimaries: avif.colorPrimaries, transferCharacteristics: avif.transferCharacteristics)
monochromeColorSpaces[identifier] = colorSpace
return colorSpace
try ColorSpaceCache.monochrome(identifier: identifier) {
try createColorSpaceMonochrome(
colorPrimaries: avif.colorPrimaries,
transferCharacteristics: avif.transferCharacteristics
)
}
}

switch (avif.colorPrimaries, avif.transferCharacteristics) {
case (AVIF_COLOR_PRIMARIES_UNKNOWN, AVIF_TRANSFER_CHARACTERISTICS_UNKNOWN),
(AVIF_COLOR_PRIMARIES_UNKNOWN, AVIF_TRANSFER_CHARACTERISTICS_UNKNOWN),
(AVIF_COLOR_PRIMARIES_UNKNOWN, AVIF_TRANSFER_CHARACTERISTICS_UNKNOWN),
(AVIF_COLOR_PRIMARIES_UNKNOWN, AVIF_TRANSFER_CHARACTERISTICS_UNKNOWN):
case (AVIF_COLOR_PRIMARIES_UNKNOWN, AVIF_TRANSFER_CHARACTERISTICS_UNKNOWN):
return defaultColorSpaceMonochrome

case (AVIF_COLOR_PRIMARIES_BT709, AVIF_TRANSFER_CHARACTERISTICS_BT709):
Expand Down