diff --git a/Android.mk b/Android.mk
index cc460ffeb7f109040559b99597e6276463478bcf..d6d543157f83acde2f43d9e802842446f48ccbdd 100644
--- a/Android.mk
+++ b/Android.mk
@@ -32,14 +32,16 @@ LOCAL_RENDERSCRIPT_TARGET_API := 23
 
 LOCAL_PROGUARD_FLAG_FILES := proguard.flags
 
+LOCAL_MULTILIB := 32
+
 # If this is an unbundled build (to install separately) then include
 # the libraries in the APK, otherwise just put them in /system/lib and
 # leave them out of the APK
-ifneq (,$(TARGET_BUILD_APPS))
+#ifneq (,$(TARGET_BUILD_APPS))
   LOCAL_JNI_SHARED_LIBRARIES := libjni_snapcammosaic libjni_snapcamtinyplanet libjni_imageutil
-else
-  LOCAL_REQUIRED_MODULES := libjni_snapcammosaic libjni_snapcamtinyplanet libjni_imageutil
-endif
+#else
+#  LOCAL_REQUIRED_MODULES := libjni_snapcammosaic libjni_snapcamtinyplanet libjni_imageutil
+#endif
 
 include $(BUILD_PACKAGE)
 
diff --git a/assets/dependency.json b/assets/dependency.json
index 69a0d8db6a807830d2f2836081695176ac37603f..7a76559d2766b0b8fa398c664b131b418d57087d 100644
--- a/assets/dependency.json
+++ b/assets/dependency.json
@@ -105,6 +105,10 @@
     ,
     "109":
     {"pref_camera2_coloreffect_key":"0"}
