Application terminating early because of GPUImageAverageColor block - objective-c

I'm receiving the following message in the console after my application quits early because it is terminating with an uncaught exception of type NSException.
* Terminating app due to uncaught exception 'NSRangeException', reason: '* -[__NSArrayM objectAtIndex:]: index 25 beyond bounds for empty array'
Here's my code:
NSMutableArray *redValues = [NSMutableArray array];
NSUInteger redValuesLength = [redValues count];
float totalOne, diffForAverage;
int amount = 1;
__block int counter = 0;
NSInteger j;
GPUImageVideoCamera *videoCamera = [[GPUImageVideoCamera alloc] initWithSessionPreset:AVCaptureSessionPreset640x480 cameraPosition:AVCaptureDevicePositionBack];
videoCamera.outputImageOrientation = UIInterfaceOrientationPortrait;
GPUImageAverageColor *averageColor = [[GPUImageAverageColor alloc] init];
[averageColor setColorAverageProcessingFinishedBlock:^(CGFloat redComponent, CGFloat greenComponent, CGFloat blueComponent, CGFloat alphaComponent, CMTime frameTime)
{
NSLog(#"%f", redComponent);
[redValues addObject:#(redComponent * 255)];
}];
[videoCamera addTarget:averageColor];
[videoCamera startCameraCapture];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 27 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
[videoCamera stopCameraCapture];
});
totalOne = [redValues[25] floatValue];
float average = totalOne / amount;
for (j = (counter + 25); j < (redValuesLength - 25); j++)
{
diffForAverage = average - [redValues[j + 1] floatValue];
if (diffForAverage > -1 && diffForAverage < 1)
{
totalOne += [redValues[j + 1] floatValue];
amount++;
[arrayOne addObject:[NSNumber numberWithInt:(j - 25)]];
counter++;
}
else
{
if (arrayOneLength >= 15)
{
break;
counter++;
}
else
{
[arrayOne removeAllObjects];
totalOne = [redValues[j + 1] floatValue];
counter++;
}
}
}
I understand that the error message I'm receiving means that my redValues array is empty, but I'm trying to visit and manipulate later elements. How can I solve this problem? I know that my GPUImageAverageColorBlock is printing red values correctly, but it seems that these values aren't being pushed into the array like I'm intending.

Related

Assigning to 'float' from incompatible type 'id'

The following error occurs on the two lines that are commented below:
Assigning to 'float' from incompatible type 'id'
NSMutableArray *redValues = [NSMutableArray array];
NSUInteger *redValuesLength = [redValues count];
NSMutableArray *arrayOne = [NSMutableArray array];
NSUInteger arrayOneLength = [arrayOne count];
__block int counter = 0;
int amount = 1;
float totalOne, diffForAverage;
NSInteger j;
totalOne = redValues[25]; // ERROR OCCURS HERE
float average = totalOne / amount;
for (j = (counter + 25); j < (redValuesLength - 25); j++)
{
diffForAverage = average - [redValues[j + 1] floatValue];
if (diffForAverage > -1 && diffForAverage < 1)
{
totalOne += [redValues[j + 1] floatValue];
amount++;
[arrayOne addObject:[NSNumber numberWithInt:(j - 25)]];
counter++;
}
else
{
if (arrayOneLength >= 15)
{
break;
counter++;
}
else
{
[arrayOne removeAllObjects];
totalOne = redValues[j + 1]; // ERROR OCCURS HERE
counter++;
}
}
}
Why is this error caused, and how can I fix it?
totalOne is float. And your array hold NSInteger. Change to that:
totalOne = [redValues[25] floatValue];

Code will never be executed warning

