181f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen/* 281f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * Copyright (C) 2011 The Android Open Source Project 381f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * 481f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * Licensed under the Apache License, Version 2.0 (the "License"); 581f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * you may not use this file except in compliance with the License. 681f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * You may obtain a copy of the License at 781f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * 881f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * http://www.apache.org/licenses/LICENSE-2.0 981f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * 1081f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * Unless required by applicable law or agreed to in writing, software 1181f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * distributed under the License is distributed on an "AS IS" BASIS, 1281f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1381f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * See the License for the specific language governing permissions and 1481f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * limitations under the License. 1581f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen */ 1681f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen 1781f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chenpackage com.android.camera.panorama; 1881f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen 1981f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen/** 2081f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * The Java interface to JNI calls regarding mosaic stitching. 2181f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * 2281f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * A high-level usage is: 2381f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * 2481f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * Mosaic mosaic = new Mosaic(); 2581f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * mosaic.setSourceImageDimensions(width, height); 2681f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * mosaic.reset(blendType); 2781f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * 2881f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * while ((pixels = hasNextImage()) != null) { 2981f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * mosaic.setSourceImage(pixels); 3081f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * } 3181f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * 3281f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * mosaic.createMosaic(highRes); 3381f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * byte[] result = mosaic.getFinalMosaic(); 3481f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * 3581f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen */ 3681f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chenpublic class Mosaic { 3781f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen /** 3881f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * In this mode, the images are stitched together in the same spatial arrangement as acquired 3981f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * i.e. if the user follows a curvy trajectory, the image boundary of the resulting mosaic will 4081f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * be curved in the same manner. This mode is useful if the user wants to capture a mosaic as 4181f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * if "painting" the scene using the smart-phone device and does not want any corrective warps 4281f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * to distort the captured images. 4381f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen */ 4481f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen public static final int BLENDTYPE_FULL = 0; 4581f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen 4681f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen /** 4781f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * This mode is the same as BLENDTYPE_FULL except that the resulting mosaic is rotated 4881f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * to balance the first and last images to be approximately at the same vertical offset in the 4981f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * output mosaic. This is useful when acquiring a mosaic by a typical panning-like motion to 5081f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * remove a one-sided curve in the mosaic (typically due to the camera not staying horizontal 5181f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * during the video capture) and convert it to a more symmetrical "smiley-face" like output. 5281f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen */ 5381f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen public static final int BLENDTYPE_PAN = 1; 5481f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen 5581f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen /** 5681f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * This mode compensates for typical "smiley-face" like output in longer mosaics and creates 5781f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * a rectangular mosaic with minimal black borders (by unwrapping the mosaic onto an imaginary 5881f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * cylinder). If the user follows a curved trajectory (instead of a perfect panning trajectory), 5981f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * the resulting mosaic here may suffer from some image distortions in trying to map the 6081f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * trajectory to a cylinder. 6181f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen */ 6281f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen public static final int BLENDTYPE_CYLINDERPAN = 2; 6381f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen 6481f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen /** 6581f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * This mode is basically BLENDTYPE_CYLINDERPAN plus doing a rectangle cropping before returning 6681f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * the mosaic. The mode is useful for making the resulting mosaic have a rectangle shape. 6781f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen */ 6881f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen public static final int BLENDTYPE_HORIZONTAL =3; 6981f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen 70e1178a73fd5756771d25d0b8375452450f509e99mbansal /** 71b28b9c0fa991bc97e8aa11da83d27f71fdfef6dambansal * This strip type will use the default thin strips where the strips are 72b28b9c0fa991bc97e8aa11da83d27f71fdfef6dambansal * spaced according to the image capture rate. 73b28b9c0fa991bc97e8aa11da83d27f71fdfef6dambansal */ 74b28b9c0fa991bc97e8aa11da83d27f71fdfef6dambansal public static final int STRIPTYPE_THIN = 0; 75b28b9c0fa991bc97e8aa11da83d27f71fdfef6dambansal 76b28b9c0fa991bc97e8aa11da83d27f71fdfef6dambansal /** 77b28b9c0fa991bc97e8aa11da83d27f71fdfef6dambansal * This strip type will use wider strips for blending. The strip separation 78b28b9c0fa991bc97e8aa11da83d27f71fdfef6dambansal * is controlled by a threshold on the native side. Since the strips are 79b28b9c0fa991bc97e8aa11da83d27f71fdfef6dambansal * wider, there is an additional cross-fade blending step to make the seam 80b28b9c0fa991bc97e8aa11da83d27f71fdfef6dambansal * boundaries smoother. Since this mode uses lesser image frames, it is 81b28b9c0fa991bc97e8aa11da83d27f71fdfef6dambansal * computationally more efficient than the thin strip mode. 82b28b9c0fa991bc97e8aa11da83d27f71fdfef6dambansal */ 83b28b9c0fa991bc97e8aa11da83d27f71fdfef6dambansal public static final int STRIPTYPE_WIDE = 1; 84b28b9c0fa991bc97e8aa11da83d27f71fdfef6dambansal 85b28b9c0fa991bc97e8aa11da83d27f71fdfef6dambansal /** 86e1178a73fd5756771d25d0b8375452450f509e99mbansal * Return flags returned by createMosaic() are one of the following. 87e1178a73fd5756771d25d0b8375452450f509e99mbansal */ 88e1178a73fd5756771d25d0b8375452450f509e99mbansal public static final int MOSAIC_RET_OK = 1; 89e1178a73fd5756771d25d0b8375452450f509e99mbansal public static final int MOSAIC_RET_ERROR = -1; 90e1178a73fd5756771d25d0b8375452450f509e99mbansal public static final int MOSAIC_RET_CANCELLED = -2; 91dd28e1cc00373c02adf88dff878dbbe5d8be9e59mbansal public static final int MOSAIC_RET_LOW_TEXTURE = -3; 92dd28e1cc00373c02adf88dff878dbbe5d8be9e59mbansal public static final int MOSAIC_RET_FEW_INLIERS = 2; 93dd28e1cc00373c02adf88dff878dbbe5d8be9e59mbansal 94e1178a73fd5756771d25d0b8375452450f509e99mbansal 9581f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen static { 9670a29f182f6696b089d1c376fc5aadd7a20f6231Jun Tian System.loadLibrary("jni_legacymosaic"); 9781f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen } 9881f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen 9981f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen /** 10081f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * Allocate memory for the image frames at the given resolution. 10181f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * 10281f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * @param width width of the input frames in pixels 10381f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * @param height height of the input frames in pixels 10481f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen */ 105b062b806441939e162e19be0baeb6513592c66b3mbansal public native void allocateMosaicMemory(int width, int height); 106b062b806441939e162e19be0baeb6513592c66b3mbansal 107b062b806441939e162e19be0baeb6513592c66b3mbansal /** 108b062b806441939e162e19be0baeb6513592c66b3mbansal * Free memory allocated by allocateMosaicMemory. 109b062b806441939e162e19be0baeb6513592c66b3mbansal * 110b062b806441939e162e19be0baeb6513592c66b3mbansal */ 111b062b806441939e162e19be0baeb6513592c66b3mbansal public native void freeMosaicMemory(); 11281f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen 11381f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen /** 11481f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * Pass the input image frame to the native layer. Each time the a new 11581f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * source image t is set, the transformation matrix from the first source 11681f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * image to t is computed and returned. 11781f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * 11881f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * @param pixels source image of NV21 format. 119dd28e1cc00373c02adf88dff878dbbe5d8be9e59mbansal * @return Float array of length 11; first 9 entries correspond to the 3x3 120dd28e1cc00373c02adf88dff878dbbe5d8be9e59mbansal * transformation matrix between the first frame and the passed frame; 121dd28e1cc00373c02adf88dff878dbbe5d8be9e59mbansal * the 10th entry is the number of the passed frame, where the counting 122dd28e1cc00373c02adf88dff878dbbe5d8be9e59mbansal * starts from 1; and the 11th entry is the returning code, whose value 123dd28e1cc00373c02adf88dff878dbbe5d8be9e59mbansal * is one of those MOSAIC_RET_* returning flags defined above. 12481f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen */ 12581f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen public native float[] setSourceImage(byte[] pixels); 12681f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen 12781f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen /** 12841a2e9735136f372de95652d0828600282c8e967mbansal * This is an alternative to the setSourceImage function above. This should 12941a2e9735136f372de95652d0828600282c8e967mbansal * be called when the image data is already on the native side in a fixed 13041a2e9735136f372de95652d0828600282c8e967mbansal * byte array. In implementation, this array is filled by the GL thread 13141a2e9735136f372de95652d0828600282c8e967mbansal * using glReadPixels directly from GPU memory (where it is accessed by 13241a2e9735136f372de95652d0828600282c8e967mbansal * an associated SurfaceTexture). 13341a2e9735136f372de95652d0828600282c8e967mbansal * 134dd28e1cc00373c02adf88dff878dbbe5d8be9e59mbansal * @return Float array of length 11; first 9 entries correspond to the 3x3 135dd28e1cc00373c02adf88dff878dbbe5d8be9e59mbansal * transformation matrix between the first frame and the passed frame; 136dd28e1cc00373c02adf88dff878dbbe5d8be9e59mbansal * the 10th entry is the number of the passed frame, where the counting 137dd28e1cc00373c02adf88dff878dbbe5d8be9e59mbansal * starts from 1; and the 11th entry is the returning code, whose value 138dd28e1cc00373c02adf88dff878dbbe5d8be9e59mbansal * is one of those MOSAIC_RET_* returning flags defined above. 13941a2e9735136f372de95652d0828600282c8e967mbansal */ 14041a2e9735136f372de95652d0828600282c8e967mbansal public native float[] setSourceImageFromGPU(); 14141a2e9735136f372de95652d0828600282c8e967mbansal 14241a2e9735136f372de95652d0828600282c8e967mbansal /** 14381f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * Set the type of blending. 14481f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * 14581f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * @param type the blending type defined in the class. {BLENDTYPE_FULL, 14681f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * BLENDTYPE_PAN, BLENDTYPE_CYLINDERPAN, BLENDTYPE_HORIZONTAL} 14781f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen */ 14881f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen public native void setBlendingType(int type); 14981f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen 15081f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen /** 151b28b9c0fa991bc97e8aa11da83d27f71fdfef6dambansal * Set the type of strips to use for blending. 152b28b9c0fa991bc97e8aa11da83d27f71fdfef6dambansal * @param type the blending strip type to use {STRIPTYPE_THIN, 153b28b9c0fa991bc97e8aa11da83d27f71fdfef6dambansal * STRIPTYPE_WIDE}. 154b28b9c0fa991bc97e8aa11da83d27f71fdfef6dambansal */ 155b28b9c0fa991bc97e8aa11da83d27f71fdfef6dambansal public native void setStripType(int type); 156b28b9c0fa991bc97e8aa11da83d27f71fdfef6dambansal 157b28b9c0fa991bc97e8aa11da83d27f71fdfef6dambansal /** 15881f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * Tell the native layer to create the final mosaic after all the input frame 15981f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * data have been collected. 16081f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * The case of generating high-resolution mosaic may take dozens of seconds to finish. 16181f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * 16281f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * @param value True means generating a high-resolution mosaic - 16381f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * which is based on the original images set in setSourceImage(). 16481f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * False means generating a low-resolution version - 16581f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * which is based on 1/4 downscaled images from the original images. 166e1178a73fd5756771d25d0b8375452450f509e99mbansal * @return Returns a status code suggesting if the mosaic building was 167e1178a73fd5756771d25d0b8375452450f509e99mbansal * successful, in error, or was cancelled by the user. 16881f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen */ 169e1178a73fd5756771d25d0b8375452450f509e99mbansal public native int createMosaic(boolean value); 17081f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen 17181f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen /** 17281f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * Get the data for the created mosaic. 17381f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * 17481f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * @return Returns an integer array which contains the final mosaic in the ARGB_8888 format. 17581f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * The first MosaicWidth*MosaicHeight values contain the image data, followed by 2 17681f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * integers corresponding to the values MosaicWidth and MosaicHeight respectively. 17781f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen */ 17881f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen public native int[] getFinalMosaic(); 17981f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen 18081f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen /** 18181f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * Get the data for the created mosaic. 18281f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * 18381f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * @return Returns a byte array which contains the final mosaic in the NV21 format. 18481f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * The first MosaicWidth*MosaicHeight*1.5 values contain the image data, followed by 18581f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * 8 bytes which pack the MosaicWidth and MosaicHeight integers into 4 bytes each 18681f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * respectively. 18781f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen */ 18881f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen public native byte[] getFinalMosaicNV21(); 18981f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen 19081f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen /** 19181f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * Reset the state of the frame arrays which maintain the captured frame data. 19281f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen * Also re-initializes the native mosaic object to make it ready for capturing a new mosaic. 19381f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen */ 19481f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen public native void reset(); 19550b3c890986aadb3780b4da8c0b8dbb0f1422ebambansal 19650b3c890986aadb3780b4da8c0b8dbb0f1422ebambansal /** 19750b3c890986aadb3780b4da8c0b8dbb0f1422ebambansal * Get the progress status of the mosaic computation process. 19850b3c890986aadb3780b4da8c0b8dbb0f1422ebambansal * @param hires Boolean flag to select whether to report progress of the 19950b3c890986aadb3780b4da8c0b8dbb0f1422ebambansal * low-res or high-res mosaicer. 200e1178a73fd5756771d25d0b8375452450f509e99mbansal * @param cancelComputation Boolean flag to allow cancelling the 201e1178a73fd5756771d25d0b8375452450f509e99mbansal * mosaic computation when needed from the GUI end. 20250b3c890986aadb3780b4da8c0b8dbb0f1422ebambansal * @return Returns a number from 0-100 where 50 denotes that the mosaic 20350b3c890986aadb3780b4da8c0b8dbb0f1422ebambansal * computation is 50% done. 20450b3c890986aadb3780b4da8c0b8dbb0f1422ebambansal */ 205e1178a73fd5756771d25d0b8375452450f509e99mbansal public native int reportProgress(boolean hires, boolean cancelComputation); 20681f844f803ea2feeb61eb9270fbdd5592620d42eWei-Ta Chen} 207