+    ,
+    "110":
+    {"pref_camera2_coloreffect_key":"0",
+      "pref_camera2_longshot_key":"off"}
   },
   "pref_camera2_clearsight_key":
   {
diff --git a/res/layout/capture_module.xml b/res/layout/capture_module.xml
index ebbe7dea833fd389de34c52dd088d4a20f7b6099..b3ade9f552ac67153ef95eee15c9dc72924d74fb 100755
--- a/res/layout/capture_module.xml
+++ b/res/layout/capture_module.xml
@@ -116,6 +116,29 @@
     <include
         layout="@layout/scene_mode_label"/>
 
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginLeft="20dp"
+        android:layout_marginTop="90dp"
+        android:gravity="left">
+        <com.android.camera.ui.RotateLayout
+            android:id="@+id/deepzoom_set_layout"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:visibility="gone">
+            <TextView
+                android:id="@+id/deepzoom_set"
+                style="@style/OnViewfinderSceneLabel"
+                android:clickable="true"
+                android:singleLine="true"
+                android:textColor="@android:color/white"
+                android:background="#90000000"
+                android:padding="6dp"
+                android:textSize="16dp" />
+        </com.android.camera.ui.RotateLayout>
+    </LinearLayout>
+
     <include
         style="@style/CameraControls"
         layout="@layout/one_ui_layout"
diff --git a/res/values/camera2arrays.xml b/res/values/camera2arrays.xml
index 86091e7c8893f9bd162ca890e990243e90c6a984..c3377d4b16d76e278c5c7c9d6e7fa0897e02eb2a 100755
--- a/res/values/camera2arrays.xml
+++ b/res/values/camera2arrays.xml
@@ -158,6 +158,7 @@
         <item>108</item>
         <item>104</item>
         <item>109</item>
+        <item>110</item>
     </string-array>
 
     <!-- Camera Preferences Scene Mode dialog box entries -->
@@ -185,6 +186,7 @@
         <item>@string/pref_camera_scenemode_entry_trackingfocus</item>
         <item>@string/pref_camera_scenemode_entry_panorama</item>
         <item>@string/pref_camera_scenemode_entry_promode</item>
+        <item>@string/pref_camera_scenemode_entry_deepzoom</item>
     </string-array>
 
     <array name="pref_camera2_scenemode_thumbnails" translatable="false">
@@ -211,6 +213,7 @@
         <item>@drawable/tracking_focus</item>
         <item>@drawable/scene_panorama</item>
         <item>@drawable/promode</item>
+        <item>@drawable/sharp_photo</item>
     </array>
 
     <array name="pref_camera2_scenemode_black_thumbnails" translatable="false">
@@ -237,6 +240,7 @@
         <item>@drawable/ic_scene_mode_black_tracking_focus</item>
         <item>@drawable/ic_scene_mode_black_panorama</item>
         <item>@drawable/ic_scene_mode_black_dual_camera</item>
+        <item>@drawable/ic_scene_mode_black_sharp_photo</item>
     </array>
 
     <!-- Camera Preferences Scene Mode dialog box entries -->
@@ -264,6 +268,7 @@
         <item>@string/pref_camera2_scene_mode_tracking_focus_instructional_content</item>
         <item>@string/pref_camera2_scene_mode_panorama_instructional_content</item>
         <item>@string/pref_camera2_scene_mode_pro_instructional_content</item>
+        <item>@string/pref_camera2_scene_mode_deepzoom_instructional_content</item>
     </string-array>
 
     <string-array name="pref_camera2_whitebalance_entryvalues" translatable="false">
diff --git a/res/values/qcomstrings.xml b/res/values/qcomstrings.xml
index aee9e2515bd0d77d92074001cdc43076bf288ff6..2374997dc2e97fa9f7c224c153418e289c57de3c 100755
--- a/res/values/qcomstrings.xml
+++ b/res/values/qcomstrings.xml
@@ -1030,6 +1030,7 @@
     <string name="pref_camera_scenemode_entry_trackingfocus" translatable="true">TrackingFocus</string>
     <string name="pref_camera_scenemode_entry_panorama" translatable="true">Panorama</string>
     <string name="pref_camera_scenemode_entry_promode" translatable="true">ProMode</string>
+    <string name="pref_camera_scenemode_entry_deepzoom" translatable="true">DeepZoom</string>
     <string name="bestpicture_done" translatable="true">SAVE</string>
     <string name="bestpicture_at_least_one_picture" translatable="true">At least, one picture has to be chosen.</string>
 
@@ -1085,6 +1086,7 @@
     <string name="pref_camera2_scene_mode_panorama_instructional_content"  translatable="true">Allows you to pan left or right to take a wide landscape photo. You can alse pan up or down to take tall photos.</string>
     <string name="pref_camera2_scene_mode_blur_buster_instructional_content"  translatable="true">BlurBuster reduces blur from shaky hands.It can be helpful when taking photos in difficult places.</string>
     <string name="pref_camera2_scene_mode_pro_instructional_content"  translatable="true">With Pro Mode, you can manually control settings for ISO,Exposure, White Balance, and Focus. You will have easy access to all of these advanced settings</string>
+    <string name="pref_camera2_scene_mode_deepzoom_instructional_content"  translatable="true">With DeepZoom Mode, you can use the 2X or 4X to take picture, then you can get the deepzoom`s picture </string>
 
     <string name="pref_camera2_not_show_again">Do not show again</string>
     <string name="pref_camera2_scene_mode_instructional_ok" translatable="true">OK</string>
diff --git a/src/com/android/camera/CaptureModule.java b/src/com/android/camera/CaptureModule.java
index 24b9137fd3aec4ae2da692abcb2a870bf36f0042..6539fa7d25cbef438e6b4abf8e45fc324c60a5fa 100755
--- a/src/com/android/camera/CaptureModule.java
+++ b/src/com/android/camera/CaptureModule.java
@@ -334,6 +334,7 @@ public class CaptureModule implements CameraModule, PhotoController,
     private boolean mQuickCapture;
     private byte[] mJpegImageData;
     private boolean mSaveRaw = false;
+    private boolean mSupportZoomCapture = true;
 
     /**
      * A {@link CameraCaptureSession } for camera preview.
@@ -1652,6 +1653,7 @@ public class CaptureModule implements CameraModule, PhotoController,
         Log.d(TAG, "captureStillPicture " + id);
         mJpegImageData = null;
         mIsRefocus = false;
+        if (isDeepZoom()) mSupportZoomCapture = false;
         try {
             if (null == mActivity || null == mCameraDevice[id]) {
                 warningToast("Camera is not ready yet to take a picture.");
@@ -1671,7 +1673,7 @@ public class CaptureModule implements CameraModule, PhotoController,
             applySettingsForJpegInformation(captureBuilder, id);
             applyAFRegions(captureBuilder, id);
             applyAERegions(captureBuilder, id);
-            if (!mIsSupportedQcfa) {
+            if (!mIsSupportedQcfa || !isDeepZoom()) {
                 addPreviewSurface(captureBuilder, null, id);
             }
             VendorTagUtil.setCdsMode(captureBuilder, 2);// CDS 0-OFF, 1-ON, 2-AUTO
@@ -1682,6 +1684,7 @@ public class CaptureModule implements CameraModule, PhotoController,
                 captureBuilder.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_OFF);
             }
 
+            if (isDeepZoom()) mSupportZoomCapture = true;
             if(isClearSightOn()) {
                 captureStillPictureForClearSight(id);
             } else if(id == getMainCameraId() && mPostProcessor.isFilterOn()) { // Case of post filtering
@@ -1744,7 +1747,9 @@ public class CaptureModule implements CameraModule, PhotoController,
             //CameraDevice was already closed
             return;
         }
-        mCaptureSession[id].stopRepeating();
+        if (!isDeepZoom()) {
+            mCaptureSession[id].stopRepeating();
+        }
         captureBuilder.addTarget(mImageReader[id].getSurface());
         if (mSaveRaw) {
             captureBuilder.addTarget(mRawImageReader[id].getSurface());
@@ -2585,6 +2590,8 @@ public class CaptureModule implements CameraModule, PhotoController,
             return PostProcessor.FILTER_SHARPSHOOTER;
         } else if (mode == SettingsManager.SCENE_MODE_BESTPICTURE_INT) {
             return PostProcessor.FILTER_BESTPICTURE;
+        } else if (mode == SettingsManager.SCENE_MODE_DEEPZOOM_INT) {
+            return PostProcessor.FILTER_DEEPZOOM;
         }
         return PostProcessor.FILTER_NONE;
     }
@@ -2842,28 +2849,7 @@ public class CaptureModule implements CameraModule, PhotoController,
     @Override
     public void onZoomChanged(float requestedZoom) {
         mZoomValue = requestedZoom;
-
-        if (isBackCamera()) {
-            switch (getCameraMode()) {
-                case DUAL_MODE:
-                    applyZoomAndUpdate(BAYER_ID);
-                    applyZoomAndUpdate(MONO_ID);
-                    break;
-                case BAYER_MODE:
-                    applyZoomAndUpdate(BAYER_ID);
-                    break;
-                case MONO_MODE:
-                    applyZoomAndUpdate(MONO_ID);
-                    break;
-                case SWITCH_MODE:
-                    applyZoomAndUpdate(SWITCH_ID);
-                    break;
-            }
-        } else {
-            int cameraId = SWITCH_ID == -1? FRONT_ID : SWITCH_ID;
-            applyZoomAndUpdate(cameraId);
-        }
-        mUI.updateFaceViewCameraBound(mCropRegion[getMainCameraId()]);
+        applyZoomAndUpdate();
     }
 
     private boolean isInMode(int cameraId) {
@@ -3403,6 +3389,35 @@ public class CaptureModule implements CameraModule, PhotoController,
         }
     }
 
+    public void updateDeepZoomIndex(float zoom) {
+        mZoomValue = zoom;
+        applyZoomAndUpdate();
+    }
+
+    private void applyZoomAndUpdate() {
+        if (isBackCamera()) {
+            switch (getCameraMode()) {
+                case DUAL_MODE:
+                    applyZoomAndUpdate(BAYER_ID);
+                    applyZoomAndUpdate(MONO_ID);
+                    break;
+                case BAYER_MODE:
+                    applyZoomAndUpdate(BAYER_ID);
+                    break;
+                case MONO_MODE:
+                    applyZoomAndUpdate(MONO_ID);
+                    break;
+                case SWITCH_MODE:
+                    applyZoomAndUpdate(SWITCH_ID);
+                    break;
+            }
+        } else {
+            int cameraId = SWITCH_ID == -1 ? FRONT_ID : SWITCH_ID;
+            applyZoomAndUpdate(cameraId);
+        }
+        mUI.updateFaceViewCameraBound(mCropRegion[getMainCameraId()]);
+    }
+
     private void updateZoom() {
         String zoomStr = mSettingsManager.getValue(SettingsManager.KEY_ZOOM);
         int zoom = Integer.parseInt(zoomStr);
@@ -3411,6 +3426,9 @@ public class CaptureModule implements CameraModule, PhotoController,
         }else{
             mZoomValue = 1.0f;
         }
+        if (isDeepZoom()) {
+            mZoomValue = mUI.getDeepZoomValue();
+        }
     }
 
     private boolean startRecordingVideo(final int cameraId) {
@@ -4459,6 +4477,7 @@ public class CaptureModule implements CameraModule, PhotoController,
     }
 
     private void applyZoom(CaptureRequest.Builder request, int id) {
+        if (!mSupportZoomCapture) return;
         request.set(CaptureRequest.SCALER_CROP_REGION, cropRegionForZoom(id));
     }
 
@@ -5231,6 +5250,18 @@ public class CaptureModule implements CameraModule, PhotoController,
         return false;
     }
 
+    public boolean isDeepZoom() {
+        String value = mSettingsManager.getValue(SettingsManager.KEY_SCENE_MODE);
+        try {
+            int mode = Integer.parseInt(value);
+            if(mode == SettingsManager.SCENE_MODE_DEEPZOOM_INT) {
+                return true;
+            }
+        } catch(Exception e) {
+        }
+        return false;
+    }
+
     private void updateFaceDetection() {
         final String value = mSettingsManager.getValue(SettingsManager.KEY_FACE_DETECTION);
         mActivity.runOnUiThread(new Runnable() {
diff --git a/src/com/android/camera/CaptureUI.java b/src/com/android/camera/CaptureUI.java
index 47ffc14354a4ac6fd5569ab00316c2df9d457146..450ba62b39690b367c08f62bb30313cb378ea705 100755
--- a/src/com/android/camera/CaptureUI.java
+++ b/src/com/android/camera/CaptureUI.java
@@ -198,9 +198,13 @@ public class CaptureUI implements FocusOverlayManager.FocusUI,
     private ImageView mSeekbarToggleButton;
     private View mProModeCloseButton;
     private RotateLayout mSceneModeLabelRect;
-    private LinearLayout mSceneModeLabelView;
     private TextView mSceneModeName;
     private ImageView mExitBestMode;
+    private RotateLayout mDeepZoomModeRect;
+    private TextView mDeepzoomSetName;
+    private int mDeepZoomIndex = 0;
+    private float mDeepZoomValue = 1.0f;
+
     private ImageView mSceneModeLabelCloseIcon;
     private AlertDialog  mSceneModeInstructionalDialog = null;
 
@@ -371,6 +375,16 @@ public class CaptureUI implements FocusOverlayManager.FocusUI,
         RotateImageView muteButton = (RotateImageView) mRootView.findViewById(R.id.mute_button);
         muteButton.setVisibility(View.GONE);
 
+        mDeepZoomModeRect = (RotateLayout)mRootView.findViewById(R.id.deepzoom_set_layout);
+        mDeepzoomSetName = (TextView)mRootView.findViewById(R.id.deepzoom_set);
+        mDeepzoomSetName.setText("Zoom OFF");
+        mDeepzoomSetName.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                mDeepZoomIndex = (mDeepZoomIndex + 1) % 3;
+                updateDeepZoomIndex();
+            }
+        });
         mSceneModeLabelRect = (RotateLayout)mRootView.findViewById(R.id.scene_mode_label_rect);
         mSceneModeName = (TextView)mRootView.findViewById(R.id.scene_mode_label);
         mSceneModeLabelCloseIcon = (ImageView)mRootView.findViewById(R.id.scene_mode_label_close);
@@ -509,6 +523,28 @@ public class CaptureUI implements FocusOverlayManager.FocusUI,
         return mModule.getCurrentIntentMode();
     }
 
+    private void updateDeepZoomIndex() {
+        switch(mDeepZoomIndex) {
+            case 0:
+                mDeepzoomSetName.setText("Zoom OFF");
+                mDeepZoomValue = 1.0f;
+                break;
+            case 1:
+                mDeepzoomSetName.setText("Zoom 2X");
+                mDeepZoomValue = 2.0f;
+                break;
+            case 2:
+                mDeepzoomSetName.setText("Zoom 4X");
+                mDeepZoomValue = 4.0f;
+                break;
+            default:
+                mDeepZoomValue = 1.0f;
+                mDeepzoomSetName.setText("Zoom OFF");
+                break;
+        }
+        mModule.updateDeepZoomIndex(mDeepZoomValue);
+    }
+
     private void toggleMakeup() {
         String value = mSettingsManager.getValue(SettingsManager.KEY_MAKEUP);
         if(value != null && !mIsVideoUI) {
@@ -543,10 +579,18 @@ public class CaptureUI implements FocusOverlayManager.FocusUI,
         });
     }
 
+    public float getDeepZoomValue() {
+        return mDeepZoomValue;
+    }
+
     public void onCameraOpened(List<Integer> cameraIds) {
         mGestures.setCaptureUI(this);
-        mGestures.setZoomEnabled(mSettingsManager.isZoomSupported(cameraIds));
-        initializeZoom(cameraIds);
+        if (mModule.isDeepZoom()) {
+            mGestures.setZoomEnabled(false);
+        } else {
+            mGestures.setZoomEnabled(mSettingsManager.isZoomSupported(cameraIds));
+            initializeZoom(cameraIds);
+        }
     }
 
     public void reInitUI() {
@@ -871,9 +915,15 @@ public class CaptureUI implements FocusOverlayManager.FocusUI,
             mSceneModeName.setText(sceneModeNameArray[index]);
             mSceneModeLabelRect.setVisibility(View.VISIBLE);
             mExitBestMode.setVisibility(View.VISIBLE);
+            if (mModule.isDeepZoom()) {
+                mDeepZoomModeRect.setVisibility(View.VISIBLE);
+            } else {
+                mDeepZoomModeRect.setVisibility(View.GONE);
+            }
         }else{
             mSceneModeLabelRect.setVisibility(View.GONE);
             mExitBestMode.setVisibility(View.GONE);
+            mDeepZoomModeRect.setVisibility(View.GONE);
         }
     }
 
@@ -888,6 +938,7 @@ public class CaptureUI implements FocusOverlayManager.FocusUI,
     public void hideUIwhileRecording() {
         mCameraControls.setVideoMode(true);
         mSceneModeLabelRect.setVisibility(View.INVISIBLE);
+        mDeepZoomModeRect.setVisibility(View.INVISIBLE);
         mFrontBackSwitcher.setVisibility(View.INVISIBLE);
         mFilterModeSwitcher.setVisibility(View.INVISIBLE);
         mSceneModeSwitcher.setVisibility(View.INVISIBLE);
@@ -1513,6 +1564,15 @@ public class CaptureUI implements FocusOverlayManager.FocusUI,
                 mSceneModeLabelRect.setOrientation(orientation, false);
             }
         }
+        if ( mDeepZoomModeRect != null ) {
+            if (orientation == 180) {
+                mDeepzoomSetName.setRotation(180);
+                mDeepZoomModeRect.setOrientation(0, false);
+            } else {
+                mDeepzoomSetName.setRotation(0);
+                mDeepZoomModeRect.setOrientation(orientation, false);
+            }
+        }
 
         if ( mSceneModeInstructionalDialog != null && mSceneModeInstructionalDialog.isShowing()) {
             mSceneModeInstructionalDialog.dismiss();
diff --git a/src/com/android/camera/SettingsManager.java b/src/com/android/camera/SettingsManager.java
index e0372153a58d7814d67b584586b091d2b33f4786..6f17a214b7b4843161df0f444977bfd93c9f74b4 100755
--- a/src/com/android/camera/SettingsManager.java
+++ b/src/com/android/camera/SettingsManager.java
@@ -57,6 +57,7 @@ import com.android.camera.imageprocessor.filter.SharpshooterFilter;
 import com.android.camera.imageprocessor.filter.StillmoreFilter;
 import com.android.camera.imageprocessor.filter.TrackingFocusFrameListener;
 import com.android.camera.imageprocessor.filter.UbifocusFilter;
+import com.android.camera.imageprocessor.filter.DeepZoomFilter;
 import com.android.camera.ui.ListMenu;
 import com.android.camera.ui.PanoCaptureProcessView;
 import com.android.camera.ui.TrackingFocusRenderer;
@@ -98,6 +99,7 @@ public class SettingsManager implements ListMenu.SettingsListener {
     public static final int SCENE_MODE_SHARPSHOOTER_INT = SCENE_MODE_CUSTOM_START + 7;
     public static final int SCENE_MODE_TRACKINGFOCUS_INT = SCENE_MODE_CUSTOM_START + 8;
     public static final int SCENE_MODE_PROMODE_INT = SCENE_MODE_CUSTOM_START + 9;
+    public static final int SCENE_MODE_DEEPZOOM_INT = SCENE_MODE_CUSTOM_START + 10;
     public static final String SCENE_MODE_DUAL_STRING = "100";
     public static final String KEY_CAMERA_SAVEPATH = "pref_camera2_savepath_key";
     public static final String KEY_RECORD_LOCATION = "pref_camera2_recordlocation_key";
@@ -1326,6 +1328,7 @@ public class SettingsManager implements ListMenu.SettingsListener {
         if (BlurbusterFilter.isSupportedStatic()) modes.add(SCENE_MODE_BLURBUSTER_INT + "");
         if (SharpshooterFilter.isSupportedStatic()) modes.add(SCENE_MODE_SHARPSHOOTER_INT + "");
         if (TrackingFocusFrameListener.isSupportedStatic()) modes.add(SCENE_MODE_TRACKINGFOCUS_INT + "");
+        if (DeepZoomFilter.isSupportedStatic()) modes.add(SCENE_MODE_DEEPZOOM_INT + "");
         modes.add("" + SCENE_MODE_PROMODE_INT);
         for (int mode : sceneModes) {
             modes.add("" + mode);
diff --git a/src/com/android/camera/imageprocessor/PostProcessor.java b/src/com/android/camera/imageprocessor/PostProcessor.java
index 4f77b90e48ecd818c214fe54a4f3ea06752397a2..72a92b4b3393324829950b733b7164b74bf16790 100644
--- a/src/com/android/camera/imageprocessor/PostProcessor.java
+++ b/src/com/android/camera/imageprocessor/PostProcessor.java
@@ -68,6 +68,7 @@ import com.android.camera.imageprocessor.filter.OptizoomFilter;
 import com.android.camera.imageprocessor.filter.SharpshooterFilter;
 import com.android.camera.imageprocessor.filter.StillmoreFilter;
 import com.android.camera.imageprocessor.filter.UbifocusFilter;
+import com.android.camera.imageprocessor.filter.DeepZoomFilter;
 import com.android.camera.ui.RotateTextToast;
 
 import java.io.ByteArrayOutputStream;
@@ -99,7 +100,8 @@ public class PostProcessor{
     public static final int FILTER_BESTPICTURE = 5;
     public static final int FILTER_CHROMAFLASH = 6;
     public static final int FILTER_BLURBUSTER = 7;
-    public static final int FILTER_MAX = 8;
+    public static final int FILTER_DEEPZOOM = 8;
+    public static final int FILTER_MAX = 9;
 
     //BestPicture requires 10 which is the biggest among filters
     private static final int MAX_REQUIRED_IMAGE_NUM = 11;
@@ -878,6 +880,9 @@ public class PostProcessor{
                 case FILTER_CHROMAFLASH:
                     mFilter = new ChromaflashFilter(mController);
                     break;
+                case FILTER_DEEPZOOM:
+                    mFilter = new DeepZoomFilter(mController);
+                    break;
             }
         }
 
diff --git a/src/com/android/camera/imageprocessor/filter/DeepZoomFilter.java b/src/com/android/camera/imageprocessor/filter/DeepZoomFilter.java
new file mode 100755
index 0000000000000000000000000000000000000000..003b4582fda2a88822d2977a5960b311162c5ce1
--- /dev/null
+++ b/src/com/android/camera/imageprocessor/filter/DeepZoomFilter.java
@@ -0,0 +1,178 @@
+/*
+Copyright (c) 2017, The Linux Foundation. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of The Linux Foundation nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.android.camera.imageprocessor.filter;
+
+import android.graphics.Rect;
+import android.hardware.camera2.CameraAccessException;
+import android.hardware.camera2.CameraCaptureSession;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.CaptureResult;
+import android.hardware.camera2.TotalCaptureResult;
+import android.os.Handler;
+import android.util.Log;
+
+import com.android.camera.CaptureModule;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+
+public class DeepZoomFilter implements ImageFilter{
+    public static final int NUM_REQUIRED_IMAGE = 1;
+    private int mWidth;
+    private int mHeight;
+    private int mStrideY;
+    private int mStrideVU;
+    private static String TAG = "DeepZoomFilter";
+
+    private static boolean mIsSupported = false;
+    private ByteBuffer mOutBuf;
+    private CaptureModule mModule;
+    private int mImageNum = -1;
+
+    private static void Log(String msg) {
+        if(DEBUG) {
+            Log.d(TAG, msg);
+        }
+    }
+
+    public DeepZoomFilter(CaptureModule module) {
+        mModule = module;
+    }
+
+    @Override
+    public List<CaptureRequest> setRequiredImages(CaptureRequest.Builder builder) {
+        List<CaptureRequest> list = new ArrayList<CaptureRequest>();
+        for(int i=0; i < NUM_REQUIRED_IMAGE; i++) {
+            list.add(builder.build());
+        }
+        return list;
+    }
+
+    @Override
+    public String getStringName() {
+        return TAG;
+    }
+
+    @Override
+    public int getNumRequiredImage() {
+        return NUM_REQUIRED_IMAGE;
+    }
+
+    @Override
+    public void init(int width, int height, int strideY, int strideVU) {
+        Log("init");
+        mWidth = width/2*2;
+        mHeight = height/2*2;
+        mStrideY = strideY/2*2;
+        mStrideVU = strideVU/2*2;
+        mOutBuf = ByteBuffer.allocate(mStrideY*mHeight*3/2);
+        mImageNum = -1;
+        Log("width: "+mWidth+" height: "+mHeight+" strideY: "+mStrideY+" strideVU: "+mStrideVU);
+        nativeInit(mWidth, mHeight, mStrideY, mStrideVU,
+                0, 0, mWidth, mHeight, NUM_REQUIRED_IMAGE);
+    }
+
+    @Override
+    public void deinit() {
+        Log("deinit");
+        mOutBuf = null;
+        mImageNum = -1;
+        nativeDeinit();
+    }
+
+    @Override
+    public void addImage(ByteBuffer bY, ByteBuffer bVU, int imageNum, Object param) {
+        Log("addImage imageNum :" + imageNum);
+        int yActualSize = bY.remaining();
+        int vuActualSize = bVU.remaining();
+        mImageNum = imageNum;
+        int status = nativeAddImage(bY, bVU, yActualSize, vuActualSize, imageNum);
+        Log("addImage status :" + status);
+        if(status != 0) {
+            Log.e(TAG, "Fail to add image");
+        }
+    }
+
+    @Override
+    public ResultImage processImage() {
+        float zoomValue = mModule.getZoomValue();
+        Log("processImage zoomValue :" + zoomValue);
+        int[] roi = new int[4];
+        int status = nativeProcessImage(mOutBuf.array(), zoomValue, roi);
+        Log("processImage done status :" + status);
+        mImageNum = -1;
+        if(status < 0) { //In failure case, library will return the first image as it is.
+            Log.w(TAG, "Fail to process the image.");
+        }
+        return new ResultImage(mOutBuf, new Rect(roi[0], roi[1], roi[0]+roi[2], roi[1] + roi[3]), mWidth, mHeight, mStrideY);
+    }
+
+    @Override
+    public boolean isSupported() {
+        return mIsSupported;
+    }
+
+    @Override
+    public boolean isFrameListener() {
+        return false;
+    }
+
+    @Override
+    public boolean isManualMode() {
+        return false;
+    }
+
+    @Override
+    public void manualCapture(final CaptureRequest.Builder builder, final CameraCaptureSession captureSession,
+                              final CameraCaptureSession.CaptureCallback callback, final Handler handler) throws CameraAccessException  {
+    }
+
+    public static boolean isSupportedStatic() {
+        return mIsSupported;
+    }
+
+    private native int nativeInit(int width, int height, int yStride, int vuStride,
+                                  int roiX, int roiY, int roiW, int roiH, int numImages);
+    private native int nativeDeinit();
+    private native int nativeAddImage(ByteBuffer yB, ByteBuffer vuB, int ySize, int vuSize, int imageNum);
+    private native int nativeProcessImage(byte[] buffer, float zoomValue, int[] roi);
+
+    static {
+        try {
+            System.loadLibrary("jni_deepzoom");
+            mIsSupported = true;
+        }catch(UnsatisfiedLinkError e) {
+            Log.d(TAG, e.toString());
+            mIsSupported = false;
+        }
+    }
+}
diff --git a/src/com/android/camera/util/PersistUtil.java b/src/com/android/camera/util/PersistUtil.java
index 9cb79ba5af7309d0bd5290ef53c28f5da91fecad..f46959f5e75f92cc6493e743e57ed4902ed55656 100644
--- a/src/com/android/camera/util/PersistUtil.java
+++ b/src/com/android/camera/util/PersistUtil.java
@@ -56,8 +56,6 @@ public class PersistUtil {
             SystemProperties.getBoolean("persist.vendor.camera.camera2", true);
     private static final boolean PERSIST_CAMERA_ZSL =
             SystemProperties.getBoolean("persist.vendor.camera.zsl.disabled", false);
-    private static final int PERSIST_CAMERA2_DEBUG =
-            SystemProperties.getInt("persist.vendor.camera2.debug", 0);
     private static final int PERSIST_CAMERA_CANCEL_TOUCHFOCUS_DELAY =
             SystemProperties.getInt("persist.vendor.camera.focus_delay", 5000);
     private static final int PERSIST_CAMERA_DEBUG =