Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

DeathscytheSeph

macrumors newbie
Original poster
Jul 9, 2007
27
0
I wrote the program about the image

when i run with the small image like 160x120px it run properly but when i run with the bigger image like 800x600px it “EXC_BAD_ACCESS” T_T.

the problem is occur at the array because I create the array that keep the data of the pixel of the image so i have 2 array
1: colorValue[height][width][4];
2: labelValue[height * width];
that 2 array is the problem

Anyone help please

PS. I try to change it to pointer but it still have the problem when use memcpy T_T after i pass the array to the function

Thank you
 

lee1210

macrumors 68040
Jan 10, 2005
3,182
3
Dallas, TX
This seems like a LOT of memory to put on the stack. I don't know the types of your arrays, but assuming they're ints, the colorValue array is 7,680,000 bytes wide, and labelValue is 1,920,000, for a total of 9,600,000 bytes on the stack. Most of the time this will be much larger than will be allowed for the stack, leading to your problem. This much data should be placed on the heap. You could do this in various ways, but the most common would be to allocate:
Code:
height*width*sizeof(int)
or
Code:
height*width*4*sizeof(int)
bytes on the heap using malloc. The (void *) returned could be cast to an (int *), and assigned to an int * variable you have on the stack (using a nice, trim 4 or 8 bytes (sizeof(void *)) depending on your platform). It would take a lot more work to be able to handily treat this as a 3-dimensional array, because you would need a lot more pointers at each dimension. You could use multiple "indicies" into this memory that you invent and track, but to actually be able to say myArr[x][y][z] would take a herculean effort.

In the last thread I suggested this, but I will again... why not use the dynamic data structures already available for this purpose? You could easily make a class that is a simple int wrapper (instead of using NSNumber), and build a:
Code:
NSMutableArray of
  NSMutableArray of
    NSMutableArray of
      intWrapper which contains an
        int
