     
     @inlinable
     @inline(__always)
-    func _cooleyTukey_convolution(_ horizontal_filter: [RawPixel.Scalar], _ vertical_filter: [RawPixel.Scalar]) -> Self {
-        
-        let width = self.width
-        let height = self.height
-        let numberOfComponents = self.numberOfComponents
-        
-        let n_width = width + horizontal_filter.count - 1
-        let n_height = height + vertical_filter.count - 1
-        
-        guard width > 0 && height > 0 else { return self }
-        
-        let length1 = Radix2CircularConvolveLength(width, horizontal_filter.count)
-        let length2 = Radix2CircularConvolveLength(height, vertical_filter.count)
-        
-        var buffer = MappedBuffer<RawPixel.Scalar>(repeating: 0, count: length1 + length2 + length1 * height, fileBacked: self.fileBacked)
-        var result = MappedBuffer<RawPixel>(repeating: RawPixel.zero, count: n_width * length2, fileBacked: self.fileBacked)
+    func _cooleyTukey_convolution_horizontal(_ filter: [RawPixel.Scalar]) -> Self {
+        
+        let width = self.width
+        let height = self.height
+        let numberOfComponents = self.numberOfComponents
+        
+        let n_width = width + filter.count - 1
+        
+        guard width > 0 && height > 0 else { return self }
+        
+        let length = Radix2CircularConvolveLength(width, filter.count)
+        
+        var buffer = MappedBuffer<RawPixel.Scalar>(repeating: 0, count: length, fileBacked: self.fileBacked)
+        var result = MappedBuffer<RawPixel>(repeating: RawPixel.zero, count: n_width * (height - 1) + length, fileBacked: self.fileBacked)
         
         buffer.withUnsafeMutableBufferPointer {
             

                    
                    let _kreal = buffer
                    let _kimag = buffer + 1
                    let _temp = buffer + length
                    
                    HalfRadix2CooleyTukey(log2n, filter, 1, filter.count, _kreal, _kimag, 2)
                    
                    for _ in 0..<numberOfComponents {
                        
                        _Radix2FiniteImpulseFilter(log2n, height, source, numberOfComponents, numberOfComponents * width, width, _kreal, _kimag, 2, 0, _temp, 1, length)
                        
                        do {
                            var _temp = _temp
                            var output = output
                            let out_stride = numberOfComponents * n_width
                            for _ in 0..<height {
                                Move(n_width, _temp, 1, output, numberOfComponents)
                                _temp += length
                                output += out_stride
                            }
                        }
                        
                        source += 1
                        output += 1
                    }
                }
            }
        }
        
        return result
    }
    
    @inlinable
    @inline(__always)
    func _cooleyTukey_convolution_vertical(_ filter: [RawPixel.Scalar]) -> Self {
        
        let width = self.width
        let height = self.height
        let numberOfComponents = self.numberOfComponents
        
        let n_height = height + filter.count - 1
        
        guard width > 0 && height > 0 else { return self }
        
        let length = Radix2CircularConvolveLength(height, filter.count)
        
        var buffer = MappedBuffer<RawPixel.Scalar>(repeating: 0, count: length, fileBacked: self.fileBacked)
        var result = MappedBuffer<RawPixel>(repeating: RawPixel.zero, count: width * length, fileBacked: self.fileBacked)
        
        buffer.withUnsafeMutableBufferPointer {
            
            guard let buffer = $0.baseAddress else { return }
            
            self.withUnsafeBytes {
                
                guard let source = $0.bindMemory(to: RawPixel.Scalar.self).baseAddress else { return }
                
                result.withUnsafeMutableBytes {
                    
                    guard let output = $0.bindMemory(to: RawPixel.Scalar.self).baseAddress else { return }
                    
                    let log2n = log2(length)
                    
                    let _kreal = buffer
                    let _kimag = buffer + 1
                    
                    HalfRadix2CooleyTukey(log2n, filter, 1, filter.count, _kreal, _kimag, 2)
                    
                    let row = width * numberOfComponents
                    _Radix2FiniteImpulseFilter(log2n, row, source, row, 1, height, _kreal, _kimag, 2, 0, output, row, 1)
                }
            }
        }

    
    @inlinable
    @inline(__always)
    func _direct_convolution_horizontal(_ filter: [RawPixel.Scalar]) -> Self {
        
        let width = self.width
