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

isthisonetaken

macrumors regular
Original poster
Jun 29, 2006
123
0
Hey guys,

so with help last night in another thread, I was able to open an mjpeg file and go through it to get the data associated with the individual pictures making up the file. This is the code used for that:

Code:
// load video 1 into a data object
NSString *path = @"/path/to/the/file/Movies/video1.mjpeg";
NSData *vid1 = [[NSData alloc] initWithContentsOfFile:path];

long int position = 0;
long int pictureCount = 0;
long int size = 0;
const char *sizeBytes;
NSRange range;
NSString *imagePath = @"";
	
NSLog(@"vid1 length: %ld", [vid1 length]);
while (position < [vid1 length]) {
	// find the picture size
	position += size; // get to the right spot in the bit stream
	range = NSMakeRange(position, (position + 5));
	NSData *picSize = [vid1 subdataWithRange:range];
	sizeBytes = [picSize bytes];
	size = strtol(sizeBytes, NULL, 0);
	
	// move the position in the byte stream to the end of the size bytes
	position += 5; 
	
	// load the bytes for the picture
	range = NSMakeRange(position, size);
	NSData *picture = [vid1 subdataWithRange:range];
		
	// create an NSImage based on the data
	NSImage *image = [[NSImage alloc] initWithDataIgnoringOrientation:picture];
	pictureCount++;
	[videoPlayer setImage:image];
		
	// add the image to the directory
	imagePath = @"";
	imagePath = [imagePath stringByAppendingFormat:@"path/to/the/pictures/pics/image%ld.jpeg", pictureCount];
		
        // code to save the NSImage as a .jpeg
	picture = [image TIFFRepresentation];
	NSBitmapImageRep *imageRep = [NSBitmapImageRep imageRepWithData:picture];
	NSDictionary *imageProps = [NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:1.0] forKey:NSImageCompressionFactor];
	picture = [imageRep representationUsingType:NSJPEGFileType properties:imageProps];
	BOOL success = [picture writeToFile:imagePath atomically:NO]; 
	if (!success) {
		NSLog(@"Something went wrong writing the image to the file...");
	}
		
	NSLog(@"Position: %ld\n", position);
	// release the image object
	[image release];
}

When I run it, it appears to work properly. The image view ends up with a picture in it and the folder is full of 301 pictures. Problem is, the picture that ends up in the image view is not the last frame from the video and from earlier work, I think there should be about twice as many pictures. I added in the calls to NSLog to see what was going on and it ends up spitting this out at the end:
2011-02-10 17:57:24.494 Video Decoder[43585:a0f] Position: 17758931
2011-02-10 17:57:24.553 Video Decoder[43585:a0f] Position: 17819849
2011-02-10 17:57:24.554 Video Decoder[43585:a0f] *** -[NSConcreteData subdataWithRange:]: range {17880739, 17880744} exceeds data length 35675568

17 million isn't greater than 35 million, so it shouldn't be exceeding the data length? Is it that range can't hold numbers that big? If so, is there any way to change it so it can?

Thanks,

Dan
 
My fault, I did this wrong in a previous thread, though I did correct it and explained the problem.

-Lee

Ah, I see where I went wrong now. That first call to range should just be 5, not position+5. I was looking at that thinking position is 0 to start and not thinking about past that first run through the loop. Thanks for the help again!
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.