views:

11

answers:

0

Hello All,

I have an object that holds a pointer to some malloced memory, when I come to dealloc the object I use the free command to free up the malloced memory, how ever the free command appears to be absolutely doing nothing and I'm getting large memory leaks as a result. I have confirmed that the dealloc command is being executed.

Header

//
//  Copyright 2010 None. All rights reserved.
//


@interface BufferedImage : NSObject {
 CGColorSpaceRef colorSpace; 
 unsigned char *data;
 uint32_t* dataInt;
 size_t width;
 size_t height;
 size_t bitsPerComponent;
 size_t bytesPerPixel;
 size_t bytesPerRow;
 size_t dataSize;
 size_t power_w;
 size_t power_h;
 size_t origin_ajust;
 size_t width_bits;
}

@property CGColorSpaceRef colorSpace;
@property unsigned char *data;
@property uint32_t* dataInt;
@property size_t width;
@property size_t height;
@property size_t bitsPerComponent;
@property size_t bytesPerPixel;
@property size_t bytesPerRow;
@property size_t dataSize;
@property size_t power_w;
@property size_t power_h;
@property size_t origin_ajust;
@property size_t width_bits;

-(BufferedImage*) initWithW:(size_t) w
        h:(size_t) h;

-(UIImage*)getUIImage;
-(void)setABGRatX:(int) x
    y:(int) y
    integer:(uint32_t) integer;
-(CGContextRef)getCGContext;
-(uint32_t)getABGRatX:(int) x
      y:(int) y;
-(void)maskABGRatX:(int) x
     y:(int) y
     integer:(uint32_t) integer;

-(void)maskWithBufferedImageAtX:(int) nx
         y:(int) ny
      image:(BufferedImage*) image;
-(void)setAsImage:(BufferedImage*) image;
@end

Main

//
//  Copyright 2010 None. All rights reserved.
//

#import "BufferedImage.h"


@implementation BufferedImage

@synthesize colorSpace;
@synthesize data;
@synthesize dataInt;
@synthesize width;
@synthesize height;
@synthesize bitsPerComponent;
@synthesize bytesPerPixel;
@synthesize bytesPerRow;
@synthesize dataSize;
@synthesize power_w;
@synthesize power_h;
@synthesize origin_ajust;
@synthesize width_bits;

- (void)dealloc
{
 CGColorSpaceRelease(self.colorSpace);
 free(self.data);
 self.data = 0;
 [super dealloc];
}

-(CGContextRef)getCGContext{
 @synchronized(self) {
  return CGBitmapContextCreate(self.data, self.power_w, self.power_h, 
           self.bitsPerComponent, self.bytesPerRow, self.colorSpace, 
           kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);

 // return context;
 }
}

-(UIImage*)getUIImage{
 @synchronized(self) {
  CGContextRef context = CGBitmapContextCreate(self.data, self.power_w, self.power_h, 
            self.bitsPerComponent, self.bytesPerRow, self.colorSpace, 
            kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);

  CGImageRef imageRef = CGBitmapContextCreateImage(context);
  UIImage *result = [UIImage imageWithCGImage:imageRef];
  CGImageRelease(imageRef);
  CGContextRelease(context);

  return result; 
 }
}

-(BufferedImage*)init{ 
 return [self initWithW:320 h:480];
}

-(BufferedImage*) initWithW:(size_t) w
        h:(size_t) h{

 CGColorSpaceRef colorS = CGColorSpaceCreateDeviceRGB();

 size_t bitsPerC = 8;
 size_t bytesPerP    = 4;
 size_t bytesPR      = (w * bitsPerC * bytesPerP + 7) / 8;
 size_t dataS        = bytesPR * h;

 unsigned char *d = malloc(dataS);
 memset(d, 0, dataS);

 CGContextRef con = CGBitmapContextCreate(d, w, h, 
            bitsPerC, bytesPR, colorS, 
            kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); 

 CGImageRef imageRef = CGBitmapContextCreateImage(con);
 UIImage *result = [UIImage imageWithCGImage:imageRef];
 CGImageRelease(imageRef);

 CGColorSpaceRelease(colorS);
 CGContextRelease(con);
 free(d);

 return [self initWithImage:result];
}

