Prevent a bunch of unnecessary CG->NS<-CI image conversions
This commit is contained in:
parent
3c7c1f865a
commit
8a83dbc25b
1 changed files with 62 additions and 62 deletions
|
@ -6,7 +6,7 @@ import Accelerate
|
|||
struct SilicaChunk {
|
||||
var x: Int = 0
|
||||
var y: Int = 0
|
||||
var image: NSImage = NSImage()
|
||||
var image: CGImage?
|
||||
}
|
||||
|
||||
struct SilicaLayerData {
|
||||
|
@ -103,7 +103,7 @@ class Document: NSDocument {
|
|||
/*
|
||||
Returns the correct tile size, taking into account the remainder between tile size and image size.
|
||||
*/
|
||||
func getTileSize(x: Int, y: Int) -> (Int, Int) {
|
||||
func getTileSize(_ x: Int, _ y: Int) -> (Int, Int) {
|
||||
var width: Int = info.tileSize
|
||||
var height: Int = info.tileSize
|
||||
|
||||
|
@ -146,7 +146,7 @@ class Document: NSDocument {
|
|||
let x = chunk.x
|
||||
var y = chunk.y
|
||||
|
||||
let (width, height) = getTileSize(x: x, y: y)
|
||||
let (width, height) = getTileSize(x, y)
|
||||
|
||||
if y == rows {
|
||||
y = 0
|
||||
|
@ -240,7 +240,7 @@ class Document: NSDocument {
|
|||
return .luminosity
|
||||
}
|
||||
|
||||
return .sourceOver;
|
||||
return .sourceAtop
|
||||
}
|
||||
|
||||
func parseSilicaLayer(archive: Archive, dict: NSDictionary, isMask: Bool) -> SilicaLayer? {
|
||||
|
@ -288,7 +288,7 @@ class Document: NSDocument {
|
|||
let queue = DispatchQueue(label: "imageWork")
|
||||
|
||||
DispatchQueue.concurrentPerform(iterations: chunkPaths.count) { (i: Int) in
|
||||
guard let threadArchive = Archive(data: self.data!, accessMode: Archive.AccessMode.read) else {
|
||||
guard let threadArchive = Archive(data: self.data!, accessMode: .read) else {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -298,7 +298,7 @@ class Document: NSDocument {
|
|||
return
|
||||
}
|
||||
|
||||
let (width, height) = getTileSize(x: x, y: y)
|
||||
let (width, height) = getTileSize(x, y)
|
||||
|
||||
let numChannels = isMask ? 1 : 4
|
||||
let byteSize = width * height * numChannels
|
||||
|
@ -327,10 +327,8 @@ class Document: NSDocument {
|
|||
return
|
||||
}
|
||||
|
||||
let image = NSImage(cgImage: cgimage, size: NSZeroSize)
|
||||
|
||||
queue.async(group: dispatchGroup) {
|
||||
layer.data.chunks[i].image = image
|
||||
layer.data.chunks[i].image = cgimage
|
||||
layer.data.chunks[i].x = x
|
||||
layer.data.chunks[i].y = y
|
||||
}
|
||||
|
@ -491,41 +489,44 @@ class Document: NSDocument {
|
|||
ccgContext?.setFillColor(info.backgroundColor)
|
||||
ccgContext?.fill(info.cgRect)
|
||||
|
||||
var masterImage = ccgContext?.makeImage()
|
||||
let context = CIContext()
|
||||
var masterImage = CIImage(cgImage: (ccgContext?.makeImage())!)
|
||||
|
||||
var previousImage: CGImage? = masterImage
|
||||
var previousImage: CGImage? = nil
|
||||
|
||||
for layer in info.layers.reversed() {
|
||||
if !layer.data.hidden {
|
||||
// start by creating a new layer composite image, needed for image masking
|
||||
let layerContext = CGContext(data: nil, width: info.width, height: info.height, bitsPerComponent: 8, bytesPerRow: info.width * 4, space: info.colorSpace, bitmapInfo: bitmapInfo.rawValue)
|
||||
|
||||
let graphicsContext = NSGraphicsContext(cgContext: layerContext!, flipped: false)
|
||||
layerContext?.clear(info.cgRect)
|
||||
|
||||
var maskContext: CGContext?
|
||||
|
||||
let kernel = getBlendKernel(layer)
|
||||
|
||||
Swift.print(layer.name + " is " + kernel!.name)
|
||||
|
||||
if layer.mask != nil {
|
||||
let grayColorSpace = CGColorSpaceCreateDeviceGray()
|
||||
let maskBitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.none.rawValue).union(.byteOrder16Big)
|
||||
|
||||
let maskContext = CGContext(data: nil, width: info.width, height: info.height, bitsPerComponent: 16, bytesPerRow: 0, space: grayColorSpace, bitmapInfo: maskBitmapInfo.rawValue)
|
||||
maskContext = CGContext(data: nil, width: info.width, height: info.height, bitsPerComponent: 16, bytesPerRow: 0, space: grayColorSpace, bitmapInfo: maskBitmapInfo.rawValue)
|
||||
|
||||
maskContext?.setFillColor(.white)
|
||||
maskContext?.fill(info.cgRect)
|
||||
|
||||
let kernel = getBlendKernel(layer)
|
||||
|
||||
if layer.mask != nil {
|
||||
for chunk in layer.mask!.chunks {
|
||||
if !layer.data.hidden {
|
||||
maskContext?.draw(chunk.image.cgImage(forProposedRect: nil, context: graphicsContext, hints: nil)!, in: getChunkRect(chunk))
|
||||
}
|
||||
maskContext?.draw(chunk.image!, in: getChunkRect(chunk))
|
||||
}
|
||||
}
|
||||
|
||||
for chunk in layer.data.chunks {
|
||||
layerContext?.setAlpha(CGFloat(layer.data.opacity))
|
||||
layerContext?.setBlendMode(.copy)
|
||||
layerContext?.setBlendMode(.normal)
|
||||
|
||||
if !layer.data.hidden {
|
||||
layerContext?.draw(chunk.image.cgImage(forProposedRect: nil, context: graphicsContext, hints: nil)!, in: getChunkRect(chunk))
|
||||
layerContext?.draw(chunk.image!, in: getChunkRect(chunk))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -536,7 +537,7 @@ class Document: NSDocument {
|
|||
let newImage = layerImage!.masking(result!)
|
||||
|
||||
previousImage = newImage
|
||||
} else if layer.mask != nil {
|
||||
} else if layer.mask != nil && maskContext != nil {
|
||||
let maskImage = (maskContext?.makeImage())!
|
||||
let newImage = layerImage!.masking(maskImage)!
|
||||
|
||||
|
@ -546,13 +547,12 @@ class Document: NSDocument {
|
|||
}
|
||||
|
||||
// apply image
|
||||
let ciImage = CIImage(cgImage: (masterImage)!)
|
||||
let newCiImage = kernel!.apply(foreground: CIImage(cgImage: previousImage!), background: ciImage, colorSpace: info.colorSpace)
|
||||
|
||||
masterImage = context.createCGImage(newCiImage!, from: info.cgRect, format: .RGBA8, colorSpace: info.colorSpace)!
|
||||
masterImage = kernel!.apply(foreground: CIImage(cgImage: previousImage!), background: masterImage, colorSpace: info.colorSpace)!
|
||||
}
|
||||
}
|
||||
|
||||
var image = NSImage(cgImage: masterImage!, size: info.nsSize)
|
||||
let cgImage = context.createCGImage(masterImage, from: info.cgRect, format: .RGBA8, colorSpace: info.colorSpace)!
|
||||
var image = NSImage(cgImage: cgImage, size: info.nsSize)
|
||||
|
||||
if info.orientation == 3 {
|
||||
image = image.imageRotatedByDegreess(degrees: 90)
|
||||
|
|
Reference in a new issue