Convert image to grayscale To convert JPEG file, C function, bgraToGrayscale is called from Swift.

Is there a better way to 

1.allocate memory and 

2.access pointers 

than the ways they have been done in code below?

And maybe things that have been completely missed, like freeing memory?

converter.swift

func BGRAToGrayscale(srcImg: CGImage) -&gt; CGImage {
    let BytesPerPixel = 4

    guard let srcProv = srcImg.dataProvider else { fatalError("dataProvider is nil") }
    guard let srcProvData = srcProv.data else { fatalError("dataProvider.data is nil") }

    let srcPtr = CFDataGetBytePtr(srcProvData)
    let srcSize = srcImg.width * srcImg.height * BytesPerPixel

    var destPtr = [CUnsignedChar](repeating: 0, count: srcSize)
    bgraToGrayscale(&amp;destPtr, srcPtr, Int32(srcImg.width), Int32(srcImg.height))

    let destCgContext = CGContext(data: &amp;destPtr,
                                  width: srcImg.width, height: srcImg.height,
                                  bitsPerComponent: srcImg.bitsPerComponent,
                                  bytesPerRow: srcImg.bytesPerRow,
                                  space: srcImg.colorSpace!,
                                  bitmapInfo: srcImg.bitmapInfo.rawValue)

    guard let destImg = destCgContext?.makeImage() else {
      fatalError("Destination Image is nil")
    }

    return destImg
}


converter.c (slow way of converting to grayscale, will write assembly code for this, just for the sake of learning :-) )

void bgraToGrayscale( unsigned char * __restrict dest, const unsigned char* src, int width, int height ) {
  int BYTES_PER_PIXEL = 4;
  int numPixels = width * height;

  for( int idx=0; idx &lt; numPixels; idx++ ) {

    float weight = ((float)src[0]) * 0.11 +
                  ((float)src[1]) * 0.59 +
                  ((float)src[2]) * 0.3;

    dest[0] = (int)weight;
    dest[1] = (int)weight;
    dest[2] = (int)weight;
    dest[3] = src[3];
    dest += BYTES_PER_PIXEL;
    src += BYTES_PER_PIXEL;
  }
}
// Not following Swift naming conventions, should be bytesPerPixel
let BytesPerPixel = 4

// Better to make function throwable and throw specific error.
guard let srcProv = srcImg.dataProvider else { fatalError("dataProvider is nil") }
guard let srcProvData = srcProv.data else { fatalError("dataProvider.data is nil") }


For unwrap of srcImg.colorSpace! is not good solution, I would recommend to use guard ... else and throw an exception if value is nil.

Overall: why you are using abbreviations and shortcuts for every variable/constant name? It is much harder to read such code