From ef10d110989eb36f34925d31e4cdb4452da15fca Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Mon, 21 Nov 2022 11:40:05 -0500 Subject: [PATCH] Insert more error checks --- SilicaViewer/SilicaEngine.swift | 46 +++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/SilicaViewer/SilicaEngine.swift b/SilicaViewer/SilicaEngine.swift index 82f2a9a..ea530b7 100644 --- a/SilicaViewer/SilicaEngine.swift +++ b/SilicaViewer/SilicaEngine.swift @@ -43,9 +43,11 @@ class SilicaEngine { var maskContext: CGContext? - let kernel = getBlendKernel(layer) + guard let kernel = getBlendKernel(layer) else { + return nil + } - if layer.mask != nil { + if let mask = layer.mask { let grayColorSpace = CGColorSpaceCreateDeviceGray() let maskBitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.none.rawValue).union(.byteOrder16Big) @@ -60,7 +62,7 @@ class SilicaEngine { maskContext?.setFillColor(.white) maskContext?.fill(document.cgRect()) - for chunk in layer.mask!.chunks { + for chunk in mask.chunks { if let image = chunk.image { maskContext?.draw(image, in: document.getChunkRect(chunk)) } @@ -72,7 +74,9 @@ class SilicaEngine { layerContext?.setBlendMode(.normal) if !layer.data.hidden { - layerContext?.draw(chunk.image!, in: document.getChunkRect(chunk)) + if let image = chunk.image { + layerContext?.draw(image, in: document.getChunkRect(chunk)) + } } } @@ -83,9 +87,9 @@ class SilicaEngine { var clippedMaster: CGImage? = layerImage for layer in clippingLayers { // so we if we want to clip, we want to gather all of the clipping layers in order first... - let temporaryClippedMaster = blendLayer(document: document, layer: layer, previousImage: &clippedMaster) - - clippedMaster = context.createCGImage(temporaryClippedMaster, from: document.cgRect(), format: .RGBA8, colorSpace: document.colorSpace) + if let temporaryClippedMaster = blendLayer(document: document, layer: layer, previousImage: &clippedMaster) { + clippedMaster = context.createCGImage(temporaryClippedMaster, from: document.cgRect(), format: .RGBA8, colorSpace: document.colorSpace) + } } layerContext?.setAlpha(1.0) @@ -106,7 +110,9 @@ class SilicaEngine { } // apply image - masterImage = kernel!.apply(foreground: CIImage(cgImage: previousImage!), background: masterImage, colorSpace: document.colorSpace)! + masterImage = kernel.apply(foreground: CIImage(cgImage: previousImage!), + background: masterImage, + colorSpace: document.colorSpace)! } } @@ -116,7 +122,7 @@ class SilicaEngine { func makeBlendImage(document: SilicaDocument, layer: SilicaLayer) -> CGImage { var maskContext: CGContext? - if layer.mask != nil { + if let mask = layer.mask { let grayColorSpace = CGColorSpaceCreateDeviceGray() let maskBitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.none.rawValue).union(.byteOrder16Big) @@ -131,8 +137,10 @@ class SilicaEngine { maskContext?.setFillColor(.white) maskContext?.fill(document.cgRect()) - for chunk in layer.mask!.chunks { - maskContext?.draw(chunk.image!, in: document.getChunkRect(chunk)) + for chunk in mask.chunks { + if let image = chunk.image { + maskContext?.draw(image, in: document.getChunkRect(chunk)) + } } } @@ -161,7 +169,9 @@ class SilicaEngine { layerContext?.setBlendMode(.normal) if !layer.hidden { - layerContext?.draw(chunk.image!, in: document.getChunkRect(chunk)) + if let image = chunk.image { + layerContext?.draw(image, in: document.getChunkRect(chunk)) + } } } @@ -173,7 +183,7 @@ class SilicaEngine { /// - layer: The `SilicaLayer` to draw. /// - previousImage: Previous `CGImage` to draw on top of, can be null. /// - Returns: A `CIImage` of the new image. - func blendLayer(document: SilicaDocument, layer : SilicaLayer, previousImage : inout CGImage?) -> CIImage { + func blendLayer(document: SilicaDocument, layer : SilicaLayer, previousImage : inout CGImage?) -> CIImage? { let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue).union(.byteOrder32Big) // start by creating a new layer composite image, needed for image masking @@ -187,21 +197,25 @@ class SilicaEngine { layerContext?.clear(document.cgRect()) - let kernel = getBlendKernel(layer) + guard let kernel = getBlendKernel(layer) else { + return nil + } for chunk in layer.data.chunks { layerContext?.setAlpha(CGFloat(layer.data.opacity)) layerContext?.setBlendMode(.normal) if !layer.data.hidden { - layerContext?.draw(chunk.image!, in: document.getChunkRect(chunk)) + if let image = chunk.image { + layerContext?.draw(image, in: document.getChunkRect(chunk)) + } } } let layerImage = layerContext?.makeImage() // apply image - return kernel!.apply(foreground: CIImage(cgImage: layerImage!), background: previousImage == nil ? CIImage(color: .clear) : CIImage(cgImage: previousImage!), colorSpace: document.colorSpace)! + return kernel.apply(foreground: CIImage(cgImage: layerImage!), background: previousImage == nil ? CIImage(color: .clear) : CIImage(cgImage: previousImage!), colorSpace: document.colorSpace)! } /// Figures out the correct `CIBlendKernel` corresponding to the `SilicaLayer`'s blending mode.