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) -> 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(&destPtr, srcPtr, Int32(srcImg.width), Int32(srcImg.height))
let destCgContext = CGContext(data: &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 < 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;
}
}
bgraToGrayScale()
, so there's nothing to worry about. Unless you want this function to allocate memory for the converted image and return a pointer to that new image? \$\endgroup\$ – G. Sliepen Dec 21 '19 at 21:13assert(int(255f*.11+255f*.59+255f*.3) < 256)
. (hm,==255
?)) \$\endgroup\$ – greybeard Dec 22 '19 at 0:33