//
//  MPT_RimageCamera.m
//  AUCoderDemo
//
//  Created by Andrew Salamon on 9/5/06.
//  Copyright (c) 2006 Machine Perception Laboratory. University of California San Diego.
//  All rights reserved.

#import "MPT_RimageCamera.h"

#include <QuickTime/QuickTime.h>

#import "MPT_RimageAdaptor.h"

@interface MPT_RimageCamera(PrivateMethods)
- (MPT_RimageAdaptor *)rimageFromGWorld:(GWorldPtr)_gWorld;
@end

@implementation MPT_RimageCamera
- (void)didUpdate;
{
	[super didUpdate];
    if( [delegate respondsToSelector:@selector(camera:didReceiveRImage:)] )
	{
        MPT_RimageAdaptor *adaptor = [self rimageFromGWorld:gWorld];
        if( adaptor )
            [delegate camera:self didReceiveRImage:adaptor];
    }
}

/// divide image values by this to normalize (usually 255.0 or 1.0)
static const float norm = 255.0;

- (MPT_RimageAdaptor *)rimageFromGWorld:(GWorldPtr)_gWorld
{
	PixMapHandle pixMapHandle = GetGWorldPixMap(_gWorld);
	void * baseAddr = GetPixBaseAddr(pixMapHandle);
	size_t rowBytes = GetPixRowBytes(pixMapHandle);
	size_t width = boundsRect.right;
	size_t height = boundsRect.bottom;
	size_t subsampling = 1;
	
	MPT_RimageAdaptor *adaptor = [[MPT_RimageAdaptor alloc] initWithWidth:width/subsampling height:height/subsampling];
	
	u_int32_t *sourceImg = (u_int32_t *)baseAddr;
	u_int32_t *srcptr, src;
	u_int32_t rowstep = (rowBytes/4)*subsampling;
	u_int32_t colstep = subsampling;
	u_int32_t destwidth = width/subsampling;
	float *array = [adaptor array];

	for( int i = 0; i < height/subsampling; ++i )
	{
		float *dst = array + i*destwidth;
		int n = destwidth;
		
		srcptr = (u_int32_t*)(sourceImg + i*rowstep);
		
		while( n-- )
		{
			src = *srcptr;
			float floatVal = ((306 * ((src >> 16) & 0xff)) + 
							  (601 * ((src >>  8) & 0xff)) + 
							  (117 * ((src >>  0) & 0xff))) >> 10;
			floatVal /= norm;
			*dst++ = floatVal;
			srcptr+=colstep;
		}
	}
	
	return [adaptor autorelease];
}


@end
