diff options
-rw-r--r-- | jni/feature_mos/src/mosaic/Blend.cpp | 37 | ||||
-rw-r--r-- | jni/feature_mos/src/mosaic/Blend.h | 5 | ||||
-rwxr-xr-x | src/com/android/camera/panorama/PanoramaActivity.java | 13 |
3 files changed, 51 insertions, 4 deletions
diff --git a/jni/feature_mos/src/mosaic/Blend.cpp b/jni/feature_mos/src/mosaic/Blend.cpp index 18972ee..cce89ff 100644 --- a/jni/feature_mos/src/mosaic/Blend.cpp +++ b/jni/feature_mos/src/mosaic/Blend.cpp @@ -226,14 +226,25 @@ int Blend::runBlend(MosaicFrame **oframes, MosaicFrame **rframes, yTopMost = max(0, max(yTopCorners[0], yTopCorners[1]) - fullRect.top + 1); yBottomMost = min(Mheight - 1, min(yBottomCorners[0], yBottomCorners[1]) - fullRect.top - 1); + if (xRightMost <= xLeftMost || yBottomMost <= yTopMost) + { + LOGE("RunBlend: aborting -consistency check failed," + "(xLeftMost, xRightMost, yTopMost, yBottomMost): (%d, %d, %d, %d)", + xLeftMost, xRightMost, yTopMost, yBottomMost); + return BLEND_RET_ERROR; + } + // Make sure image width is multiple of 4 Mwidth = (unsigned short) ((Mwidth + 3) & ~3); Mheight = (unsigned short) ((Mheight + 3) & ~3); // Round up. - if (Mwidth < width || Mheight < height || xRightMost <= xLeftMost) + ret = MosaicSizeCheck(LIMIT_SIZE_MULTIPLIER, LIMIT_HEIGHT_MULTIPLIER); + if (ret != BLEND_RET_OK) { - LOGE("RunBlend: aborting - consistency check failed, w=%d, h=%d, xLeftMost=%d, xRightMost=%d", Mwidth, Mheight, xLeftMost, xRightMost); - return BLEND_RET_ERROR; + LOGE("RunBlend: aborting - mosaic size check failed, " + "(frame_width, frame_height) vs (mosaic_width, mosaic_height): " + "(%d, %d) vs (%d, %d)", width, height, Mwidth, Mheight); + return ret; } LOGI("Allocate mosaic image for blending - size: %d x %d", Mwidth, Mheight); @@ -296,6 +307,26 @@ int Blend::runBlend(MosaicFrame **oframes, MosaicFrame **rframes, return ret; } +int Blend::MosaicSizeCheck(float sizeMultiplier, float heightMultiplier) { + if (Mwidth < width || Mheight < height) { + return BLEND_RET_ERROR; + } + + if ((Mwidth * Mheight) > (width * height * sizeMultiplier)) { + return BLEND_RET_ERROR; + } + + // We won't do blending for the cases where users swing the device too much + // in the secondary direction. We use a short side to determine the + // secondary direction because users may hold the device in landsape + // or portrait. + int shortSide = min(Mwidth, Mheight); + if (shortSide > height * heightMultiplier) { + return BLEND_RET_ERROR; + } + + return BLEND_RET_OK; +} int Blend::FillFramePyramid(MosaicFrame *mb) { diff --git a/jni/feature_mos/src/mosaic/Blend.h b/jni/feature_mos/src/mosaic/Blend.h index 80bb577..ebb3bdc 100644 --- a/jni/feature_mos/src/mosaic/Blend.h +++ b/jni/feature_mos/src/mosaic/Blend.h @@ -113,6 +113,11 @@ protected: int PerformFinalBlending(YUVinfo &imgMos, MosaicRect &cropping_rect); void CropFinalMosaic(YUVinfo &imgMos, MosaicRect &cropping_rect); + +private: + static const float LIMIT_SIZE_MULTIPLIER = 5.0f * 2.0f; + static const float LIMIT_HEIGHT_MULTIPLIER = 2.5f; + int MosaicSizeCheck(float sizeMultiplier, float heightMultiplier); }; #endif diff --git a/src/com/android/camera/panorama/PanoramaActivity.java b/src/com/android/camera/panorama/PanoramaActivity.java index 8b9c65a..a65d263 100755 --- a/src/com/android/camera/panorama/PanoramaActivity.java +++ b/src/com/android/camera/panorama/PanoramaActivity.java @@ -989,9 +989,20 @@ public class PanoramaActivity extends ActivityBase implements keepScreenOnAwhile(); } + /** + * Generate the final mosaic image. + * + * @param highRes flag to indicate whether we want to get a high-res version. + * @return a MosaicJpeg with its isValid flag set to true if successful; null if the generation + * process is cancelled; and a MosaicJpeg with its isValid flag set to false if there + * is an error in generating the final mosaic. + */ public MosaicJpeg generateFinalMosaic(boolean highRes) { - if (mMosaicFrameProcessor.createMosaic(highRes) == Mosaic.MOSAIC_RET_CANCELLED) { + int mosaicReturnCode = mMosaicFrameProcessor.createMosaic(highRes); + if (mosaicReturnCode == Mosaic.MOSAIC_RET_CANCELLED) { return null; + } else if (mosaicReturnCode == Mosaic.MOSAIC_RET_ERROR) { + return new MosaicJpeg(); } byte[] imageData = mMosaicFrameProcessor.getFinalMosaicNV21(); |