TestControl.java

/*
 * Copyright © 2012 Nokia Corporation. All rights reserved.
 * Nokia and Nokia Connecting People are registered trademarks of Nokia Corporation. 
 * Oracle and Java are trademarks or registered trademarks of Oracle and/or its
 * affiliates. Other product and company names mentioned herein may be trademarks
 * or trade names of their respective owners. 
 * See LICENSE.TXT for license information.
 */ 
package com.nokia.example.ammscamera;

import java.io.IOException;
import javax.microedition.amms.control.camera.*;
import javax.microedition.lcdui.*;
import javax.microedition.media.*;
import javax.microedition.media.control.VideoControl;

public abstract class TestControl
        implements CommandListener, PlayerListener {

    public TestControl(CameraMIDlet c) {
        snaps = 10;
        zoomlevel = 100;
        midlet = c;
        player = null;
        optionsForm = new Form("");
        cmdCapture = new Command("Capture", Command.OK, 0);
        cmdOptions = new Command("Options", Command.SCREEN, 0);
        cmdBack = new Command("Back", Command.BACK, 1);
    }

    public void setSupported(boolean supp) {
        supported = supp;
        if (!supported) {
            player.deallocate();
            player = null;
        }
    }

    public boolean isSupported() {
        return supported;
    }

    public boolean isInitialized() {
        return initialized;
    }

    public void createCameraForm(int key) {
        id = key;
        try {
            player = Manager.createPlayer(midlet.getPlayerType());
            player.addPlayerListener(this);
            player.realize();
            player.prefetch();
            videoControl = (VideoControl) player.getControl("VideoControl");
            if (videoControl == null) {
                midlet.showAlert("Error", "Video Control is null", canvas);
            }
            canvas = new VideoCanvas(this, videoControl, id);
            if (id == midlet.cameracontrol) {
                cameraControl = (CameraControl) player.getControl("javax.microedition.amms.control.camera.CameraControl");
                setSupported(cameraControl != null);
                canvas.setTitle("Camera Control Test");
            }
            else if (id == midlet.exposurecontrol) {
                exposureControl = (ExposureControl) player.getControl("javax.microedition.amms.control.camera.ExposureControl");
                setSupported(exposureControl != null);
                canvas.setTitle("Exposure Control Test");
            }
            else if (id == midlet.flashcontrol) {
                flashControl = (FlashControl) player.getControl("javax.microedition.amms.control.camera.FlashControl");
                setSupported(flashControl != null);
                canvas.setTitle("Flash Control Test");
            }
            else if (id == midlet.focuscontrol) {
                focusControl = (FocusControl) player.getControl("javax.microedition.amms.control.camera.FocusControl");
                setSupported(focusControl != null);
                canvas.setTitle("Focus Control Test");
            }
            else if (id == midlet.snapshotcontrol) {
                snapControl = (SnapshotControl) player.getControl("javax.microedition.amms.control.camera.SnapshotControl");
                setSupported(snapControl != null);
                if (snapControl != null) {
                    snapControl.setFilePrefix("snapshotTest");
                    String time = String.valueOf(System.currentTimeMillis());
                    snapControl.setFileSuffix(time.substring(0, 5) + ".jpg");
                }
                canvas.setTitle("Snapshot Control Test");
            }
            else if (id == midlet.zoomcontrol) {
                zoomControl = (ZoomControl) player.getControl("javax.microedition.amms.control.camera.ZoomControl");
                setSupported(zoomControl != null);
                canvas.setTitle("Zoom Control Test");
            }
            if (player.getState() == 300) {
                player.start();
            }
        }
        catch (IOException ioexception) {
        }
        catch (MediaException mediaexception) {
        }
        catch (NullPointerException nullpointerexception) {
        }
    }

    public boolean captureImage() {
        try {
            imageData = videoControl.getSnapshot("encoding=jpeg");
            capturedImage = Image.createImage(imageData, 0, imageData.length);
        }
        catch (MediaException exc) {
            midlet.showAlert("Error", exc.getMessage(), canvas);
            return false;
        }
        catch (SecurityException secExc) {
            midlet.showAlert("Security error", secExc.getMessage(), canvas);
            return false;
        }
        catch (NullPointerException exc) {
            midlet.showAlert("Null Pointer Error", "Null Pointer - videoControl not working ... ", canvas);
            return false;
        }
        catch (Exception e) {
            midlet.showAlert("Error", e.getMessage(), canvas);
            return false;
        }
        return true;
    }

    public boolean showCapturedImageAfterCapture() {
        return true;
    }

    public void showCapturedImage() {
        createImageForm();
        if (capturedImage != null) {
            imageForm.append(scaleImage(capturedImage, imageForm));
        }
        imageForm.setTitle("Captured image");
        CameraMIDlet.getDisplay().setCurrent(imageForm);
    }

    public void createImageForm() {
        imageForm = new Form("Captured image");
        cmdSave = new Command("Save", Command.OK, 0);
        imageForm.addCommand(cmdBack);
        imageForm.addCommand(cmdSave);
        imageForm.setCommandListener(this);
    }

    /**
     * Changes size of image, adapted from
     * http://www.developer.nokia.com/Community/Wiki/CS001269_-_Scaling_bitmaps_in_Java_ME
     *
     * @param sourceImage to be scaled
     * @param newImageWidth is the new width of the image
     * @param newImageHeight is the new height of the image
     */
    private Image scaleImage(Image sourceImage, int newImageWidth, int newImageHeight) {
        try {
            int srcWidth = sourceImage.getWidth();
            int srcHeight = sourceImage.getHeight();

            // An array for RGB, with the size of original image)  
            int rgbSource[] = new int[srcWidth * srcHeight];
            // An array for RGB, with the size of scaled image)  
            int rgb2Scaled[] = new int[newImageWidth * newImageHeight];

            // Get the RGB array of source image
            sourceImage.getRGB(rgbSource, 0, srcWidth, 0, 0, srcWidth, srcHeight);

            int tempScaleRatioWidth;
            int tempScaleRatioHeight;

            // calculations and bit shift operations to optimize the for loop
            tempScaleRatioWidth = ((srcWidth << 16) / newImageWidth);
            tempScaleRatioHeight = ((srcHeight << 16) / newImageHeight);

            int i = 0;
            for (int y = 0; y < newImageHeight; y++) {
                for (int x = 0; x < newImageWidth; x++) {
                    rgb2Scaled[i++] = rgbSource[(srcWidth
                            * ((y * tempScaleRatioHeight) >> 16))
                            + ((x * tempScaleRatioWidth) >> 16)];
                }
            }

            //Create an RGB image from rgbScaled array
            return Image.createRGBImage(rgb2Scaled,
                    newImageWidth, newImageHeight, true);

        }
        catch (ArithmeticException e) {
            // if newImageWidth or newImageHeight was 0, return the orig. image
            return sourceImage;
        }
    }

    private Image scaleImage(Image sourceImage, Form targetForm) {

        float targetFormWidth = (float) targetForm.getWidth();
        float targetFormHeight = (float) targetForm.getHeight() * 0.85f;

        float scaleFactor1 = targetFormWidth / (float) sourceImage.getWidth();
        float scaleFactor2 = targetFormHeight / (float) sourceImage.getHeight();
        float scaleFactor = (scaleFactor1 < scaleFactor2) ? scaleFactor1 : scaleFactor2;

        int targetWidth = (int) (sourceImage.getWidth() * scaleFactor);
        int targetHeight = (int) (sourceImage.getHeight() * scaleFactor);

        return scaleImage(sourceImage, targetWidth, targetHeight);

    }

    public void commandAction(Command command, Displayable display) {
        if (display.equals(optionsForm) && command.equals(cmdBack)) {
            SaveOptions();
            CameraMIDlet.getDisplay().setCurrent(canvas);

        }
        else if (display.equals(imageForm) && command.equals(cmdBack)) {
            CameraMIDlet.getDisplay().setCurrent(canvas);

        }
        else if (display.equals(imageForm) && command.equals(cmdSave)) {
            new ImageSaver(midlet, imageData, "jpeg", canvas, imageForm);
        }
    }

    public abstract void SaveOptions();

    public void playerUpdate(Player p, String event, Object obj) {
        switch (p.getState()) {
            case 400:
                initialized = true;
                break;
        }
    }

    public void zoomIn() {
        if (zoomControl != null) {
            if (-1001 > zoomControl.getMaxDigitalZoom()) {
                midlet.showAlert("Zoom Control", "Already zoomed in max amount", canvas);
            }
            else {
                zoomlevel = zoomControl.setDigitalZoom(-1001);
            }
        }
        else {
            midlet.showAlert("Zoom Control", "Zoom Not Supported.", canvas);
        }
        canvas.repaint();
    }

    protected void zoomOut() {
        if (zoomControl != null) {
            zoomlevel = zoomControl.setDigitalZoom(-1002);
        }
        else {
            midlet.showAlert("Zoom Control", "Zoom Not Supported.", canvas);
        }
        canvas.repaint();
    }

    public void setSnapshotNbr(int s) {
        snaps = s;
    }
    boolean supported;
    CameraMIDlet midlet;
    Player player;
    VideoControl videoControl;
    Command cmdCapture;
    Command cmdOptions;
    Command cmdBack;
    Command cmdSave;
    Canvas canvas;
    Form imageForm;
    Form optionsForm;
    byte imageData[];
    Image capturedImage;
    boolean initialized;
    int snaps;
    int zoomlevel;
    int id;
    ExposureControl exposureControl;
    CameraControl cameraControl;
    FlashControl flashControl;
    FocusControl focusControl;
    SnapshotControl snapControl;
    ZoomControl zoomControl;
    int width;
    int height;
    int zoomModes[];
}