iOS: convertir un UIImage a la manipulación de memory de vImage

Tengo una function en la que convierto un UIImage a un vImage (para usar en algunos methods de vImage en Accelerate.framework de iOS.

El método que tengo es:

 -(vImage_Buffer)convertImage:(UIImage *)image { CGImageRef sourceRef = [image CGImage]; NSUInteger sourceWidth = CGImageGetWidth(sourceRef); NSUInteger sourceHeight = CGImageGetHeight(sourceRef); CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); unsigned char *sourceData = (unsigned char*)calloc(sourceHeight * sourceWidth * 4, sizeof(unsigned char)); NSUInteger bytesPerPixel = 4; NSUInteger sourceBytesPerRow = bytesPerPixel * sourceWidth; NSUInteger bitsPerComponent = 8; CGContextRef context = CGBitmapContextCreate(sourceData, sourceWidth, sourceHeight, bitsPerComponent, sourceBytesPerRow, colorSpace, kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Big); CGContextDrawImage(context, CGRectMake(0, 0, sourceWidth, sourceHeight), sourceRef); CGContextRelease(context); vImage_Buffer v_image = { .data = sourceData, .height = sourceHeight, .width = sourceWidth, .rowBytes = sourceBytesPerRow }; return v_image; } 

Construí esto mezclando y combinando algunos fragments de código en la web.

Mi pregunta es : tengo una llamada calloc que asigna el espacio para sourceData . ¿Pero cómo y dónde liberaría este recuerdo?

Dado que puedo llamar a este método muchas veces, parece como tal , habría una gran pérdida de memory. No creo que lo publique aquí porque proporciona el respaldo .data para mi variable vImage_Buffer . Pero, ¿lo liberaré en mi function de llamada? ¿O establecería v_image a nil ( o lo que sea que la variable devuelta se nombra en el método de llamada ) liberará finalmente la memory asignada por la línea calloc ?

¿Alguien tiene algún puntero?

En primer lugar, también debe liberar CGColorSpaceRelease(colorSpace) llamando a CGColorSpaceRelease(colorSpace)

La memory asignada por calloc puede liberarse más tarde en la function de llamada usando free(v_image.data) ( o lo que sea que la variable devuelta se nombra en el método de llamada ).

También puede cambiar la implementación de su método para deshacerse de CGContext y get bytes de CGImage utilizando CGDataProviderRef , sería algo así como:

 -(vImage_Buffer)convertImage:(UIImage *)image { CGImageRef sourceRef = [image CGImage]; NSUInteger sourceWidth = CGImageGetWidth(sourceRef); NSUInteger sourceHeight = CGImageGetHeight(sourceRef); CGDataProviderRef provider = CGImageGetDataProvider(sourceRef); CFDataRef bitmapData = CGDataProviderCopyData(provider); unsigned char *sourceData = (unsigned char*)calloc(sourceHeight * sourceWidth * 4, sizeof(unsigned char)); NSUInteger bytesPerPixel = 4; NSUInteger sourceBytesPerRow = bytesPerPixel * sourceWidth; CFDataGetBytes(bitmapData, CFRangeMake(0, CFDataGetLength(bitmapData)), sourceData); vImage_Buffer v_image = { .data = (void *)sourceData, .height = sourceHeight, .width = sourceWidth, .rowBytes = sourceBytesPerRow }; CFRelease(bitmapData); return v_image; } 

Sin embargo, no comprobé el performance.

También sugiero cambiar el nombre de su método a algo así como vImageCreateFromImage . Se dará count de que luego es responsable de limpiar la memory.

Primero, y lo más importante, esto se simplificó enormemente en iOS7.0 / OSX 10.9, con la introducción de la function vImageBuffer_InitWithCGImage (declarada en vImage_Utilities.h, con una documentation bastante extensa en el encabezado). Si no necesita admitir sistemas operativos antiguos, debería considerar usar esta nueva function.

En segundo lugar, ya sea que use su código existente o InitWithCGImage , una vez que haya terminado de usar un object vImage_Buffer creado por cualquier medio, debe liberar la memory asociada con el campo de datos: free(buffer.data); .