19bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava/*
2737bd08db020802f1c60941be09e13c3c587f2aaBasavapatna Dattaguru * Copyright (C) 2011 The Android Open Source Project
39bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava *
49bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava * Licensed under the Apache License, Version 2.0 (the "License");
59bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava * you may not use this file except in compliance with the License.
69bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava * You may obtain a copy of the License at
79bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava *
89bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava *      http://www.apache.org/licenses/LICENSE-2.0
99bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava *
109bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava * Unless required by applicable law or agreed to in writing, software
119bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava * distributed under the License is distributed on an "AS IS" BASIS,
129bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava * See the License for the specific language governing permissions and
149bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava * limitations under the License.
159bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava */
169bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
179bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
189bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhavapackage android.media.videoeditor;
199bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
209bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhavaimport android.graphics.Bitmap;
219bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhavaimport android.graphics.BitmapFactory;
229bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhavaimport android.graphics.Canvas;
239bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhavaimport android.graphics.Paint;
249bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhavaimport android.graphics.Rect;
259bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhavaimport java.util.ArrayList;
269bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhavaimport android.media.videoeditor.MediaArtistNativeHelper.ClipSettings;
279bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhavaimport android.media.videoeditor.MediaArtistNativeHelper.EditSettings;
289bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhavaimport android.media.videoeditor.MediaArtistNativeHelper.FileType;
299bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhavaimport android.media.videoeditor.MediaArtistNativeHelper.Properties;
309bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhavaimport android.util.Log;
319bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhavaimport android.util.Pair;
329bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
339bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhavaimport java.io.DataOutputStream;
349bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhavaimport java.io.File;
359bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhavaimport java.io.FileOutputStream;
369bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhavaimport java.io.IOException;
379bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhavaimport java.nio.ByteBuffer;
389bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhavaimport java.nio.IntBuffer;
399bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhavaimport java.lang.Math;
409bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhavaimport java.util.List;
419bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
429bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava/**
439bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava * This class represents an image item on the storyboard. Note that images are
449bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava * scaled down to the maximum supported resolution by preserving the native
459bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava * aspect ratio. To learn the scaled image dimensions use
469bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava * {@link #getScaledWidth()} and {@link #getScaledHeight()} respectively.
479bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava *
489bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava * {@hide}
499bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava */
509bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhavapublic class MediaImageItem extends MediaItem {
519bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    /**
529bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     *  Logging
539bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     */
549bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    private static final String TAG = "MediaImageItem";
559bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
569bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    /**
579bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     *  The resize paint
589bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     */
599bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    private static final Paint sResizePaint = new Paint(Paint.FILTER_BITMAP_FLAG);
609bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
619bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    /**
629bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     *  Instance variables
639bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     */
649bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    private final int mWidth;
659bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    private final int mHeight;
669bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    private final int mAspectRatio;
679bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    private long mDurationMs;
689bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    private int mScaledWidth, mScaledHeight;
699bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    private String mScaledFilename;
709bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    private final VideoEditorImpl mVideoEditor;
719bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    private String mDecodedFilename;
729bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    private int mGeneratedClipHeight;
739bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    private int mGeneratedClipWidth;
74737bd08db020802f1c60941be09e13c3c587f2aaBasavapatna Dattaguru    private String mFileName;
759bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
769bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    private final MediaArtistNativeHelper mMANativeHelper;
779bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
789bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    /**
799bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * This class cannot be instantiated by using the default constructor
809bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     */
819bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    @SuppressWarnings("unused")
829bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    private MediaImageItem() throws IOException {
839bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        this(null, null, null, 0, RENDERING_MODE_BLACK_BORDER);
849bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    }
859bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
869bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    /**
879bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * Constructor
889bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     *
899bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * @param editor The video editor reference
909bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * @param mediaItemId The media item id
919bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * @param filename The image file name
929bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * @param durationMs The duration of the image on the storyboard
939bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * @param renderingMode The rendering mode
949bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     *
959bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * @throws IOException
969bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     */
97c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi    public MediaImageItem(VideoEditor editor, String mediaItemId, String filename, long durationMs,
98c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi        int renderingMode) throws IOException {
999bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
1009bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        super(editor, mediaItemId, filename, renderingMode);
1019bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
1029bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        mMANativeHelper = ((VideoEditorImpl)editor).getNativeContext();
1039bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        mVideoEditor = ((VideoEditorImpl)editor);
1049bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        try {
105c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi            final Properties properties = mMANativeHelper.getMediaProperties(filename);
1069bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
1079bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            switch (mMANativeHelper.getFileType(properties.fileType)) {
1089bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                case MediaProperties.FILE_JPEG:
109c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi                case MediaProperties.FILE_PNG: {
1109bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                    break;
111c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi                }
1129bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
113c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi                default: {
114c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi                    throw new IllegalArgumentException("Unsupported Input File Type");
115c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi                }
1169bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            }
1179bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        } catch (Exception e) {
118c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi            throw new IllegalArgumentException("Unsupported file or file not found: " + filename);
1199bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        }
120737bd08db020802f1c60941be09e13c3c587f2aaBasavapatna Dattaguru        mFileName = filename;
1219bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        /**
1229bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava         *  Determine the dimensions of the image
1239bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava         */
1249bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        final BitmapFactory.Options dbo = new BitmapFactory.Options();
1259bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        dbo.inJustDecodeBounds = true;
1269bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        BitmapFactory.decodeFile(filename, dbo);
1279bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
1289bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        mWidth = dbo.outWidth;
1299bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        mHeight = dbo.outHeight;
1309bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        mDurationMs = durationMs;
1319bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        mDecodedFilename = String.format(mMANativeHelper.getProjectPath() +
1329bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                "/" + "decoded" + getId()+ ".rgb");
133c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi
1349bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        try {
1359bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            mAspectRatio = mMANativeHelper.getAspectRatio(mWidth, mHeight);
1369bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        } catch(IllegalArgumentException e) {
1379bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            throw new IllegalArgumentException ("Null width and height");
1389bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        }
139c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi
1409bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        mGeneratedClipHeight = 0;
1419bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        mGeneratedClipWidth = 0;
1429bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
1439bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        /**
1449bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava         *  Images are stored in memory scaled to the maximum resolution to
1459bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava         *  save memory.
1469bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava         */
1479bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        final Pair<Integer, Integer>[] resolutions =
1489bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            MediaProperties.getSupportedResolutions(mAspectRatio);
149c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi
1509bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        /**
1519bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava         *  Get the highest resolution
1529bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava         */
1539bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        final Pair<Integer, Integer> maxResolution = resolutions[resolutions.length - 1];
154737bd08db020802f1c60941be09e13c3c587f2aaBasavapatna Dattaguru
155737bd08db020802f1c60941be09e13c3c587f2aaBasavapatna Dattaguru        final Bitmap imageBitmap;
156737bd08db020802f1c60941be09e13c3c587f2aaBasavapatna Dattaguru
157b1224ff1c4ef8324c9d76b857463787aabd84707Chih-Chung Chang        if (mWidth > maxResolution.first || mHeight > maxResolution.second) {
1589bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            /**
1599bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava             *  We need to scale the image
1609bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava             */
161737bd08db020802f1c60941be09e13c3c587f2aaBasavapatna Dattaguru            imageBitmap = scaleImage(filename, maxResolution.first,
162737bd08db020802f1c60941be09e13c3c587f2aaBasavapatna Dattaguru                                                         maxResolution.second);
1639bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            mScaledFilename = String.format(mMANativeHelper.getProjectPath() +
1649bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                    "/" + "scaled" + getId()+ ".JPG");
1659bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            if (!((new File(mScaledFilename)).exists())) {
1669bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                super.mRegenerateClip = true;
1679bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                final FileOutputStream f1 = new FileOutputStream(mScaledFilename);
168737bd08db020802f1c60941be09e13c3c587f2aaBasavapatna Dattaguru                imageBitmap.compress(Bitmap.CompressFormat.JPEG, 50,f1);
1699bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                f1.close();
1709bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            }
171737bd08db020802f1c60941be09e13c3c587f2aaBasavapatna Dattaguru            mScaledWidth =  (imageBitmap.getWidth() >> 1) << 1;
172737bd08db020802f1c60941be09e13c3c587f2aaBasavapatna Dattaguru            mScaledHeight = (imageBitmap.getHeight() >> 1) << 1;
173737bd08db020802f1c60941be09e13c3c587f2aaBasavapatna Dattaguru        } else {
174737bd08db020802f1c60941be09e13c3c587f2aaBasavapatna Dattaguru            mScaledFilename = filename;
175737bd08db020802f1c60941be09e13c3c587f2aaBasavapatna Dattaguru            mScaledWidth =  (mWidth >> 1) << 1;
176737bd08db020802f1c60941be09e13c3c587f2aaBasavapatna Dattaguru            mScaledHeight = (mHeight >> 1) << 1;
177737bd08db020802f1c60941be09e13c3c587f2aaBasavapatna Dattaguru            imageBitmap = BitmapFactory.decodeFile(mScaledFilename);
178737bd08db020802f1c60941be09e13c3c587f2aaBasavapatna Dattaguru        }
179737bd08db020802f1c60941be09e13c3c587f2aaBasavapatna Dattaguru        int newWidth = mScaledWidth;
180737bd08db020802f1c60941be09e13c3c587f2aaBasavapatna Dattaguru        int newHeight = mScaledHeight;
181737bd08db020802f1c60941be09e13c3c587f2aaBasavapatna Dattaguru        if (!((new File(mDecodedFilename)).exists())) {
182737bd08db020802f1c60941be09e13c3c587f2aaBasavapatna Dattaguru            final FileOutputStream fl = new FileOutputStream(mDecodedFilename);
183737bd08db020802f1c60941be09e13c3c587f2aaBasavapatna Dattaguru            final DataOutputStream dos = new DataOutputStream(fl);
184737bd08db020802f1c60941be09e13c3c587f2aaBasavapatna Dattaguru            final int [] framingBuffer = new int[newWidth];
1859bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            final ByteBuffer byteBuffer = ByteBuffer.allocate(framingBuffer.length * 4);
1869bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            IntBuffer intBuffer;
1879bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            final byte[] array = byteBuffer.array();
1889bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            int tmp = 0;
189737bd08db020802f1c60941be09e13c3c587f2aaBasavapatna Dattaguru            while (tmp < newHeight) {
190737bd08db020802f1c60941be09e13c3c587f2aaBasavapatna Dattaguru                imageBitmap.getPixels(framingBuffer, 0, mScaledWidth, 0,
191737bd08db020802f1c60941be09e13c3c587f2aaBasavapatna Dattaguru                                                        tmp, newWidth, 1);
1929bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                intBuffer = byteBuffer.asIntBuffer();
193737bd08db020802f1c60941be09e13c3c587f2aaBasavapatna Dattaguru                intBuffer.put(framingBuffer, 0, newWidth);
1949bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                dos.write(array);
1959bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                tmp += 1;
1969bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            }
197737bd08db020802f1c60941be09e13c3c587f2aaBasavapatna Dattaguru            fl.close();
1989bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        }
199737bd08db020802f1c60941be09e13c3c587f2aaBasavapatna Dattaguru        imageBitmap.recycle();
2009bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    }
2019bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
2029bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    /*
2039bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * {@inheritDoc}
2049bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     */
2059bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    @Override
2069bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    public int getFileType() {
2079bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        if (mFilename.endsWith(".jpg") || mFilename.endsWith(".jpeg")
2089bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                || mFilename.endsWith(".JPG") || mFilename.endsWith(".JPEG")) {
2099bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            return MediaProperties.FILE_JPEG;
2109bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        } else if (mFilename.endsWith(".png") || mFilename.endsWith(".PNG")) {
2119bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            return MediaProperties.FILE_PNG;
2129bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        } else {
2139bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            return MediaProperties.FILE_UNSUPPORTED;
2149bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        }
2159bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    }
2169bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
2179bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    /**
2189bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * @return The scaled image file name
2199bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     */
2209bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    String getScaledImageFileName() {
2219bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        return mScaledFilename;
2229bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    }
2239bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
2249bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    /**
2259bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * @return The generated Kenburns clip height.
2269bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     */
2279bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    int getGeneratedClipHeight() {
2289bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        return mGeneratedClipHeight;
2299bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    }
2309bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
2319bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    /**
2329bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * @return The generated Kenburns clip width.
2339bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     */
2349bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    int getGeneratedClipWidth() {
2359bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        return mGeneratedClipWidth;
2369bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    }
2379bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
2389bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    /**
2399bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * @return The file name of image which is decoded and stored
240c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi     * in RGB format
2419bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     */
2429bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    String getDecodedImageFileName() {
2439bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        return mDecodedFilename;
2449bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    }
2459bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
2469bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    /*
2479bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * {@inheritDoc}
2489bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     */
2499bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    @Override
2509bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    public int getWidth() {
2519bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        return mWidth;
2529bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    }
2539bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
2549bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    /*
2559bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * {@inheritDoc}
2569bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     */
2579bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    @Override
2589bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    public int getHeight() {
2599bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        return mHeight;
2609bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    }
2619bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
2629bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    /**
2639bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * @return The scaled width of the image.
2649bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     */
2659bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    public int getScaledWidth() {
2669bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        return mScaledWidth;
2679bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    }
2689bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
2699bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    /**
2709bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * @return The scaled height of the image.
2719bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     */
2729bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    public int getScaledHeight() {
2739bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        return mScaledHeight;
2749bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    }
2759bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
2769bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    /*
2779bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * {@inheritDoc}
2789bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     */
2799bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    @Override
2809bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    public int getAspectRatio() {
2819bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        return mAspectRatio;
2829bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    }
2839bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
2849bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    /**
2859bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * This method will adjust the duration of bounding transitions, effects
2869bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * and overlays if the current duration of the transactions become greater
2879bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * than the maximum allowable duration.
2889bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     *
2899bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * @param durationMs The duration of the image in the storyboard timeline
2909bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     */
2919bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    public void setDuration(long durationMs) {
2929bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        if (durationMs == mDurationMs) {
2939bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            return;
2949bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        }
2959bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
2962bb13573d619e3371d06847d36db78a20b17dfabGil Dobjanschi        mMANativeHelper.setGeneratePreview(true);
2972bb13573d619e3371d06847d36db78a20b17dfabGil Dobjanschi
2989bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        /**
2999bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava         * Invalidate the end transitions if necessary.
3009bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava         * This invalidation is necessary for the case in which an effect or
3019bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava         * an overlay is overlapping with the end transition
3029bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava         * (before the duration is changed) and it no longer overlaps with the
3039bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava         * transition after the duration is increased.
3049bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava         *
3059bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava         * The beginning transition does not need to be invalidated at this time
3069bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava         * because an effect or an overlay overlaps with the beginning
3079bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava         * transition, the begin transition is unaffected by a media item
3089bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava         * duration change.
3099bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava         */
3109bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        invalidateEndTransition();
3119bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
3129bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        mDurationMs = durationMs;
3139bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
3149bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        adjustTransitions();
3159bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        final List<Overlay> adjustedOverlays = adjustOverlays();
3169bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        final List<Effect> adjustedEffects = adjustEffects();
3179bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
3189bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        /**
3199bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava         * Invalidate the beginning and end transitions after adjustments.
3209bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava         * This invalidation is necessary for the case in which an effect or
3219bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava         * an overlay was not overlapping with the beginning or end transitions
3229bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava         * before the setDuration reduces the duration of the media item and
3239bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava         * causes an overlap of the beginning and/or end transition with the
3249bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava         * effect.
3259bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava         */
3269bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        invalidateBeginTransition(adjustedEffects, adjustedOverlays);
3279bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        invalidateEndTransition();
3289bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        if (getGeneratedImageClip() != null) {
3299bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            /*
3309bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava             *  Delete the file
3319bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava             */
3329bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            new File(getGeneratedImageClip()).delete();
3339bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            /*
3349bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava             *  Invalidate the filename
3359bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava             */
3369bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            setGeneratedImageClip(null);
3379bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            super.setRegenerateClip(true);
3389bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        }
3399bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        mVideoEditor.updateTimelineDuration();
3409bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    }
3419bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
3429bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    /**
3439bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * Invalidate the begin transition if any effects and overlays overlap
3449bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * with the begin transition.
3459bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     *
3469bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * @param effects List of effects to check for transition overlap
3479bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * @param overlays List of overlays to check for transition overlap
3489bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     */
3499bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    private void invalidateBeginTransition(List<Effect> effects, List<Overlay> overlays) {
3509bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        if (mBeginTransition != null && mBeginTransition.isGenerated()) {
3519bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            final long transitionDurationMs = mBeginTransition.getDuration();
3529bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
3539bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            /**
3549bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava             *  The begin transition must be invalidated if it overlaps with
3559bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava             *  an effect.
3569bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava             */
3579bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            for (Effect effect : effects) {
3589bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                /**
3599bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                 *  Check if the effect overlaps with the begin transition
3609bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                 */
3619bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                if (effect.getStartTime() < transitionDurationMs) {
3629bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                    mBeginTransition.invalidate();
3639bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                    break;
3649bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                }
3659bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            }
3669bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
3679bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            if (mBeginTransition.isGenerated()) {
3689bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                /**
3699bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                 *  The end transition must be invalidated if it overlaps with
3709bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                 *  an overlay.
3719bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                 */
3729bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                for (Overlay overlay : overlays) {
3739bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                    /**
3749bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                     *  Check if the overlay overlaps with the end transition
3759bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                     */
3769bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                    if (overlay.getStartTime() < transitionDurationMs) {
3779bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                        mBeginTransition.invalidate();
3789bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                        break;
3799bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                    }
3809bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                }
3819bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            }
3829bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        }
3839bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    }
3849bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
3859bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    /**
3869bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * Invalidate the end transition if any effects and overlays overlap
3879bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * with the end transition.
3889bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     */
3899bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    private void invalidateEndTransition() {
3909bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        if (mEndTransition != null && mEndTransition.isGenerated()) {
3919bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            final long transitionDurationMs = mEndTransition.getDuration();
3929bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
3939bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            /**
3949bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava             *  The end transition must be invalidated if it overlaps with
3959bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava             *  an effect.
3969bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava             */
3979bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            final List<Effect> effects = getAllEffects();
3989bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            for (Effect effect : effects) {
3999bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                /**
4009bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                 *  Check if the effect overlaps with the end transition
4019bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                 */
4029bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                if (effect.getStartTime() + effect.getDuration() >
403c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi                    mDurationMs - transitionDurationMs) {
4049bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                    mEndTransition.invalidate();
4059bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                    break;
4069bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                }
4079bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            }
4089bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
4099bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            if (mEndTransition.isGenerated()) {
4109bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                /**
4119bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                 *  The end transition must be invalidated if it overlaps with
4129bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                 *  an overlay.
4139bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                 */
4149bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                final List<Overlay> overlays = getAllOverlays();
4159bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                for (Overlay overlay : overlays) {
4169bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                    /**
4179bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                     *  Check if the overlay overlaps with the end transition
4189bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                     */
4199bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                    if (overlay.getStartTime() + overlay.getDuration() >
420c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi                        mDurationMs - transitionDurationMs) {
4219bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                        mEndTransition.invalidate();
4229bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                        break;
4239bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                    }
4249bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                }
4259bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            }
4269bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        }
4279bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    }
4289bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
4299bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    /**
4309bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * Adjust the start time and/or duration of effects.
4319bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     *
4329bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * @return The list of effects which were adjusted
4339bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     */
4349bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    private List<Effect> adjustEffects() {
4359bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        final List<Effect> adjustedEffects = new ArrayList<Effect>();
4369bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        final List<Effect> effects = getAllEffects();
4379bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        for (Effect effect : effects) {
4389bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            /**
4399bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava             *  Adjust the start time if necessary
4409bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava             */
4419bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            final long effectStartTimeMs;
4429bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            if (effect.getStartTime() > getDuration()) {
4439bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                effectStartTimeMs = 0;
4449bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            } else {
4459bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                effectStartTimeMs = effect.getStartTime();
4469bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            }
4479bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
4489bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            /**
4499bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava             *  Adjust the duration if necessary
4509bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava             */
4519bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            final long effectDurationMs;
4529bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            if (effectStartTimeMs + effect.getDuration() > getDuration()) {
4539bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                effectDurationMs = getDuration() - effectStartTimeMs;
4549bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            } else {
4559bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                effectDurationMs = effect.getDuration();
4569bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            }
4579bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
4589bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            if (effectStartTimeMs != effect.getStartTime() ||
4599bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                    effectDurationMs != effect.getDuration()) {
4609bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                effect.setStartTimeAndDuration(effectStartTimeMs, effectDurationMs);
4619bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                adjustedEffects.add(effect);
4629bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            }
4639bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        }
4649bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
4659bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        return adjustedEffects;
4669bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    }
4679bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
4689bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    /**
4699bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * Adjust the start time and/or duration of overlays.
4709bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     *
4719bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * @return The list of overlays which were adjusted
4729bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     */
4739bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    private List<Overlay> adjustOverlays() {
4749bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        final List<Overlay> adjustedOverlays = new ArrayList<Overlay>();
4759bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        final List<Overlay> overlays = getAllOverlays();
4769bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        for (Overlay overlay : overlays) {
4779bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            /**
4789bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava             *  Adjust the start time if necessary
4799bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava             */
4809bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            final long overlayStartTimeMs;
4819bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            if (overlay.getStartTime() > getDuration()) {
4829bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                overlayStartTimeMs = 0;
4839bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            } else {
4849bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                overlayStartTimeMs = overlay.getStartTime();
4859bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            }
4869bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
4879bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            /**
4889bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava             *  Adjust the duration if necessary
4899bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava             */
4909bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            final long overlayDurationMs;
4919bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            if (overlayStartTimeMs + overlay.getDuration() > getDuration()) {
4929bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                overlayDurationMs = getDuration() - overlayStartTimeMs;
4939bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            } else {
4949bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                overlayDurationMs = overlay.getDuration();
4959bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            }
4969bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
4979bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            if (overlayStartTimeMs != overlay.getStartTime() ||
4989bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                    overlayDurationMs != overlay.getDuration()) {
4999bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                overlay.setStartTimeAndDuration(overlayStartTimeMs, overlayDurationMs);
5009bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                adjustedOverlays.add(overlay);
5019bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            }
5029bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        }
5039bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
5049bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        return adjustedOverlays;
5059bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    }
5069bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    /**
507600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng     * This function get the proper width by given aspect ratio
508600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng     * and height.
5099bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     *
510600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng     * @param aspectRatio  Given aspect ratio
511600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng     * @param height  Given height
5129bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     */
513600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng    private int getWidthByAspectRatioAndHeight(int aspectRatio, int height) {
514600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng        int width = 0;
5159bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
516600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng        switch (aspectRatio) {
5179bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            case MediaProperties.ASPECT_RATIO_3_2:
518600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng                if (height == MediaProperties.HEIGHT_480)
519600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng                    width = 720;
520600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng                else if (height == MediaProperties.HEIGHT_720)
521600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng                    width = 1080;
5229bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                break;
523600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng
5249bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            case MediaProperties.ASPECT_RATIO_16_9:
525600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng                if (height == MediaProperties.HEIGHT_360)
526600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng                    width = 640;
527600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng                else if (height == MediaProperties.HEIGHT_480)
528600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng                    width = 854;
529600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng                else if (height == MediaProperties.HEIGHT_720)
530600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng                    width = 1280;
531600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng                else if (height == MediaProperties.HEIGHT_1080)
532600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng                    width = 1920;
5339bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                break;
534600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng
5359bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            case MediaProperties.ASPECT_RATIO_4_3:
536600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng                if (height == MediaProperties.HEIGHT_480)
537600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng                    width = 640;
538600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng                if (height == MediaProperties.HEIGHT_720)
539600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng                    width = 960;
5409bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                break;
541600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng
5429bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            case MediaProperties.ASPECT_RATIO_5_3:
543600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng                if (height == MediaProperties.HEIGHT_480)
544600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng                    width = 800;
5459bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                break;
546600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng
5479bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            case MediaProperties.ASPECT_RATIO_11_9:
548600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng                if (height == MediaProperties.HEIGHT_144)
549600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng                    width = 176;
5509bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                break;
551600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng
552600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng            default : {
553600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng                throw new IllegalArgumentException(
554600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng                    "Illegal arguments for aspectRatio");
555600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng            }
5569bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        }
557600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng
558600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng        return width;
559600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng    }
560600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng
561600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng    /**
562600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng     * This function sets the Ken Burn effect generated clip
563600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng     * name.
564600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng     *
565600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng     * @param generatedFilePath The name of the generated clip
566600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng     */
567600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng    @Override
568600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng    void setGeneratedImageClip(String generatedFilePath) {
569600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng        super.setGeneratedImageClip(generatedFilePath);
570600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng
571600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng        // set the Kenburns clip width and height
572600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng        mGeneratedClipHeight = getScaledHeight();
573600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng        mGeneratedClipWidth = getWidthByAspectRatioAndHeight(
574600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng                mVideoEditor.getAspectRatio(), mGeneratedClipHeight);
5759bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    }
5769bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
5779bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    /**
5789bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * @return The name of the image clip
5799bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * generated with ken burns effect.
5809bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     */
5819bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    @Override
5829bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    String getGeneratedImageClip() {
5839bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        return super.getGeneratedImageClip();
5849bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    }
5859bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
5869bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    /*
5879bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * {@inheritDoc}
5889bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     */
5899bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    @Override
5909bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    public long getDuration() {
5919bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        return mDurationMs;
5929bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    }
5939bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
5949bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    /*
5959bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * {@inheritDoc}
5969bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     */
5979bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    @Override
5989bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    public long getTimelineDuration() {
5999bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        return mDurationMs;
6009bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    }
6019bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
6029bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    /*
6039bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * {@inheritDoc}
6049bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     */
6059bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    @Override
6069bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    public Bitmap getThumbnail(int width, int height, long timeMs) throws IOException {
6079bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        if (getGeneratedImageClip() != null) {
6089bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            return mMANativeHelper.getPixels(getGeneratedImageClip(),
60947a52158d2df0eb818bf7d589d8ff9fd5c0daaa3Chih-Chung Chang                width, height, timeMs, 0);
6109bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        } else {
6119bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            return scaleImage(mFilename, width, height);
6129bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        }
6139bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    }
6149bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
6159bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    /*
6169bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * {@inheritDoc}
6179bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     */
6189bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    @Override
6191f5de3833daddfa1d0ebc7dee1f9e007d4ed36a0Chih-Chung Chang    public void getThumbnailList(int width, int height,
6201f5de3833daddfa1d0ebc7dee1f9e007d4ed36a0Chih-Chung Chang                                 long startMs, long endMs,
6211f5de3833daddfa1d0ebc7dee1f9e007d4ed36a0Chih-Chung Chang                                 int thumbnailCount,
6221f5de3833daddfa1d0ebc7dee1f9e007d4ed36a0Chih-Chung Chang                                 int[] indices,
6231f5de3833daddfa1d0ebc7dee1f9e007d4ed36a0Chih-Chung Chang                                 GetThumbnailListCallback callback)
6241f5de3833daddfa1d0ebc7dee1f9e007d4ed36a0Chih-Chung Chang                                 throws IOException {
6259bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        //KenBurns was not applied on this.
6269bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        if (getGeneratedImageClip() == null) {
6279bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            final Bitmap thumbnail = scaleImage(mFilename, width, height);
6281f5de3833daddfa1d0ebc7dee1f9e007d4ed36a0Chih-Chung Chang            for (int i = 0; i < indices.length; i++) {
629f1824a9762a28c1b664360cb1b6c354d937878bcChih-Chung Chang                callback.onThumbnail(thumbnail, indices[i]);
6309bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            }
631c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi        } else {
6329bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            if (startMs > endMs) {
6339bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                throw new IllegalArgumentException("Start time is greater than end time");
6349bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            }
635c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi
6369bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            if (endMs > mDurationMs) {
6379bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                throw new IllegalArgumentException("End time is greater than file duration");
6389bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            }
639c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi
6401f5de3833daddfa1d0ebc7dee1f9e007d4ed36a0Chih-Chung Chang            mMANativeHelper.getPixelsList(getGeneratedImageClip(), width,
641c847b1a89df94dbff4c2f557f8c042ead5398c3fRajneesh Chowdury                height, startMs, endMs, thumbnailCount, indices, callback, 0);
6429bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        }
6439bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    }
6449bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
6459bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    /*
6469bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * {@inheritDoc}
6479bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     */
6489bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    @Override
6499bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    void invalidateTransitions(long startTimeMs, long durationMs) {
6509bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        /**
6519bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava         *  Check if the item overlaps with the beginning and end transitions
6529bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava         */
6539bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        if (mBeginTransition != null) {
6549bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            if (isOverlapping(startTimeMs, durationMs, 0, mBeginTransition.getDuration())) {
6559bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                mBeginTransition.invalidate();
6569bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            }
6579bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        }
6589bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
6599bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        if (mEndTransition != null) {
6609bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            final long transitionDurationMs = mEndTransition.getDuration();
6619bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            if (isOverlapping(startTimeMs, durationMs,
6629bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                    getDuration() - transitionDurationMs, transitionDurationMs)) {
6639bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                mEndTransition.invalidate();
6649bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            }
6659bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        }
6669bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    }
6679bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
6689bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    /*
6699bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * {@inheritDoc}
6709bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     */
6719bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    @Override
6729bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    void invalidateTransitions(long oldStartTimeMs, long oldDurationMs, long newStartTimeMs,
6739bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            long newDurationMs) {
6749bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        /**
6759bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava         *  Check if the item overlaps with the beginning and end transitions
6769bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava         */
6779bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        if (mBeginTransition != null) {
6789bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            final long transitionDurationMs = mBeginTransition.getDuration();
679c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi            final boolean oldOverlap = isOverlapping(oldStartTimeMs, oldDurationMs, 0,
680c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi                    transitionDurationMs);
681c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi            final boolean newOverlap = isOverlapping(newStartTimeMs, newDurationMs, 0,
682c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi                    transitionDurationMs);
6839bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            /**
684c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi             * Invalidate transition if:
685c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi             *
686c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi             * 1. New item overlaps the transition, the old one did not
687c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi             * 2. New item does not overlap the transition, the old one did
688c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi             * 3. New and old item overlap the transition if begin or end
689c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi             * time changed
6909bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava             */
691c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi            if (newOverlap != oldOverlap) { // Overlap has changed
6929bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                mBeginTransition.invalidate();
693c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi            } else if (newOverlap) { // Both old and new overlap
694c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi                if ((oldStartTimeMs != newStartTimeMs) ||
695c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi                        !(oldStartTimeMs + oldDurationMs > transitionDurationMs &&
696c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi                        newStartTimeMs + newDurationMs > transitionDurationMs)) {
697c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi                    mBeginTransition.invalidate();
698c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi                }
6999bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            }
7009bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        }
7019bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
7029bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        if (mEndTransition != null) {
7039bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            final long transitionDurationMs = mEndTransition.getDuration();
704c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi            final boolean oldOverlap = isOverlapping(oldStartTimeMs, oldDurationMs,
705c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi                    mDurationMs - transitionDurationMs, transitionDurationMs);
706c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi            final boolean newOverlap = isOverlapping(newStartTimeMs, newDurationMs,
707c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi                    mDurationMs - transitionDurationMs, transitionDurationMs);
7089bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            /**
709c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi             * Invalidate transition if:
710c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi             *
711c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi             * 1. New item overlaps the transition, the old one did not
712c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi             * 2. New item does not overlap the transition, the old one did
713c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi             * 3. New and old item overlap the transition if begin or end
714c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi             * time changed
7159bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava             */
716c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi            if (newOverlap != oldOverlap) { // Overlap has changed
7179bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                mEndTransition.invalidate();
718c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi            } else if (newOverlap) { // Both old and new overlap
719c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi                if ((oldStartTimeMs + oldDurationMs != newStartTimeMs + newDurationMs) ||
720c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi                        ((oldStartTimeMs > mDurationMs - transitionDurationMs) ||
721c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi                        newStartTimeMs > mDurationMs - transitionDurationMs)) {
722c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi                    mEndTransition.invalidate();
723c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi                }
7249bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            }
7259bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        }
7269bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    }
7279bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
7289bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    /**
7299bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * This function invalidates the rgb image clip,ken burns effect clip,
7309bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * and scaled image clip
7319bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     */
7329bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    void invalidate() {
7339bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        if (getGeneratedImageClip() != null) {
7349bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            new File(getGeneratedImageClip()).delete();
7359bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            setGeneratedImageClip(null);
7369bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            setRegenerateClip(true);
7379bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        }
738c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi
7399bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        if (mScaledFilename != null) {
740737bd08db020802f1c60941be09e13c3c587f2aaBasavapatna Dattaguru            if(mFileName != mScaledFilename) {
741737bd08db020802f1c60941be09e13c3c587f2aaBasavapatna Dattaguru                new File(mScaledFilename).delete();
742737bd08db020802f1c60941be09e13c3c587f2aaBasavapatna Dattaguru            }
7439bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            mScaledFilename = null;
7449bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        }
745c4edeb5a60a45af874474ae7244c921a268430f1Gil Dobjanschi
7469bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        if (mDecodedFilename != null) {
7479bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            new File(mDecodedFilename).delete();
7489bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            mDecodedFilename = null;
7499bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        }
7509bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    }
7519bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
7529bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    /**
7539bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * @param KenBurnEffect object.
7549bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * @return an Object of {@link ClipSettings} with Ken Burn settings
7559bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * needed to generate the clip
7569bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     */
7579bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    private ClipSettings getKenBurns(EffectKenBurns effectKB) {
7589bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        int PanZoomXa;
7599bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        int PanZoomXb;
7609bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        int width = 0, height = 0;
7619bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        Rect start = new Rect();
7629bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        Rect end = new Rect();
7639bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        ClipSettings clipSettings = null;
7649bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        clipSettings = new ClipSettings();
7659bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        /**
7669bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava         *  image:
7679bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        ---------------------------------------
7689bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava       |    Xa                                  |
7699bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava       | Ya ---------------                     |
7709bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava       |    |                |                  |
7719bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava       |    |                |                  |
7729bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava       |     ---------------    Xb       ratioB |
7739bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava       |        ratioA           -------        |
7749bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava       |                  Yb    |        |      |
7759bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava       |                        |        |      |
7769bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava       |                         -------        |
7779bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        ---------------------------------------
7789bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava         */
7799bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
7809bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        effectKB.getKenBurnsSettings(start, end);
7819bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        width = getWidth();
7829bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        height = getHeight();
7839bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        if ((start.left < 0) || (start.left > width) || (start.right < 0) || (start.right > width)
7849bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                || (start.top < 0) || (start.top > height) || (start.bottom < 0)
7859bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                || (start.bottom > height) || (end.left < 0) || (end.left > width)
7869bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                || (end.right < 0) || (end.right > width) || (end.top < 0) || (end.top > height)
7879bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                || (end.bottom < 0) || (end.bottom > height)) {
7889bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            throw new IllegalArgumentException("Illegal arguments for KebBurns");
7899bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        }
7909bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
7919bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        if (((width - (start.right - start.left) == 0) || (height - (start.bottom - start.top) == 0))
7929bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                && ((width - (end.right - end.left) == 0) || (height - (end.bottom - end.top) == 0))) {
7939bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            setRegenerateClip(false);
7949bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            clipSettings.clipPath = getDecodedImageFileName();
7959bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            clipSettings.fileType = FileType.JPG;
7969bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            clipSettings.beginCutTime = 0;
7979bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            clipSettings.endCutTime = (int)getTimelineDuration();
7989bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            clipSettings.beginCutPercent = 0;
7999bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            clipSettings.endCutPercent = 0;
8009bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            clipSettings.panZoomEnabled = false;
8019bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            clipSettings.panZoomPercentStart = 0;
8029bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            clipSettings.panZoomTopLeftXStart = 0;
8039bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            clipSettings.panZoomTopLeftYStart = 0;
8049bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            clipSettings.panZoomPercentEnd = 0;
8059bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            clipSettings.panZoomTopLeftXEnd = 0;
8069bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            clipSettings.panZoomTopLeftYEnd = 0;
8079bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            clipSettings.mediaRendering = mMANativeHelper
8089bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            .getMediaItemRenderingMode(getRenderingMode());
8099bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
8109bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            clipSettings.rgbWidth = getScaledWidth();
8119bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            clipSettings.rgbHeight = getScaledHeight();
8129bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
8139bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            return clipSettings;
8149bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        }
8159bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
8169803b8435e973d7e44360b91fa6935d0e3981a76Dheeraj Sharma        PanZoomXa = (1000 * start.width()) / width;
8179803b8435e973d7e44360b91fa6935d0e3981a76Dheeraj Sharma        PanZoomXb = (1000 * end.width()) / width;
8189bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
8199bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        clipSettings.clipPath = getDecodedImageFileName();
8209bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        clipSettings.fileType = mMANativeHelper.getMediaItemFileType(getFileType());
8219bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        clipSettings.beginCutTime = 0;
8229bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        clipSettings.endCutTime = (int)getTimelineDuration();
8239bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        clipSettings.beginCutPercent = 0;
8249bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        clipSettings.endCutPercent = 0;
8259bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        clipSettings.panZoomEnabled = true;
8269bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        clipSettings.panZoomPercentStart = PanZoomXa;
8279803b8435e973d7e44360b91fa6935d0e3981a76Dheeraj Sharma        clipSettings.panZoomTopLeftXStart = (start.left * 1000) / width;
8289803b8435e973d7e44360b91fa6935d0e3981a76Dheeraj Sharma        clipSettings.panZoomTopLeftYStart = (start.top * 1000) / height;
8299bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        clipSettings.panZoomPercentEnd = PanZoomXb;
8309803b8435e973d7e44360b91fa6935d0e3981a76Dheeraj Sharma        clipSettings.panZoomTopLeftXEnd = (end.left * 1000) / width;
8319803b8435e973d7e44360b91fa6935d0e3981a76Dheeraj Sharma        clipSettings.panZoomTopLeftYEnd = (end.top * 1000) / height;
8329bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        clipSettings.mediaRendering
8339bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            = mMANativeHelper.getMediaItemRenderingMode(getRenderingMode());
8349bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
8359bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        clipSettings.rgbWidth = getScaledWidth();
8369bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        clipSettings.rgbHeight = getScaledHeight();
8379bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
8389bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        return clipSettings;
8399bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    }
8409bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
8419bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
8429bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    /**
8439bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * @param KenBurnEffect object.
8449bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * @return an Object of {@link ClipSettings} with Ken Burns
8459bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * generated clip name
8469bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     */
8479bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    ClipSettings generateKenburnsClip(EffectKenBurns effectKB) {
8489bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        EditSettings editSettings = new EditSettings();
8499bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        editSettings.clipSettingsArray = new ClipSettings[1];
8509bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        String output = null;
8519bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        ClipSettings clipSettings = new ClipSettings();
8529bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        initClipSettings(clipSettings);
8539bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        editSettings.clipSettingsArray[0] = getKenBurns(effectKB);
8549bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        if ((getGeneratedImageClip() == null) && (getRegenerateClip())) {
8559bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            output = mMANativeHelper.generateKenBurnsClip(editSettings, this);
8569bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            setGeneratedImageClip(output);
8579bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            setRegenerateClip(false);
8589bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            clipSettings.clipPath = output;
8599bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            clipSettings.fileType = FileType.THREE_GPP;
8609bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
8619bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            mGeneratedClipHeight = getScaledHeight();
862600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng            mGeneratedClipWidth = getWidthByAspectRatioAndHeight(
863600acf14ff12eaf139f0ac644fb7e17849af65faHong Teng                    mVideoEditor.getAspectRatio(), mGeneratedClipHeight);
8649bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        } else {
8659bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            if (getGeneratedImageClip() == null) {
8669bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                clipSettings.clipPath = getDecodedImageFileName();
8679bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                clipSettings.fileType = FileType.JPG;
8689bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
8699bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                clipSettings.rgbWidth = getScaledWidth();
8709bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                clipSettings.rgbHeight = getScaledHeight();
8719bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
8729bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            } else {
8739bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                clipSettings.clipPath = getGeneratedImageClip();
8749bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                clipSettings.fileType = FileType.THREE_GPP;
8759bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            }
8769bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        }
8779bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        clipSettings.mediaRendering = mMANativeHelper.getMediaItemRenderingMode(getRenderingMode());
8789bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        clipSettings.beginCutTime = 0;
8799bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        clipSettings.endCutTime = (int)getTimelineDuration();
8809bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
8819bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        return clipSettings;
8829bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    }
8839bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
8849bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    /**
8859bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * @return an Object of {@link ClipSettings} with Image Clip
8869bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * properties data populated.If the image has Ken Burns effect applied,
8879bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * then file path contains generated image clip name with Ken Burns effect
8889bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     */
8899bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    ClipSettings getImageClipProperties() {
8909bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        ClipSettings clipSettings = new ClipSettings();
8919bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        List<Effect> effects = null;
8929bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        EffectKenBurns effectKB = null;
8939bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        boolean effectKBPresent = false;
8949bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
8959bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        effects = getAllEffects();
8969bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        for (Effect effect : effects) {
8979bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            if (effect instanceof EffectKenBurns) {
8989bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                effectKB = (EffectKenBurns)effect;
8999bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                effectKBPresent = true;
9009bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                break;
9019bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            }
9029bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        }
9039bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
9049bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        if (effectKBPresent) {
9059bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            clipSettings = generateKenburnsClip(effectKB);
9069bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        } else {
9079bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            /**
9089bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava             * Init the clip settings object
9099bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava             */
9109bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            initClipSettings(clipSettings);
9119bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            clipSettings.clipPath = getDecodedImageFileName();
9129bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            clipSettings.fileType = FileType.JPG;
9139bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            clipSettings.beginCutTime = 0;
9149bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            clipSettings.endCutTime = (int)getTimelineDuration();
9159bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            clipSettings.mediaRendering = mMANativeHelper
9169bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                .getMediaItemRenderingMode(getRenderingMode());
9179bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            clipSettings.rgbWidth = getScaledWidth();
9189bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            clipSettings.rgbHeight = getScaledHeight();
9199bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
9209bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        }
9219bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        return clipSettings;
9229bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    }
9239bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
9249bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    /**
9259bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * Resize a bitmap to the specified width and height
9269bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     *
9279bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * @param filename The filename
9289bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * @param width The thumbnail width
9299bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * @param height The thumbnail height
9309bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     *
9319bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     * @return The resized bitmap
9329bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava     */
9339bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    private Bitmap scaleImage(String filename, int width, int height)
9349bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    throws IOException {
9359bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        final BitmapFactory.Options dbo = new BitmapFactory.Options();
9369bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        dbo.inJustDecodeBounds = true;
9379bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        BitmapFactory.decodeFile(filename, dbo);
9389bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
9399bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        final int nativeWidth = dbo.outWidth;
9409bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        final int nativeHeight = dbo.outHeight;
9419bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        if (Log.isLoggable(TAG, Log.DEBUG)) {
9429bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            Log.d(TAG, "generateThumbnail: Input: " + nativeWidth + "x" + nativeHeight
9439bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                    + ", resize to: " + width + "x" + height);
9449bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        }
9459bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
9469bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        final Bitmap srcBitmap;
9479bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        float bitmapWidth, bitmapHeight;
9489bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        if (nativeWidth > width || nativeHeight > height) {
9499bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            float dx = ((float)nativeWidth) / ((float)width);
9509bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            float dy = ((float)nativeHeight) / ((float)height);
9519bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
9529bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            if (dx > dy) {
9539bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                bitmapWidth = width;
9546bcbb3bd095daf2c630454f2ac0c26f48b6edf60Santosh Madhava
9556bcbb3bd095daf2c630454f2ac0c26f48b6edf60Santosh Madhava                if (((float)nativeHeight / dx) < (float)height) {
9566bcbb3bd095daf2c630454f2ac0c26f48b6edf60Santosh Madhava                    bitmapHeight = (float)Math.ceil(nativeHeight / dx);
9576bcbb3bd095daf2c630454f2ac0c26f48b6edf60Santosh Madhava                } else { // value equals the requested height
9586bcbb3bd095daf2c630454f2ac0c26f48b6edf60Santosh Madhava                    bitmapHeight = (float)Math.floor(nativeHeight / dx);
9596bcbb3bd095daf2c630454f2ac0c26f48b6edf60Santosh Madhava                }
9606bcbb3bd095daf2c630454f2ac0c26f48b6edf60Santosh Madhava
9619bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            } else {
9626bcbb3bd095daf2c630454f2ac0c26f48b6edf60Santosh Madhava                if (((float)nativeWidth / dy) > (float)width) {
9636bcbb3bd095daf2c630454f2ac0c26f48b6edf60Santosh Madhava                    bitmapWidth = (float)Math.floor(nativeWidth / dy);
9646bcbb3bd095daf2c630454f2ac0c26f48b6edf60Santosh Madhava                } else { // value equals the requested width
9656bcbb3bd095daf2c630454f2ac0c26f48b6edf60Santosh Madhava                    bitmapWidth = (float)Math.ceil(nativeWidth / dy);
9666bcbb3bd095daf2c630454f2ac0c26f48b6edf60Santosh Madhava                }
9676bcbb3bd095daf2c630454f2ac0c26f48b6edf60Santosh Madhava
9689bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                bitmapHeight = height;
9699bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            }
9709bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
9719bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            /**
9729bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava             *  Create the bitmap from file
9739bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava             */
974b1224ff1c4ef8324c9d76b857463787aabd84707Chih-Chung Chang            int sampleSize = (int) Math.ceil(Math.max(
975b1224ff1c4ef8324c9d76b857463787aabd84707Chih-Chung Chang                    (float) nativeWidth / bitmapWidth,
976b1224ff1c4ef8324c9d76b857463787aabd84707Chih-Chung Chang                    (float) nativeHeight / bitmapHeight));
977b1224ff1c4ef8324c9d76b857463787aabd84707Chih-Chung Chang            sampleSize = nextPowerOf2(sampleSize);
978b1224ff1c4ef8324c9d76b857463787aabd84707Chih-Chung Chang            final BitmapFactory.Options options = new BitmapFactory.Options();
979b1224ff1c4ef8324c9d76b857463787aabd84707Chih-Chung Chang            options.inSampleSize = sampleSize;
980b1224ff1c4ef8324c9d76b857463787aabd84707Chih-Chung Chang            srcBitmap = BitmapFactory.decodeFile(filename, options);
9819bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        } else {
9829bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            bitmapWidth = width;
9839bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            bitmapHeight = height;
9849bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            srcBitmap = BitmapFactory.decodeFile(filename);
9859bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
9869bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        }
9879bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
9889bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        if (srcBitmap == null) {
9899bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            Log.e(TAG, "generateThumbnail: Cannot decode image bytes");
9909bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava            throw new IOException("Cannot decode file: " + mFilename);
9919bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        }
9929bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava
9939bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        /**
9949bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava         *  Create the canvas bitmap
9959bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava         */
9969bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        final Bitmap bitmap = Bitmap.createBitmap((int)bitmapWidth,
9979bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                                                  (int)bitmapHeight,
9989bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                                                  Bitmap.Config.ARGB_8888);
9999bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        final Canvas canvas = new Canvas(bitmap);
10009bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        canvas.drawBitmap(srcBitmap, new Rect(0, 0, srcBitmap.getWidth(),
10019bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                                              srcBitmap.getHeight()),
10029bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                                              new Rect(0, 0, (int)bitmapWidth,
10039bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava                                              (int)bitmapHeight), sResizePaint);
10046311d0a079702b29984c0d31937345be105e1a5eDianne Hackborn        canvas.setBitmap(null);
10059bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        /**
10069bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava         *  Release the source bitmap
10079bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava         */
10089bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        srcBitmap.recycle();
10099bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava        return bitmap;
10109bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava    }
1011b1224ff1c4ef8324c9d76b857463787aabd84707Chih-Chung Chang
1012b1224ff1c4ef8324c9d76b857463787aabd84707Chih-Chung Chang    public static int nextPowerOf2(int n) {
1013b1224ff1c4ef8324c9d76b857463787aabd84707Chih-Chung Chang        n -= 1;
1014b1224ff1c4ef8324c9d76b857463787aabd84707Chih-Chung Chang        n |= n >>> 16;
1015b1224ff1c4ef8324c9d76b857463787aabd84707Chih-Chung Chang        n |= n >>> 8;
1016b1224ff1c4ef8324c9d76b857463787aabd84707Chih-Chung Chang        n |= n >>> 4;
1017b1224ff1c4ef8324c9d76b857463787aabd84707Chih-Chung Chang        n |= n >>> 2;
1018b1224ff1c4ef8324c9d76b857463787aabd84707Chih-Chung Chang        n |= n >>> 1;
1019b1224ff1c4ef8324c9d76b857463787aabd84707Chih-Chung Chang        return n + 1;
1020b1224ff1c4ef8324c9d76b857463787aabd84707Chih-Chung Chang    }
10219bcedf7cf3e9c981837f2d8ec98cd118efad3f01Santosh Madhava}
1022