How to have really big numbers in NSRange

Discussion in 'Mac Programming' started by isthisonetaken, Feb 10, 2011.

  1. isthisonetaken macrumors regular

    Jun 29, 2006
    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:

    // 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];
    	[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?


  2. chown33 macrumors 604

    Aug 9, 2009
    Sailing beyond the sunset
  3. lee1210 macrumors 68040


    Jan 10, 2005
    Dallas, TX
    My fault, I did this wrong in a previous thread, though I did correct it and explained the problem.

  4. isthisonetaken thread starter macrumors regular

    Jun 29, 2006
    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!

Share This Page