In my previous question, I asked why my application was terminating early. It turns out I'm getting this warning on one of the lines below and that may help me solve my problem.
Here's the code:
NSMutableArray *redValues = [NSMutableArray array];
NSUInteger redValuesLength = [redValues count];
float totalOne, diffForAverage;
int amount = 1;
__block int counter = 0;
NSInteger j;
GPUImageVideoCamera *videoCamera = [[GPUImageVideoCamera alloc] initWithSessionPreset:AVCaptureSessionPreset640x480 cameraPosition:AVCaptureDevicePositionBack];
videoCamera.outputImageOrientation = UIInterfaceOrientationPortrait;
GPUImageAverageColor *averageColor = [[GPUImageAverageColor alloc] init];
[averageColor setColorAverageProcessingFinishedBlock:^(CGFloat redComponent, CGFloat greenComponent, CGFloat blueComponent, CGFloat alphaComponent, CMTime frameTime)
{
NSLog(#"%f", redComponent);
[redValues addObject:#(redComponent * 255)];
}];
[videoCamera addTarget:averageColor];
[videoCamera startCameraCapture];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 27 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
[videoCamera stopCameraCapture];
});
totalOne = [redValues[25] floatValue];
float average = totalOne / amount;
for (j = (counter + 25); j < (redValuesLength - 25); j++)
{
diffForAverage = average - [redValues[j + 1] floatValue];
if (diffForAverage > -1 && diffForAverage < 1)
{
totalOne += [redValues[j + 1] floatValue];
amount++;
[arrayOne addObject:[NSNumber numberWithInt:(j - 25)]];
counter++;
}
else
{
if (arrayOneLength >= 15)
{
break;
counter++; // WARNING OCCURS HERE
}
else
{
[arrayOne removeAllObjects];
totalOne = [redValues[j + 1] floatValue];
counter++;
}
}
}
Why would the commented line above never be run? Is it a problem with my for loop, or my if statement, or something else entirely?
Because you have a break command just before it. The break command will immediately take you out of the for loop, so the next line won't be executed.

myArray count isn't functioning as expected