-(BufferedImage*)initWithImage:(UIImage*)source
{
 if(self = [super init]){
  CGImageRef sourceRef = source.CGImage;
  self.width = CGImageGetWidth(sourceRef);
  self.height = CGImageGetHeight(sourceRef);

  power_w = 1;
  while (power_w < self.width) {
   power_w <<= 1;
  }

  uint32_t n = power_w - 1;
  width_bits = 0;
  while (n) {
   width_bits += n & 0x1u;
   n >>= 1;
  }

  //self.width;//512;
  //512;
  power_h = self.height;// + 20; // As we are not using it for scrolling we can get away with this //1;
  //while (power_h < self.height) {
  // power_h <<= 1;
  //}

  origin_ajust = power_h - 1;

  self.colorSpace = CGColorSpaceCreateDeviceRGB();

  self.bitsPerComponent = 8;
  self.bytesPerPixel    = 4;
  self.bytesPerRow      = (power_w * self.bitsPerComponent * self.bytesPerPixel + 7) / 8;
  self.dataSize         = self.bytesPerRow * power_h;

  self.data = 0;
  self.data = malloc(self.dataSize);
  memset(self.data, 0, self.dataSize);
  self.dataInt = (uint32_t*) self.data;

  CGContextRef context = CGBitmapContextCreate(self.data, power_w, power_h, 
            self.bitsPerComponent, self.bytesPerRow, self.colorSpace, 
            kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);


  CGContextDrawImage(context, CGRectMake(0, 0, self.width, self.height), sourceRef);
  //free(self.data);
  CGContextRelease(context);
 }

 return self;
}

-(void)setABGRatX:(int) x
    y:(int) y
    integer:(uint32_t) integer{
 int byteIndex = ((origin_ajust-y) << width_bits) + x;

 self.dataInt[byteIndex] = integer;
}


-(void)maskWithBufferedImageAtX:(int) nx
    y:(int) ny
    image:(BufferedImage*) image{

 for (int i = 0; i < image.height; i++) {
   int newy = i + ny;

  uint32_t * copy = self.dataInt;
  uint32_t * copy2 = image.dataInt;

  copy += ((self.origin_ajust-newy) << self.width_bits) + nx;
  copy2 += ((image.origin_ajust-i) << image.width_bits);

  for (int j = 0; j < image.width; j++) {
   *copy &= *copy2;

   copy++;
   copy2++;
  }
 }
}

-(void)setAsImage:(BufferedImage*) image{

 for (int i = 0; i < image.height; i++) {
  uint32_t * copy = self.dataInt;
  uint32_t * copy2 = image.dataInt;

  copy += ((self.origin_ajust-i) << self.width_bits);
  copy2 += ((image.origin_ajust-i) << image.width_bits);

  for (int j = 0; j < image.width; j++) {
   *copy = *copy2;

   copy++;
   copy2++;
  }
 }

 self.width = image.width;
 self.height = image.height;
}

-(void)maskABGRatX:(int) x
    y:(int) y
    integer:(uint32_t) integer{
 int byteIndex = ((origin_ajust-y) << width_bits) + x;

 self.dataInt[byteIndex] &= integer;
}

-(uint32_t)getABGRatX:(int) x
      y:(int) y {

 y = (y>origin_ajust)?(origin_ajust):(y); // A fixes a bug that happens on the device but not in the simulator.

 @synchronized(self) {
  //int byteIndex = (power_w * (origin_ajust-y)) + x;
  int byteIndex = ((origin_ajust-y) << width_bits) + x;

  return self.dataInt[byteIndex];
 }
}

@end

Thanks in advance.