(That's not code, not sure if quote maintains formatting)

You would access it as:
Code:
rPart = [[[[colorValue objectAtIndex:x] objectAtIndex:y] objectAtIndex:0] intValue];
gPart = [[[[colorValue objectAtIndex:x] objectAtIndex:y] objectAtIndex:1] intValue];
bPart = [[[[colorValue objectAtIndex:x] objectAtIndex:y] objectAtIndex:2] intValue];
alphaPart = [[[[colorValue objectAtIndex:x] objectAtIndex:y] objectAtIndex:3] intValue];
Though this would give you 96-bit colorspace, which is probably overkill, but it's just for example's sake. You could also have a method that does all of that for you:
Code:
-(int) valueFrom:(NSArray *)valList Xpos:(int)x Ypos:(int)y Zpos:(int)z {
  return [[[[valList objectAtIndex:x] objectAtIndex: y] objectAtIndex:z] intValue];
}

then you could call it as:

Code:
int rValue = [self valueFrom:colorList Xpos:x YPos:y Zpos:0];

The setup of this would require a bit of work, but it wouldn't be too bad (not as bad as a C-means of trying to make something you can get to with [][][]):
Code:
NSMutableArray *colorList = [[NSMutableArray alloc] init];
for(int x=0;x<height;x++){
  [colorList addObject:[[NSMutableArray alloc] init]];
  for(int y=0;y<width;y++) {
    [[colorList objectAtIndex:x] addObject:[[NSMutableArray alloc] init]];
    for(int z=0;z<4;z++) {
      [[[colorList objectAtIndex:x] objectAtIndex:y] addObject:[NSNumber initWithInt:0]];
    }
  }
}

This should be treated as pseduocode, even though i tried to write correct Objective-C. I am not at a mac, and don't have an objective-C environment set up here.

-Lee
 

DeathscytheSeph

macrumors newbie
Original poster
Jul 9, 2007
27
0
There is not enough information here for us to diagnose the problem or offer advice. Can you provide code snippets?

How are you computing 'width' and 'height'?

Width and Height is the size of the input image

this is the code snippet
NSLog(@"Begin Labeling image");
NSSize mySize = [self size];
int
row, column, widthInPixels = mySize.width, heightInPixels = mySize.height;
int colorValue[heightInPixels][widthInPixels][4],
labelValue[heightInPixels * widthInPixels];
// int*** colorValue;
//
// colorValue = (int***) malloc(sizeof(int***) * heightInPixels);
// for(int i = 0; i < heightInPixels;i++)
// {
// colorValue = (int**)malloc(widthInPixels * sizeof(int*));
// for(int j=0; j < widthInPixels;j++)
// {
// colorValue[j] = (int*)malloc(4 * sizeof(int));
// for(int k=0;k < 4;k++)
// {
// colorValue[j][k] = 0;
// }
// }
// }
//
// int * labelValue = (int*) malloc(sizeof(int) * heightInPixels * widthInPixels);
for (int i = 0; i < heightInPixels * widthInPixels; i++)
labelValue = 0;


//Read Pixel Data
[self lockFocus]; // necessary for NSReadPixel() to work.
for (row = 0; row < heightInPixels; row++)
for (column = 0; column < widthInPixels; column++)
{
NSColor
*pixelColor = NSReadPixel(NSMakePoint(column, heightInPixels - (row +1)));
colorValue[row][column][0] = [pixelColor redComponent] * 255;
colorValue[row][column][1] = [pixelColor greenComponent] * 255;
colorValue[row][column][2] = [pixelColor blueComponent] * 255;
colorValue[row][column][3] = [pixelColor alphaComponent] * 255;
}
[self unlockFocus];

int numLabel = 0;
if (![NSImage isBackGroundOfImage:self atX:0 atY:0])
labelValue[0 * widthInPixels + 0] = ++numLabel;

//label first row
for (column = 1; column < widthInPixels; column++)
{
if (![NSImage isBackGroundOfImage:self atX:column atY:0] &&
![NSImage isValueInRangeOfFirstValue:colorValue[0][column]
compareWith:colorValue[0][column - 1]]) {
labelValue[0 * widthInPixels + column] = ++numLabel;
} else {

labelValue[0 * widthInPixels + column] = numLabel;
}
}

//label entire row
for (row = 1; row < heightInPixels; row++)
for (column = 0; column < widthInPixels; column++)
if (![NSImage isBackGroundOfImage:self atX:column atY:row]) {
if ([NSImage isValueInRangeOfFirstValue:colorValue[row][column]
compareWith:colorValue[row][column - 1]]) {
labelValue[row * widthInPixels + column] = labelValue[row * widthInPixels + column - 1];
} else if ([NSImage isValueInRangeOfFirstValue:colorValue[row][column]
compareWith:colorValue[row - 1][column]]) {
labelValue[row * widthInPixels + column] = labelValue[(row - 1) * widthInPixels + column];
} else if ([NSImage isValueInRangeOfFirstValue:colorValue[row][column]
compareWith:colorValue[row - 1][column - 1]]) {
labelValue[row * widthInPixels + column] = labelValue[(row - 1) * widthInPixels + column - 1];
} else if ([NSImage isValueInRangeOfFirstValue:colorValue[row][column]
compareWith:colorValue[row - 1][column + 1]]) {
labelValue[row * widthInPixels + column] = labelValue[(row - 1) * widthInPixels + column + 1];
} else {
labelValue[row * widthInPixels + column] = ++numLabel;
}
}


//second pass
for (row = 1; row < heightInPixels; row++)
for (column = 0; column < widthInPixels; column++) {
if(column + 1 < widthInPixels && labelValue[row * widthInPixels + column] != labelValue[row * widthInPixels + column+1] &&
[NSImage isValueInRangeOfFirstValue:colorValue[row][column]
compareWith:colorValue[row][column + 1]]){
if(labelValue[row * widthInPixels + column]<labelValue[row * widthInPixels + column+1])
[NSImage reValueInArray:labelValue arrayHeight: heightInPixels widthOfRow:widthInPixels replaceValue:labelValue[row * widthInPixels + column + 1] withValue:labelValue[row * widthInPixels + column]];
else
[NSImage reValueInArray:labelValue arrayHeight: heightInPixels widthOfRow:widthInPixels replaceValue:labelValue[row * widthInPixels + column] withValue:labelValue[row * widthInPixels + column + 1]];
}
else if(column - 1 >= 0 && row+1<heightInPixels && labelValue[row * widthInPixels + column]!=labelValue[(row+1) * widthInPixels + column-1] &&
[NSImage isValueInRangeOfFirstValue:colorValue[row][column]
compareWith:colorValue[row - 1][column + 1]]){
if(labelValue[row * widthInPixels + column] < labelValue[(row+1) * widthInPixels + column-1])
[NSImage reValueInArray:labelValue arrayHeight: heightInPixels widthOfRow:widthInPixels replaceValue:labelValue[(row + 1) * widthInPixels + column - 1] withValue:labelValue[row * widthInPixels + column]];
else
[NSImage reValueInArray:labelValue arrayHeight: heightInPixels widthOfRow:widthInPixels replaceValue:labelValue[row * widthInPixels + column] withValue:labelValue[(row + 1) * widthInPixels + column - 1]];
}
else if(row+1<heightInPixels && labelValue[row * widthInPixels + column] != labelValue[(row+1) * widthInPixels + column]
&& [NSImage isValueInRangeOfFirstValue:colorValue[row][column]
compareWith:colorValue[row + 1][column]]){
if(labelValue[row * widthInPixels + column]<labelValue[(row+1) * widthInPixels + column])
[NSImage reValueInArray:labelValue arrayHeight: heightInPixels widthOfRow:widthInPixels replaceValue:labelValue[(row + 1) * widthInPixels + column] withValue:labelValue[row * widthInPixels + column]];
else
[NSImage reValueInArray:labelValue arrayHeight: heightInPixels widthOfRow:widthInPixels replaceValue:labelValue[row * widthInPixels + column] withValue:labelValue[(row + 1) * widthInPixels + column]];
}
else if(column+1<widthInPixels && row+1<heightInPixels && labelValue[row * widthInPixels + column]!=labelValue[(row+1) * widthInPixels + column+1]
&& [NSImage isValueInRangeOfFirstValue:colorValue[row][column]
compareWith:colorValue[row + 1][column + 1]]){
if(labelValue[row * widthInPixels + column]<labelValue[(row+1) * widthInPixels + column+1])
[NSImage reValueInArray:labelValue arrayHeight: heightInPixels widthOfRow:widthInPixels replaceValue:labelValue[(row + 1) * widthInPixels + column + 1] withValue:labelValue[row * widthInPixels + column]];
else
[NSImage reValueInArray:labelValue arrayHeight: heightInPixels widthOfRow:widthInPixels replaceValue:labelValue[row * widthInPixels + column] withValue:labelValue[(row + 1) * widthInPixels + column + 1]];
}


}


NSLog(@"End of Labeling Begin check how many of label");

bool checkInt[numLabel + 1];

for(int i = 0; i < numLabel + 1; i++)
checkInt = NO;

for(int i = 0; i < heightInPixels * widthInPixels; i++) {
checkInt[labelValue] = YES;
}

int numCheck = 0;
for (int i = 0; i < 23; i++)
if (checkInt)
numCheck++;


NSLog(@"%d", numCheck);


// Create the represent image
NSImage
*labeledImage = [[[self class] alloc] initWithSize:mySize];


// Need a place to put the monochrome pixels.
NSBitmapImageRep *blackAndWhiteRep =
[[NSBitmapImageRep alloc]
initWithBitmapDataPlanes: nil // Nil pointer tells the kit to allocate the pixel buffer for us.
pixelsWide: widthInPixels
pixelsHigh: heightInPixels
bitsPerSample: 8
samplesPerPixel: 2
hasAlpha: YES
isPlanar: NO
colorSpaceName: NSCalibratedWhiteColorSpace // 0 = black, 1 = white in this color space.
bytesPerRow: 0 // Passing zero means "you figure it out."
bitsPerPixel: 16]; // This must agree with bitsPerSample and samplesPerPixel.

monochromePixel
*pixels = (monochromePixel *)[blackAndWhiteRep bitmapData]; // -bitmapData returns a void*, not an NSData object ;-)

[self lockFocus]; // necessary for NSReadPixel() to work.
for (row = 0; row < heightInPixels; row++)
for (column = 0; column < widthInPixels; column++) {
monochromePixel
*thisPixel = &(pixels[((widthInPixels * row) + column)]);


// thisPixel->grayValue = 1.0 - rint(255 * // use this line for negative..
thisPixel->grayValue = (1.0 - (labelValue[(widthInPixels * row) + column] / (numCheck + 1.0))) * 255;

thisPixel->alpha = 255; // handle the transparency, too
}
[self unlockFocus];

[labeledImage addRepresentation:blackAndWhiteRep];
[blackAndWhiteRep release];

//return [labeledImage autorelease];
return labeledImage;
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.