     
     @_versioned
     @inline(__always)
+    func read_source<ColorModel: ColorModelProtocol>(_ source: UnsafePointer<ColorPixel<ColorModel>>, _ width: Int, _ height: Int, _ x: Int, _ y: Int) -> ColorPixel<ColorModel> {
+        
+        let x_range = 0..<width
+        let y_range = 0..<height
+        
+        let check1 = x_range.contains(x)
+        let check2 = y_range.contains(y)
+        
+        if check1 && check2 {
+            return source[y * width + x]
+        }
+        
+        let _x = x.clamped(to: x_range)
+        let _y = y.clamped(to: y_range)
+        
+        return source[_y * width + _x].with(opacity: 0)
+    }
+    
+    @_versioned
+    @inline(__always)
     func convolve<ColorModel: ColorModelProtocol>(source: UnsafePointer<ColorPixel<ColorModel>>, width: Int, height: Int, point: Point, kernel_size: Int, kernel: (Double) -> Double) -> ColorPixel<ColorModel> {
         
         var pixel = ColorPixel<ColorModel>()

        let min_y = _y - a + b
        let max_y = min_y + kernel_size
        
        let x_range = 0..<width
        let y_range = 0..<height
        
        for y in min_y..<max_y {
            for x in min_x..<max_x {
                let l = kernel((point - Point(x: x, y: y)).magnitude)
                let _source = x_range.contains(x) && y_range.contains(y) ? source[y * width + x] : source[y.clamped(to: y_range) * width + x.clamped(to: x_range)].with(opacity: 0)
                pixel += _source * l
                t += l
            }
        }
        return t == 0 ? ColorPixel<ColorModel>() : pixel / t

        let _y1 = _y2 - 1
        let _x4 = _x2 + 2
        let _y4 = _y2 + 2
        
        let _tx = point.x - Double(_x2)
        let _ty = point.y - Double(_y2)
        
        let _s1 = read_source(source, width, height, _x1, _y1)
        let _s2 = read_source(source, width, height, _x2, _y1)
        let _s3 = read_source(source, width, height, _x3, _y1)
        let _s4 = read_source(source, width, height, _x4, _y1)
        let _s5 = read_source(source, width, height, _x1, _y2)
        let _s6 = read_source(source, width, height, _x2, _y2)
        let _s7 = read_source(source, width, height, _x3, _y2)
        let _s8 = read_source(source, width, height, _x4, _y2)
        let _s9 = read_source(source, width, height, _x1, _y3)
        let _s10 = read_source(source, width, height, _x2, _y3)
        let _s11 = read_source(source, width, height, _x3, _y3)
        let _s12 = read_source(source, width, height, _x4, _y3)
        let _s13 = read_source(source, width, height, _x1, _y4)
        let _s14 = read_source(source, width, height, _x2, _y4)
        let _s15 = read_source(source, width, height, _x3, _y4)
        let _s16 = read_source(source, width, height, _x4, _y4)
        
        var color = ColorModel()
        
        for i in 0..<ColorModel.count {
            let _u1 = sampler(_tx, _s1.color.component(i), _s2.color.component(i), _s3.color.component(i), _s4.color.component(i))
            let _u2 = sampler(_tx, _s5.color.component(i), _s6.color.component(i), _s7.color.component(i), _s8.color.component(i))
            let _u3 = sampler(_tx, _s9.color.component(i), _s10.color.component(i), _s11.color.component(i), _s12.color.component(i))
            let _u4 = sampler(_tx, _s13.color.component(i), _s14.color.component(i), _s15.color.component(i), _s16.color.component(i))
            color.setComponent(i, sampler(_ty, _u1, _u2, _u3, _u4))
        }
        
        let a1 = sampler(_tx, _s1.opacity, _s2.opacity, _s3.opacity, _s4.opacity)
        let a2 = sampler(_tx, _s5.opacity, _s6.opacity, _s7.opacity, _s8.opacity)
        let a3 = sampler(_tx, _s9.opacity, _s10.opacity, _s11.opacity, _s12.opacity)
        let a4 = sampler(_tx, _s13.opacity, _s14.opacity, _s15.opacity, _s16.opacity)
        
        return ColorPixel<ColorModel>(color: color, opacity: sampler(_ty, a1, a2, a3, a4))
        
    }
}
