//--------------------------------------------------------------------------------
unsigned char*  ofxCvFloatImage::getPixels(){
    if(bPixelsDirty) {
    
        if( cvGrayscaleImage == NULL ) {
            cvGrayscaleImage = cvCreateImage( cvSize(width,height), IPL_DEPTH_8U, 1 );
        }
         
        pushROI();
        resetImageROI(cvGrayscaleImage);         
        convertFloatToGray(cvImage, cvGrayscaleImage);
        popROI();
    
        if(pixels == NULL) {
            // we need pixels, allocate it
            pixels = new unsigned char[width*height];
            pixelsWidth = width;
            pixelsHeight = height;            
        } else if(pixelsWidth != width || pixelsHeight != height) {
            // ROI changed, reallocate pixels for new size
            delete pixels;
            pixels = new unsigned char[width*height];
            pixelsWidth = width;
            pixelsHeight = height;
        }
        
        // copy from ROI to pixels
        for( int i = 0; i < height; i++ ) {
            memcpy( pixels + (i*width),
                    cvGrayscaleImage->imageData + (i*cvGrayscaleImage->widthStep),
                    width );
        }
        bPixelsDirty = false;
    }
	return pixels;        
}
//--------------------------------------------------------------------------------
void ofxCvFloatImage::setFromPixels( const unsigned char* _pixels, int w, int h ) {
    // This sets the internal image ignoring any ROI
	if( w == 0 || h == 0 ){
		ofLog(OF_LOG_ERROR, "in setFromPixels, w and h cannot = 0");
		return;
	}
    if( !bAllocated || w != width || h != height ) {
		ofLog(OF_LOG_NOTICE, "in setFromPixels, reallocating to match dimensions");	
		allocate(w,h);
	}

    if( w == width && h == height ) {
        ofRectangle lastROI = getROI();
        if( cvGrayscaleImage == NULL ) {
            cvGrayscaleImage = cvCreateImage( cvSize(width,height), IPL_DEPTH_8U, 1 );
        }
        resetImageROI(cvGrayscaleImage);
        // copy _pixels into cvGrayscaleImage
        for( int i=0; i < height; i++ ) {
            memcpy( cvGrayscaleImage->imageData + (i*cvGrayscaleImage->widthStep),
                    _pixels + (i*w),
                    width );
        }
        convertGrayToFloat(cvGrayscaleImage, cvImage);
        setROI(lastROI);
        flagImageChanged();
    } else {
        ofLog(OF_LOG_ERROR, "in setFromPixels, size mismatch");
    }
}
//--------------------------------------------------------------------------------
IplImage*  ofxCvFloatImage::getCv8BitsImage() {
	if( !bAllocated ){
		ofLog(OF_LOG_WARNING, "in getCv8BitsImage, image is not allocated");		
	}
		
	if(bPixelsDirty) {
		if( cvGrayscaleImage == NULL ) {
			cvGrayscaleImage = cvCreateImage( cvSize(width,height), IPL_DEPTH_8U, 1 );
		}

		ofRectangle lastROI = getROI();

		resetImageROI(cvGrayscaleImage);
		convertFloatToGray(cvImage, cvGrayscaleImage);
		setROI(lastROI);
	}
	return cvGrayscaleImage;
}
//--------------------------------------------------------------------------------
void ofxCvFloatImage::setFromPixels( unsigned char* _pixels, int w, int h ) {
    // This sets the internal image ignoring any ROI
    
    if( w == width && h == height ) {
        pushROI();
        if( cvGrayscaleImage == NULL ) {
            cvGrayscaleImage = cvCreateImage( cvSize(width,height), IPL_DEPTH_8U, 1 );
        }        
        resetImageROI(cvGrayscaleImage);    
        // copy _pixels into cvGrayscaleImage
        for( int i=0; i < height; i++ ) {
            memcpy( cvGrayscaleImage->imageData + (i*cvGrayscaleImage->widthStep),
                    _pixels + (i*w),
                    width );
        }
        convertGrayToFloat(cvGrayscaleImage, cvImage);
        popROI();
        flagImageChanged();
    } else {
        ofLog(OF_LOG_ERROR, "in setFromPixels, size mismatch");
    }    
}