/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.cts.verifier.camera.formats;

import com.android.cts.verifier.PassFailButtons;
import com.android.cts.verifier.R;

import android.app.AlertDialog;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.ImageFormat;
import android.graphics.Matrix;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.hardware.Camera.CameraInfo;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.util.SparseArray;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Surface;
import android.view.TextureView;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.Toast;

import java.io.IOException;
import java.lang.Math;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Comparator;
import java.util.List;
import java.util.TreeSet;

/**
 * Tests for manual verification of the CDD-required camera output formats
 * for preview callbacks
 */
public class CameraFormatsActivity extends PassFailButtons.Activity
        implements TextureView.SurfaceTextureListener, Camera.PreviewCallback {

    private static final String TAG = "CameraFormats";

    private TextureView mPreviewView;
    private SurfaceTexture mPreviewTexture;
    private int mPreviewTexWidth;
    private int mPreviewTexHeight;
    private int mPreviewRotation;

    private ImageView mFormatView;

    private Spinner mCameraSpinner;
    private Spinner mFormatSpinner;
    private Spinner mResolutionSpinner;

    private int mCurrentCameraId = -1;
    private Camera mCamera;

    private List<Camera.Size> mPreviewSizes;
    private Camera.Size mNextPreviewSize;
    private Camera.Size mPreviewSize;
    private List<Integer> mPreviewFormats;
    private int mNextPreviewFormat;
    private int mPreviewFormat;
    private SparseArray<String> mPreviewFormatNames;

    private ColorMatrixColorFilter mYuv2RgbFilter;

    private Bitmap mCallbackBitmap;
    private int[] mRgbData;
    private int mRgbWidth;
    private int mRgbHeight;

    private static final int STATE_OFF = 0;
    private static final int STATE_PREVIEW = 1;
    private static final int STATE_NO_CALLBACKS = 2;
    private int mState = STATE_OFF;
    private boolean mProcessInProgress = false;
    private boolean mProcessingFirstFrame = false;

    private TreeSet<String> mTestedCombinations = new TreeSet<String>();
    private TreeSet<String> mUntestedCombinations = new TreeSet<String>();

    private int mAllCombinationsSize = 0;

    // Menu to show the test progress
    private static final int MENU_ID_PROGRESS = Menu.FIRST + 1;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.cf_main);

        mAllCombinationsSize = calcAllCombinationsSize();

        // disable "Pass" button until all combinations are tested
        setPassButtonEnabled(false);

        setPassFailButtonClickListeners();
        setInfoResources(R.string.camera_format, R.string.cf_info, -1);

        mPreviewView = (TextureView) findViewById(R.id.preview_view);
        mFormatView = (ImageView) findViewById(R.id.format_view);

        mPreviewView.setSurfaceTextureListener(this);

        int numCameras = Camera.getNumberOfCameras();
        String[] cameraNames = new String[numCameras];
        for (int i = 0; i < numCameras; i++) {
            cameraNames[i] = "Camera " + i;
            mUntestedCombinations.add("All combinations for Camera " + i + "\n");
        }
        mCameraSpinner = (Spinner) findViewById(R.id.cameras_selection);
        mCameraSpinner.setAdapter(
            new ArrayAdapter<String>(
                this, R.layout.cf_format_list_item, cameraNames));
        mCameraSpinner.setOnItemSelectedListener(mCameraSpinnerListener);

        mFormatSpinner = (Spinner) findViewById(R.id.format_selection);
        mFormatSpinner.setOnItemSelectedListener(mFormatSelectedListener);

        mResolutionSpinner = (Spinner) findViewById(R.id.resolution_selection);
        mResolutionSpinner.setOnItemSelectedListener(mResolutionSelectedListener);

        // Must be kept in sync with android.graphics.ImageFormat manually
        mPreviewFormatNames = new SparseArray(7);
        mPreviewFormatNames.append(ImageFormat.JPEG, "JPEG");
        mPreviewFormatNames.append(ImageFormat.NV16, "NV16");
        mPreviewFormatNames.append(ImageFormat.NV21, "NV21");
        mPreviewFormatNames.append(ImageFormat.RGB_565, "RGB_565");
        mPreviewFormatNames.append(ImageFormat.UNKNOWN, "UNKNOWN");
        mPreviewFormatNames.append(ImageFormat.YUY2, "YUY2");
        mPreviewFormatNames.append(ImageFormat.YV12, "YV12");

        // Need YUV->RGB conversion in many cases

        ColorMatrix y2r = new ColorMatrix();
        y2r.setYUV2RGB();
        float[] yuvOffset = new float[] {
            1.f, 0.f, 0.f, 0.f, 0.f,
            0.f, 1.f, 0.f, 0.f, -128.f,
            0.f, 0.f, 1.f, 0.f, -128.f,
            0.f, 0.f, 0.f, 1.f, 0.f
        };

        ColorMatrix yOffset = new ColorMatrix(yuvOffset);

        ColorMatrix yTotal = new ColorMatrix();
        yTotal.setConcat(y2r, yOffset);

        mYuv2RgbFilter = new ColorMatrixColorFilter(yTotal);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        menu.add(Menu.NONE, MENU_ID_PROGRESS, Menu.NONE, "Current Progress");
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        boolean ret = true;
        switch (item.getItemId()) {
        case MENU_ID_PROGRESS:
            showCombinationsDialog();
            ret = true;
            break;
        default:
            ret = super.onOptionsItemSelected(item);
            break;
        }
        return ret;
    }

    private void showCombinationsDialog() {
        AlertDialog.Builder builder =
                new AlertDialog.Builder(CameraFormatsActivity.this);
        builder.setMessage(getTestDetails())
                .setTitle("Current Progress")
                .setPositiveButton("OK", null);
        builder.show();
    }

    @Override
    public void onResume() {
        super.onResume();

        setUpCamera(mCameraSpinner.getSelectedItemPosition());
    }

    @Override
    public void onPause() {
        super.onPause();

        shutdownCamera();
        mPreviewTexture = null;
    }

    @Override
    public String getTestDetails() {
        StringBuilder reportBuilder = new StringBuilder();
        reportBuilder.append("Tested combinations:\n");
        for (String combination: mTestedCombinations) {
            reportBuilder.append(combination);
        }
        reportBuilder.append("Untested combinations:\n");
        for (String combination: mUntestedCombinations) {
            reportBuilder.append(combination);
        }
        return reportBuilder.toString();
    }


    public void onSurfaceTextureAvailable(SurfaceTexture surface,
            int width, int height) {
        mPreviewTexture = surface;
        if (mFormatView.getMeasuredWidth() != width
                || mFormatView.getMeasuredHeight() != height) {
            mPreviewTexWidth = mFormatView.getMeasuredWidth();
            mPreviewTexHeight = mFormatView.getMeasuredHeight();
         } else {
            mPreviewTexWidth = width;
            mPreviewTexHeight = height;
        }

        if (mCamera != null) {
            startPreview();
        }
    }

    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
        // Ignored, Camera does all the work for us
    }

    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
        return true;
    }

    public void onSurfaceTextureUpdated(SurfaceTexture surface) {
        // Invoked every time there's a new Camera preview frame
    }

    private AdapterView.OnItemSelectedListener mCameraSpinnerListener =
            new AdapterView.OnItemSelectedListener() {
                public void onItemSelected(AdapterView<?> parent,
                        View view, int pos, long id) {
                    if (mCurrentCameraId != pos) {
                        setUpCamera(pos);
                    }
                }

                public void onNothingSelected(AdapterView parent) {

                }

            };

    private AdapterView.OnItemSelectedListener mResolutionSelectedListener =
            new AdapterView.OnItemSelectedListener() {
                public void onItemSelected(AdapterView<?> parent,
                        View view, int position, long id) {
                    if (mPreviewSizes.get(position) != mPreviewSize) {
                        mNextPreviewSize = mPreviewSizes.get(position);
                        startPreview();
                    }
                }

                public void onNothingSelected(AdapterView parent) {

                }

            };


    private AdapterView.OnItemSelectedListener mFormatSelectedListener =
            new AdapterView.OnItemSelectedListener() {
                public void onItemSelected(AdapterView<?> parent,
                        View view, int position, long id) {
                    if (mPreviewFormats.get(position) != mNextPreviewFormat) {
                        mNextPreviewFormat = mPreviewFormats.get(position);
                        startPreview();
                    }
                }

                public void onNothingSelected(AdapterView parent) {

                }

            };



    private void setUpCamera(int id) {
        shutdownCamera();

        mCurrentCameraId = id;
        mCamera = Camera.open(id);
        Camera.Parameters p = mCamera.getParameters();

        // Get preview resolutions

        List<Camera.Size> unsortedSizes = p.getSupportedPreviewSizes();

        class SizeCompare implements Comparator<Camera.Size> {
            public int compare(Camera.Size lhs, Camera.Size rhs) {
                if (lhs.width < rhs.width) return -1;
                if (lhs.width > rhs.width) return 1;
                if (lhs.height < rhs.height) return -1;
                if (lhs.height > rhs.height) return 1;
                return 0;
            }
        };

        SizeCompare s = new SizeCompare();
        TreeSet<Camera.Size> sortedResolutions = new TreeSet<Camera.Size>(s);
        sortedResolutions.addAll(unsortedSizes);

        mPreviewSizes = new ArrayList<Camera.Size>(sortedResolutions);

        String[] availableSizeNames = new String[mPreviewSizes.size()];
        for (int i = 0; i < mPreviewSizes.size(); i++) {
            availableSizeNames[i] =
                    Integer.toString(mPreviewSizes.get(i).width) + " x " +
                    Integer.toString(mPreviewSizes.get(i).height);
        }
        mResolutionSpinner.setAdapter(
            new ArrayAdapter<String>(
                this, R.layout.cf_format_list_item, availableSizeNames));

        // Get preview formats, removing duplicates

        HashSet<Integer> formatSet = new HashSet<>(p.getSupportedPreviewFormats());
        mPreviewFormats = new ArrayList<Integer>(formatSet);

        String[] availableFormatNames = new String[mPreviewFormats.size()];
        for (int i = 0; i < mPreviewFormats.size(); i++) {
            availableFormatNames[i] =
                    mPreviewFormatNames.get(mPreviewFormats.get(i));
        }
        mFormatSpinner.setAdapter(
            new ArrayAdapter<String>(
                this, R.layout.cf_format_list_item, availableFormatNames));

        // Update untested entries

        mUntestedCombinations.remove("All combinations for Camera " + id + "\n");
        for (Camera.Size previewSize: mPreviewSizes) {
            for (int previewFormat: mPreviewFormats) {
                String combination = "Camera " + id + ", "
                        + previewSize.width + "x" + previewSize.height
                        + ", " + mPreviewFormatNames.get(previewFormat)
                        + "\n";
                if (!mTestedCombinations.contains(combination)) {
                    mUntestedCombinations.add(combination);
                }
            }
        }

        // Set initial values

        mNextPreviewSize = mPreviewSizes.get(0);
        mResolutionSpinner.setSelection(0);

        mNextPreviewFormat = mPreviewFormats.get(0);
        mFormatSpinner.setSelection(0);


        // Set up correct display orientation

        CameraInfo info =
            new CameraInfo();
        Camera.getCameraInfo(id, info);
        int rotation = getWindowManager().getDefaultDisplay().getRotation();
        int degrees = 0;
        switch (rotation) {
            case Surface.ROTATION_0: degrees = 0; break;
            case Surface.ROTATION_90: degrees = 90; break;
            case Surface.ROTATION_180: degrees = 180; break;
            case Surface.ROTATION_270: degrees = 270; break;
        }

        if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
            mPreviewRotation = (info.orientation + degrees) % 360;
            mPreviewRotation = (360 - mPreviewRotation) % 360;  // compensate the mirror
        } else {  // back-facing
            mPreviewRotation = (info.orientation - degrees + 360) % 360;
        }
        if (mPreviewRotation != 0 && mPreviewRotation != 180) {
            Log.w(TAG,
                "Display orientation correction is not 0 or 180, as expected!");
        }

        mCamera.setDisplayOrientation(mPreviewRotation);

        // Start up preview if display is ready

        if (mPreviewTexture != null) {
            startPreview();
        }

    }

    private void shutdownCamera() {
        if (mCamera != null) {
            mCamera.setPreviewCallback(null);
            mCamera.stopPreview();
            mCamera.release();
            mCamera = null;
            mState = STATE_OFF;
        }
    }

    private void startPreview() {
        if (mState != STATE_OFF) {
            // Stop for a while to drain callbacks
            mCamera.setPreviewCallback(null);
            mCamera.stopPreview();
            mState = STATE_OFF;
            Handler h = new Handler();
            Runnable mDelayedPreview = new Runnable() {
                public void run() {
                    startPreview();
                }
            };
            h.postDelayed(mDelayedPreview, 300);
            return;
        }
        mState = STATE_PREVIEW;

        Matrix transform = new Matrix();
        float widthRatio = mNextPreviewSize.width / (float)mPreviewTexWidth;
        float heightRatio = mNextPreviewSize.height / (float)mPreviewTexHeight;

        if (heightRatio < widthRatio) {
            transform.setScale(1, heightRatio/widthRatio);
            transform.postTranslate(0,
                mPreviewTexHeight * (1 - heightRatio/widthRatio)/2);
        } else {
            transform.setScale(widthRatio/heightRatio, 1);
            transform.postTranslate(mPreviewTexWidth * (1 - widthRatio/heightRatio)/2,
            0);
        }

        mPreviewView.setTransform(transform);

        mPreviewFormat = mNextPreviewFormat;
        mPreviewSize   = mNextPreviewSize;

        Camera.Parameters p = mCamera.getParameters();
        p.setPreviewFormat(mPreviewFormat);
        p.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
        mCamera.setParameters(p);

        mCamera.setPreviewCallback(this);
        switch (mPreviewFormat) {
            case ImageFormat.NV16:
            case ImageFormat.NV21:
            case ImageFormat.YUY2:
            case ImageFormat.YV12:
                mFormatView.setColorFilter(mYuv2RgbFilter);
                break;
            default:
                mFormatView.setColorFilter(null);
                break;
        }

        // Filter out currently untestable formats
        switch (mPreviewFormat) {
            case ImageFormat.NV16:
            case ImageFormat.RGB_565:
            case ImageFormat.UNKNOWN:
            case ImageFormat.JPEG:
                AlertDialog.Builder builder =
                        new AlertDialog.Builder(CameraFormatsActivity.this);
                builder.setMessage("Unsupported format " +
                        mPreviewFormatNames.get(mPreviewFormat) +
                        "; consider this combination as pass. ")
                        .setTitle("Missing test" )
                        .setNeutralButton("Back", null);
                builder.show();
                mState = STATE_NO_CALLBACKS;
                mCamera.setPreviewCallback(null);
                break;
            default:
                // supported
                break;
        }

        mProcessingFirstFrame = true;
        try {
            mCamera.setPreviewTexture(mPreviewTexture);
            mCamera.startPreview();
        } catch (IOException ioe) {
            // Something bad happened
            Log.e(TAG, "Unable to start up preview");
        }
    }

    private class ProcessPreviewDataTask extends AsyncTask<byte[], Void, Boolean> {
        protected Boolean doInBackground(byte[]... datas) {
            byte[] data = datas[0];
            try {
                if (mRgbData == null ||
                        mPreviewSize.width != mRgbWidth ||
                        mPreviewSize.height != mRgbHeight) {

                    mRgbData = new int[mPreviewSize.width * mPreviewSize.height * 4];
                    mRgbWidth = mPreviewSize.width;
                    mRgbHeight = mPreviewSize.height;
                }
                switch(mPreviewFormat) {
                    case ImageFormat.NV21:
                        convertFromNV21(data, mRgbData);
                        break;
                    case ImageFormat.YV12:
                        convertFromYV12(data, mRgbData);
                        break;
                    case ImageFormat.YUY2:
                        convertFromYUY2(data, mRgbData);
                        break;
                    case ImageFormat.NV16:
                    case ImageFormat.RGB_565:
                    case ImageFormat.UNKNOWN:
                    case ImageFormat.JPEG:
                    default:
                        convertFromUnknown(data, mRgbData);
                        break;
                }

                if (mCallbackBitmap == null ||
                        mRgbWidth != mCallbackBitmap.getWidth() ||
                        mRgbHeight != mCallbackBitmap.getHeight() ) {
                    mCallbackBitmap =
                            Bitmap.createBitmap(
                                mRgbWidth, mRgbHeight,
                                Bitmap.Config.ARGB_8888);
                }
                mCallbackBitmap.setPixels(mRgbData, 0, mRgbWidth,
                        0, 0, mRgbWidth, mRgbHeight);
            } catch (OutOfMemoryError o) {
                Log.e(TAG, "Out of memory trying to process preview data");
                return false;
            }
            return true;
        }

        protected void onPostExecute(Boolean result) {
            if (result) {
                mFormatView.setImageBitmap(mCallbackBitmap);
                if (mProcessingFirstFrame) {
                    mProcessingFirstFrame = false;
                    String combination = "Camera " + mCurrentCameraId + ", "
                            + mPreviewSize.width + "x" + mPreviewSize.height
                            + ", " + mPreviewFormatNames.get(mPreviewFormat)
                            + "\n";
                    mUntestedCombinations.remove(combination);
                    mTestedCombinations.add(combination);

                    displayToast(combination.replace("\n", ""));

                    if (mTestedCombinations.size() == mAllCombinationsSize) {
                        setPassButtonEnabled(true);
                    }
                }
            }
            mProcessInProgress = false;
        }

    }

    private void setPassButtonEnabled(boolean enabled) {
        ImageButton pass_button = (ImageButton) findViewById(R.id.pass_button);
        pass_button.setEnabled(enabled);
    }

    private int calcAllCombinationsSize() {
        int allCombinationsSize = 0;
        int numCameras = Camera.getNumberOfCameras();

        for (int i = 0; i<numCameras; i++) {
            // must release a Camera object before a new Camera object is created
            shutdownCamera();

            mCamera = Camera.open(i);
            Camera.Parameters p = mCamera.getParameters();

            HashSet<Integer> formatSet = new HashSet<>(p.getSupportedPreviewFormats());

            allCombinationsSize +=
                    p.getSupportedPreviewSizes().size() *   // resolutions
                    formatSet.size();  // unique formats
        }

        return allCombinationsSize;
    }

    private void displayToast(String combination) {
        Toast.makeText(this, "\"" + combination + "\"\n" + " has been tested.", Toast.LENGTH_LONG).show();
    }

    public void onPreviewFrame(byte[] data, Camera camera) {
        if (mProcessInProgress || mState != STATE_PREVIEW) return;

        int expectedBytes;
        switch (mPreviewFormat) {
            case ImageFormat.YV12:
                // YV12 may have stride != width.
                int w = mPreviewSize.width;
                int h = mPreviewSize.height;
                int yStride = (int)Math.ceil(w / 16.0) * 16;
                int uvStride = (int)Math.ceil(yStride / 2 / 16.0) * 16;
                int ySize = yStride * h;
                int uvSize = uvStride * h / 2;
                expectedBytes = ySize + uvSize * 2;
                break;
            case ImageFormat.NV21:
            case ImageFormat.YUY2:
            default:
                expectedBytes = mPreviewSize.width * mPreviewSize.height *
                        ImageFormat.getBitsPerPixel(mPreviewFormat) / 8;
                break;
        }
        if (expectedBytes != data.length) {
            AlertDialog.Builder builder =
                    new AlertDialog.Builder(CameraFormatsActivity.this);
            builder.setMessage("Mismatched size of buffer! Expected " +
                    expectedBytes + ", but got " +
                    data.length + " bytes instead!")
                    .setTitle("Error trying to use format "
                            + mPreviewFormatNames.get(mPreviewFormat))
                    .setNeutralButton("Back", null);

            builder.show();

            mState = STATE_NO_CALLBACKS;
            mCamera.setPreviewCallback(null);
            return;
        }

        mProcessInProgress = true;
        new ProcessPreviewDataTask().execute(data);
    }

    private void convertFromUnknown(byte[] data, int[] rgbData) {
        int w = mPreviewSize.width;
        int h = mPreviewSize.height;
        // RGBA output
        int rgbInc = 1;
        if (mPreviewRotation == 180) {
            rgbInc = -1;
        }
        int index = 0;
        for (int y = 0; y < h; y++) {
            int rgbIndex = y * w;
            if (mPreviewRotation == 180) {
                rgbIndex = w * (h - y) - 1;
            }
            for (int x = 0; x < mPreviewSize.width/3; x++) {
                int r = data[index + 0] & 0xFF;
                int g = data[index + 1] & 0xFF;
                int b = data[index + 2] & 0xFF;
                rgbData[rgbIndex] = Color.rgb(r,g,b);
                rgbIndex += rgbInc;
                index += 3;
            }
        }
    }

    // NV21 is a semi-planar 4:2:0 format, in the order YVU, which means we have:
    // a W x H-size 1-byte-per-pixel Y plane, then
    // a W/2 x H/2-size 2-byte-per-pixel plane, where each pixel has V then U.
    private void convertFromNV21(byte[] data, int rgbData[]) {
        int w = mPreviewSize.width;
        int h = mPreviewSize.height;
        // RGBA output
        int rgbIndex = 0;
        int rgbInc = 1;
        if (mPreviewRotation == 180) {
            rgbIndex = h * w - 1;
            rgbInc = -1;
        }
        int yIndex = 0;
        int uvRowIndex = w*h;
        int uvRowInc = 0;
        for (int y = 0; y < h; y++) {
            int uvInc = 0;
            int vIndex = uvRowIndex;
            int uIndex = uvRowIndex + 1;

            uvRowIndex += uvRowInc * w;
            uvRowInc = (uvRowInc + 1) & 0x1;

            for (int x = 0; x < w; x++) {
                int yv = data[yIndex] & 0xFF;
                int uv = data[uIndex] & 0xFF;
                int vv = data[vIndex] & 0xFF;
                rgbData[rgbIndex] =
                        Color.rgb(yv, uv, vv);

                rgbIndex += rgbInc;
                yIndex += 1;
                uIndex += uvInc;
                vIndex += uvInc;
                uvInc = (uvInc + 2) & 0x2;
            }
        }
    }

    // YV12 is a planar 4:2:0 format, in the order YVU, which means we have:
    // a W x H-size 1-byte-per-pixel Y plane, then
    // a W/2 x H/2-size 1-byte-per-pixel V plane, then
    // a W/2 x H/2-size 1-byte-per-pixel U plane
    // The stride may not be equal to width, since it has to be a multiple of
    // 16 pixels for both the Y and UV planes.
    private void convertFromYV12(byte[] data, int rgbData[]) {
        int w = mPreviewSize.width;
        int h = mPreviewSize.height;
        // RGBA output
        int rgbIndex = 0;
        int rgbInc = 1;
        if (mPreviewRotation == 180) {
            rgbIndex = h * w - 1;
            rgbInc = -1;
        }

        int yStride = (int)Math.ceil(w / 16.0) * 16;
        int uvStride = (int)Math.ceil(yStride/2/16.0) * 16;
        int ySize = yStride * h;
        int uvSize = uvStride * h / 2;

        int uRowIndex = ySize + uvSize;
        int vRowIndex = ySize;

        int uv_w = w/2;
        for (int y = 0; y < h; y++) {
            int yIndex = yStride * y;
            int uIndex = uRowIndex;
            int vIndex = vRowIndex;

            if ( (y & 0x1) == 1) {
                uRowIndex += uvStride;
                vRowIndex += uvStride;
            }

            int uv = 0, vv = 0;
            for (int x = 0; x < w; x++) {
                if ( (x & 0x1)  == 0) {
                    uv = data[uIndex] & 0xFF;
                    vv = data[vIndex] & 0xFF;
                    uIndex++;
                    vIndex++;
                }
                int yv = data[yIndex] & 0xFF;
                rgbData[rgbIndex] =
                        Color.rgb(yv, uv, vv);

                rgbIndex += rgbInc;
                yIndex += 1;
            }
        }
    }

    // YUY2 is an interleaved 4:2:2 format: YU,YV,YU,YV
    private void convertFromYUY2(byte[] data, int[] rgbData) {
        int w = mPreviewSize.width;
        int h = mPreviewSize.height;
        // RGBA output
        int yIndex = 0;
        int uIndex = 1;
        int vIndex = 3;
        int rgbIndex = 0;
        int rgbInc = 1;
        if (mPreviewRotation == 180) {
            rgbIndex = h * w - 1;
            rgbInc = -1;
        }

        for (int y = 0; y < h; y++) {
            for (int x = 0; x < w; x++) {
                int yv = data[yIndex] & 0xFF;
                int uv = data[uIndex] & 0xFF;
                int vv = data[vIndex] & 0xFF;
                rgbData[rgbIndex] = Color.rgb(yv,uv,vv);
                rgbIndex += rgbInc;
                yIndex += 2;
                if ( (x & 0x1) == 1 ) {
                    uIndex += 4;
                    vIndex += 4;
                }
            }
        }
    }

}
