package com.github.sarxos.webcam.ds.javacv;

import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.io.File;

import org.bytedeco.javacpp.videoInputLib.videoInput;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.FrameGrabber;
import org.bytedeco.javacv.Java2DFrameConverter;

import com.github.sarxos.webcam.WebcamDevice;
import com.github.sarxos.webcam.WebcamException;
import com.github.sarxos.webcam.WebcamResolution;
import com.github.sarxos.webcam.util.OsUtils;


/**
 * UNSTABLE, EXPERIMENTALL STUFF !!!
 * 
 * @author bfiryn
 */
public class JavaCvDevice implements WebcamDevice {

	private int address = -1;
	private File vfile = null;

	private String name = null;
	private FrameGrabber grabber = null;

	private volatile boolean open = false;
	private volatile boolean disposed = false;

	public JavaCvDevice(int address) {
		this.address = address;
	}

	public JavaCvDevice(File vfile) {
		this.vfile = vfile;
	}

	@Override
	public String getName() {
		if (name == null) {
			switch (OsUtils.getOS()) {
				case WIN:
					name = videoInput.getDeviceName(address).getString();
					break;
				case NIX:
					name = vfile.getAbsolutePath();
					break;
				case OSX:
					throw new UnsupportedOperationException("Mac OS is not supported");
			}
		}
		return name;
	}

	@Override
	public Dimension[] getResolutions() {
		// grabber.get

		throw new WebcamException("Not implemented");
	}

	@Override
	public Dimension getResolution() {
		return WebcamResolution.VGA.getSize();
	}

	@Override
	public void setResolution(Dimension size) {
		throw new WebcamException("Not implemented");
	}

	@Override
	public BufferedImage getImage() {

		if (!open) {
			throw new WebcamException("Cannot grab image - webcam device is not open");
		}

		Frame frame = null;
		try {
			frame = grabber.grab();
		} catch (Exception e) {
			throw new WebcamException("OpenCV cannot grab image frame", e);
		}
		if (frame == null) {
			throw new WebcamException("OpenCV image frame is null");
		}

		return new Java2DFrameConverter().getBufferedImage(frame);

	}

	private FrameGrabber buildGrabber() throws FrameGrabber.Exception {
		switch (OsUtils.getOS()) {
			case WIN:
				return FrameGrabber.createDefault(address);
			case NIX:
				return FrameGrabber.createDefault(vfile);
			case OSX:
			default:
				throw new UnsupportedOperationException("Current OS is not supported");
		}
	}

	public FrameGrabber getGrabber() {
		return grabber;
	}

	@Override
	public void open() {

		if (open || disposed) {
			return;
		}

		try {

			grabber = buildGrabber();
			grabber.start();

			open = true;

		} catch (FrameGrabber.Exception e) {
			release();
			throw new WebcamException(e);
		}
	}

	private void release() {
		if (grabber != null) {
			try {
				grabber.release();
			} catch (FrameGrabber.Exception e) {
				throw new WebcamException(e);
			}
		}
	}

	@Override
	public void close() {

		if (!open) {
			return;
		}

		try {
			grabber.stop();
		} catch (FrameGrabber.Exception e) {
			throw new WebcamException(e);
		} finally {
			dispose();
		}
	}

	@Override
	public void dispose() {
		disposed = true;
	}

	@Override
	public boolean isOpen() {
		return open;
	}

	@Override
	public String toString() {
		return getClass().getName() + "#address=" + address + "#vfile=" + vfile;
	}
}

@@ -558,17 +558,16 @@
  !!!%0D%0A *
- 
 %0D%0A * @au
@@ -2144,24 +2144,15 @@
 r().
-getBufferedImage
+convert
 (fra

Use convert() instead of getBufferedImage() as suggested