The arrayTwelveLEngth variable isn't working as expected. When I placed a breakpoint on the amount = 1; line above, I hovered over arrayTwelve, and found that it was empty with 0 elements. Immediately after, I then hovered about arrayTwelveLength, expecting to see 0, but instead it seems that the arrayTwelveLength had a value of 1876662112. I don't know how it got that value, and I need to solve that problem. What am I doing wrong?
NSMutableArray *redValues = [NSMutableArray array];
NSMutableArray *arrayTwelve = [NSMutableArray array];
__block int counter = 0;
__block NSInteger u;
NSUInteger redValuesLength = [redValues count];
__block int arrayTwelveLength = 0;
__block float diffForAverage, fps, averageTime, bloodSpeed;
float average;
__block int amount = 1;
__block float totalTwelve, totalThirteen;
__block NSUInteger totalNumberOfFramesInSmallArrays = 0;
__block NSUInteger totalNumberOfFramesNotInSmallArrays;
for (u = (counter + 24); u < (redValuesLength - 24); u++)
{
diffForAverage = average - [redValues[u + 1] floatValue];
float test = [redValues[u] floatValue];
arrayTwelveLength = [arrayTwelve count];
if (diffForAverage > -1 && diffForAverage < 1)
{
totalTwelve += [redValues[u + 1] floatValue];
amount++;
[arrayTwelve addObject:#(test)];
counter++;
}
else
{
if (arrayTwelveLength >= 8)
{
counter++;
break;
}
else
{
[arrayTwelve removeAllObjects];
totalTwelve = [redValues[u + 1] floatValue];
counter++;
amount = 1;
}
}
}
amount = 1; // I added a breakpoint here
totalThirteen = [redValues[u + 1] floatValue];
average = totalThirteen / amount;
if (counter == redValuesLength)
{
totalNumberOfFramesNotInSmallArrays = redValuesLength - totalNumberOfFramesInSmallArrays - 25 - (redValuesLength - counter);
fps = redValuesLength / 30;
averageTime = totalNumberOfFramesNotInSmallArrays / fps;
bloodSpeed = 3 / averageTime;
[_BloodSpeedValue setText:[NSString stringWithFormat:#"%f", bloodSpeed]];
}
if (arrayTwelveLength == NULL)
{
arrayTwelveLength = 0;
}
totalNumberOfFramesInSmallArrays += arrayTwelveLength;
You have problems with unsigned/signed types and with your data set the first for loop should not even enter, because your for loop index variable u (== 24) < (redValuesLength (== 0) - 24) but, because redValuesLength being Unsigned type it wraps around and you get:
(unsigned long)0 - (unsigned long)24 = -24 modulo ULONG_MAX + 1= 18446744073709551592
Also, you are not initialising average before usage.

Iterating backwards over an array throwing exception

I am trying to make an add method that works like long addition, so I want to start the addition from the end and work my way backwards so I can get the carrys right and etc. So I am currently trying to start working backwards over the array.
For example what im trying to do.
two arrays with the character 123456789
and i want to add them starting at 9 + 9 then move to 8+8
So I'm pretty sure I'm using the right way to iterate backwards over an array, but everytime I try I get just the runtime error, index out of bounds, and I can't figure out why. Any help would be great, I just cant figure out why it keeps throwing the exception.
-(MPInteger *) add: (MPInteger *) x
{
NSMutableArray *a = self->intString;
NSMutableArray *b = x->intString;
NSMutableArray *c = [NSMutableArray arrayWithCapacity:100];
//for (int i = 0; i < [a count]; i++) {
for (NSInteger i = [a count] - 1; i > 0; i--) {
int num = 10;
NSNumber *ourNum = [NSNumber numberWithInt:num];
NSNumber *total = [NSNumber numberWithInt:[[a objectAtIndex:i] intValue] + [[b objectAtIndex:i] intValue]];
if ([total intValue] >= [ourNum intValue]) {
total = [NSNumber numberWithInt:([total intValue] - [ourNum intValue])];
[c addObject:[NSNumber numberWithInt:([total intValue])]];
} else {
[c addObject:[NSNumber numberWithInt:[[a objectAtIndex:i] intValue]+[[b objectAtIndex:i] intValue]]];
}
NSLog(#"%#", c[i]);
}
return x;
}
First, let's clean up this code.
- (MPInteger *)add:(MPInteger *)x {
NSMutableArray *a = self->intString;
NSMutableArray *b = x->intString;
NSMutableArray *c = [NSMutableArray arrayWithCapacity:100];
for (NSInteger i = [a count] - 1; i > 0; i--) {
int num = 10;
NSNumber *ourNum = #(num);
NSNumber *total = #([a[i] intValue] + [b[i] intValue]);
if ([total intValue] >= [ourNum intValue]) {
total = #([total intValue] - [ourNum intValue]);
[c addObject:#([total intValue])];
} else {
[c addObject:#([a[i] intValue] + [b[i] intValue])];
}
NSLog(#"%#", c[i]);
}
return x;
}
Next, let's remove redundant/duplicate code.
- (MPInteger *)add:(MPInteger *)x {
NSMutableArray *a = self->intString;
NSMutableArray *b = x->intString;
NSMutableArray *c = [NSMutableArray arrayWithCapacity:100];
for (NSInteger i = [a count] - 1; i > 0; i--) {
int num = 10;
NSNumber *total = #([a[i] intValue] + [b[i] intValue]);
if ([total intValue] >= num) {
total = #([total intValue] - num);
}
[c addObject:total];
NSLog(#"%#", c[i]);
}
return x;
}
Now we can clearly see all of the issues.
You're going from [a count] - 1 to 1. You should be going all the way to 0.
a and b might have different sizes, so if you only do [a count] - 1 to 0, then if for example [b count] < [a count], you'll get an index out of bounds error when you try to access b[i].
You're adding stuff to the end of c, but you should be adding it to the beginning of c since you're iterating backwards.
You don't store the carry anywhere.
You are accessing c[i], which doesn't exist.
You are starting with an empty array 'c', and you NSLog c[i] which is obviously out of bounds on the first iteration.

array index out of bounds problems

So I'm making a biginteger program, and I'm having a problem with adding two arrays that aren't the same length. The problem I'm having is with the add method. If I'm iterating through an array is there any way to test if element is out of bounds. I've tried testing if the element in a is equal to nil, but I still get the exception. Any help would be great thanks.
#import <Foundation/Foundation.h>
#import "MPInteger.h"
#implementation MPInteger
{
}
-(id) initWithString: (NSString *) x
{
self = [super init];
if (self) {
intString = [NSMutableArray array];
for (int i = 0; i < [x length]; i++) {
NSString *ch = [x substringWithRange:NSMakeRange(i, 1)];
[intString addObject:ch];
}
}
return self;
}
-(NSString *) description
{
return self.description;
}
- (MPInteger *) add: (MPInteger *) x {
NSMutableArray *a = self->intString;
NSMutableArray *b = x->intString;
NSMutableArray *c = [NSMutableArray array];
NSInteger arrayCount;
if (a < b) {
arrayCount = [b count];
} else {
arrayCount = [a count];
}
int num = 10;
int carry = 1;
NSNumber *total;
NSNumber *carrySum;
for (int i = 0; i < arrayCount; i++) {
if (a[i] == nil) {
total = #([b[i] intValue]);
[c addObject:total];
} else if (b[i] == nil) {
total = #([a[i] intValue]);
[c addObject:total];
} else {
total = #([a[i] intValue] + [b[i] intValue]);
[c addObject:total];
}
}
for (NSInteger j = [c count]-1; j >=0; j--) {
if ([c[j] intValue] >= num) {
total = #([c[j] intValue] - num);
carrySum = #([c[j-1] intValue] + carry);
[c replaceObjectAtIndex:j withObject:total];
[c replaceObjectAtIndex:j-1 withObject: carrySum];
}
}
NSString *str = [c componentsJoinedByString:#""];
NSLog(#"%#", str);
return x;
}
-(MPInteger *) multiply: (MPInteger *) x
{
NSMutableArray *a = self->intString;
NSMutableArray *b = x->intString;
NSMutableArray *c = [NSMutableArray array];
NSMutableArray *sum = [NSMutableArray array];
NSNumber *total;
NSNumber *carrySum;
int num = 10;
NSNumber *endZero = 0;
NSInteger bottomCount = [b count]-1;
while (bottomCount != -1) {
for (int i = 0; i < [a count]; i++) {
total = #([a[i] intValue] * [[b objectAtIndex:bottomCount] intValue]);
if (bottomCount == [b count] -1) {
[c addObject:total];
} else {
[c replaceObjectAtIndex:i withObject:total];
}
}
for (NSInteger j = [c count]-1; j>=0; j--) {
NSString *carry = [NSString stringWithFormat:#"%d", [c[j] intValue]];
NSString *carry2 = [carry substringToIndex:1];
int carryFinal = [carry2 intValue];
NSString *carry3 = [carry2 stringByAppendingString:#"0"];
int carry4 = [carry3 intValue];
if ([c[j] intValue] >= num) {
total = #([c[j] intValue] - carry4);
carrySum = #([c[j-1] intValue] + carryFinal);
[c replaceObjectAtIndex:j withObject:total];
[c replaceObjectAtIndex:j-1 withObject: carrySum];
} else {
if(j == 0) {
if (bottomCount == [b count] -1) {
bottomCount = bottomCount - 1;
NSString *str = [c componentsJoinedByString:#""];
[sum addObject: str];
} else {
[c addObject:#([endZero intValue])];
bottomCount = bottomCount - 1;
NSString *str = [c componentsJoinedByString:#""];
[sum addObject: str];
}
}
}
}
}
NSMutableArray *finalSum = [NSMutableArray array];
MPInteger *ele1;
MPInteger *ele2;
MPInteger *eleSum;
NSNumber *endZ= #(0);
[finalSum insertObject:endZ atIndex:0];
for (int k = 0; k < [sum count]; k++) {
NSString *str= [NSString stringWithFormat:#"%d", [sum[k] intValue]];
NSString *str2 = [NSString stringWithFormat:#"%d", [sum[k+1] intValue]];
ele1 = [[MPInteger alloc] initWithString:str];
ele2 = [[MPInteger alloc] initWithString:str2];
eleSum = [ele1 add: ele2];
NSLog(#"%#", eleSum);
}
NSLog(#"%#", sum);
return self;
}
Updated this
for (int i = 0; i < arrayCount; i++) {
if (a[i] == nil) {
total = #([b[i] intValue]);
[c addObject:total];
} else if (b[i] == nil) {
total = #([a[i] intValue]);
[c addObject:total];
} else {
total = #([a[i] intValue] + [b[i] intValue]);
[c addObject:total];
}
}
has now become:
NSMutableArray *c = a.count > b.count ? [a mutableCopy] : [b mutableCopy];
NSArray *shortestArray = a.count > b.count ? b : a;
[shortestArray enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(NSNumber *currentNumber, NSUInteger idx, BOOL *stop) {
c[idx] = #(currentNumber.integerValue + [c[idx] integerValue]);
NSLog(#"%#", c[idx]);
}];
What I think I need to do is every index that is in array a and not b or vise versa, is add beginning zeros, but I don't know how to do that.
I printed out what it does after each iteration and it gives:
2013-09-02 12:31:42.630 Asgn1[42471:303] 5
2013-09-02 12:31:42.632 Asgn1[42471:303] 3
2013-09-02 12:31:42.632 Asgn1[42471:303] 1
And a final answer of:
2013-09-02 12:31:42.633 Asgn1[42471:303] 353
For the code that is failing would it not be simpler to take a mutableCopy of the large array and then loop over the smaller array for the calculations?
Perhaps something like this:
NSMutableArray *c = a.count > b.count ? [a mutableCopy] : [b mutableCopy];
NSArray *shortestArray = a.count > b.count ? b : a;
[shortestArray enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(NSNumber *currentNumber, NSUInteger idx, BOOL *stop) {
c[idx] = #(currentNumber.integerValue + [c[idx] integerValue]);
}];