diff options
Diffstat (limited to 'jni/feature_mos_jni.cpp')
-rw-r--r-- | jni/feature_mos_jni.cpp | 669 |
1 files changed, 0 insertions, 669 deletions
diff --git a/jni/feature_mos_jni.cpp b/jni/feature_mos_jni.cpp deleted file mode 100644 index 0fa792a6b..000000000 --- a/jni/feature_mos_jni.cpp +++ /dev/null @@ -1,669 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* -* - */ -#include <string.h> -#include <jni.h> -#include <stdio.h> -#include <stdlib.h> -#include <time.h> -#include <db_utilities_camera.h> - -#include "mosaic/AlignFeatures.h" -#include "mosaic/Blend.h" -#include "mosaic/Mosaic.h" -#include "mosaic/Log.h" -#define LOG_TAG "FEATURE_MOS_JNI" - -#ifdef __cplusplus -extern "C" { -#endif - -#include "mosaic_renderer_jni.h" - -char buffer[1024]; - -const int MAX_FRAMES = 100; - -static double mTx; - -int tWidth[NR]; -int tHeight[NR]; - -ImageType tImage[NR][MAX_FRAMES];// = {{ImageUtils::IMAGE_TYPE_NOIMAGE}}; // YVU24 format image -Mosaic *mosaic[NR] = {NULL,NULL}; -ImageType resultYVU = ImageUtils::IMAGE_TYPE_NOIMAGE; -ImageType resultBGR = ImageUtils::IMAGE_TYPE_NOIMAGE; -float gTRS[11]; // 9 elements of the transformation, 1 for frame-number, 1 for alignment error code. -// Variables to keep track of the mosaic computation progress for both LR & HR. -float gProgress[NR]; -// Variables to be able to cancel the mosaic computation when the GUI says so. -bool gCancelComputation[NR]; - -int c; -int width=0, height=0; -int mosaicWidth=0, mosaicHeight=0; - -//int blendingType = Blend::BLEND_TYPE_FULL; -//int blendingType = Blend::BLEND_TYPE_CYLPAN; -int blendingType = Blend::BLEND_TYPE_HORZ; -int stripType = Blend::STRIP_TYPE_THIN; -bool high_res = false; -bool quarter_res[NR] = {false,false}; -float thresh_still[NR] = {5.0f,0.0f}; - -/* return current time in milliseconds*/ - -#ifndef now_ms -static double -now_ms(void) -{ - //struct timespec res; - struct timeval res; - //clock_gettime(CLOCK_REALTIME, &res); - gettimeofday(&res, NULL); - return 1000.0*res.tv_sec + (double)res.tv_usec/1e3; -} -#endif - - -static int frame_number_HR = 0; -static int frame_number_LR = 0; - -int Init(int mID, int nmax) -{ - double t0, t1, time_c; - - if(mosaic[mID]!=NULL) - { - delete mosaic[mID]; - mosaic[mID] = NULL; - } - - mosaic[mID] = new Mosaic(); - - t0 = now_ms(); - - // When processing higher than 720x480 video, process low-res at - // quarter resolution - if(tWidth[LR]>180) - quarter_res[LR] = true; - - - // Check for initialization and if not, initialize - if (!mosaic[mID]->isInitialized()) - { - mosaic[mID]->initialize(blendingType, stripType, tWidth[mID], tHeight[mID], - nmax, quarter_res[mID], thresh_still[mID]); - } - - t1 = now_ms(); - time_c = t1 - t0; - LOGV("Init[%d]: %g ms [%d frames]",mID,time_c,nmax); - return 1; -} - -void GenerateQuarterResImagePlanar(ImageType im, int input_w, int input_h, - ImageType &out) -{ - ImageType imp; - ImageType outp; - - int count = 0; - - for (int j = 0; j < input_h; j += H2L_FACTOR) - { - imp = im + j * input_w; - outp = out + (j / H2L_FACTOR) * (input_w / H2L_FACTOR); - - for (int i = 0; i < input_w; i += H2L_FACTOR) - { - *outp++ = *(imp + i); - count++; - } - } - - for (int j = input_h; j < 2 * input_h; j += H2L_FACTOR) - { - imp = im + j * input_w; - outp = out + (j / H2L_FACTOR) * (input_w / H2L_FACTOR); - - for (int i = 0; i < input_w; i += H2L_FACTOR) - { - *outp++ = *(imp + i); - count++; - } - } - - for (int j = 2 * input_h; j < 3 * input_h; j += H2L_FACTOR) - { - imp = im + j * input_w; - outp = out + (j / H2L_FACTOR) * (input_w / H2L_FACTOR); - - for (int i = 0; i < input_w; i += H2L_FACTOR) - { - *outp++ = *(imp + i); - count++; - } - } -} - -int AddFrame(int mID, int k, float* trs1d) -{ - double t0, t1, time_c; - double trs[3][3]; - - int ret_code = mosaic[mID]->addFrame(tImage[mID][k]); - - mosaic[mID]->getAligner()->getLastTRS(trs); - - if(trs1d!=NULL) - { - - trs1d[0] = trs[0][0]; - trs1d[1] = trs[0][1]; - trs1d[2] = trs[0][2]; - trs1d[3] = trs[1][0]; - trs1d[4] = trs[1][1]; - trs1d[5] = trs[1][2]; - trs1d[6] = trs[2][0]; - trs1d[7] = trs[2][1]; - trs1d[8] = trs[2][2]; - } - - return ret_code; -} - -int Finalize(int mID) -{ - double t0, t1, time_c; - - t0 = now_ms(); - // Create the mosaic - int ret = mosaic[mID]->createMosaic(gProgress[mID], gCancelComputation[mID]); - t1 = now_ms(); - time_c = t1 - t0; - LOGV("CreateMosaic: %g ms",time_c); - - // Get back the result - resultYVU = mosaic[mID]->getMosaic(mosaicWidth, mosaicHeight); - - return ret; -} - -void YUV420toYVU24(ImageType yvu24, ImageType yuv420sp, int width, int height) -{ - int frameSize = width * height; - - ImageType oyp = yvu24; - ImageType ovp = yvu24+frameSize; - ImageType oup = yvu24+frameSize+frameSize; - - for (int j = 0, yp = 0; j < height; j++) - { - unsigned char u = 0, v = 0; - int uvp = frameSize + (j >> 1) * width; - for (int i = 0; i < width; i++, yp++) - { - *oyp++ = yuv420sp[yp]; - //int y = (0xff & (int)yuv420sp[yp]) -16; - //yvu24p[yp] = (y<0)?0:y; - - if ((i & 1) == 0) - { - v = yuv420sp[uvp++]; - u = yuv420sp[uvp++]; - } - - *ovp++ = v; - *oup++ = u; - } - } -} - -void YUV420toYVU24_NEW(ImageType yvu24, ImageType yuv420sp, int width, - int height) -{ - int frameSize = width * height; - - ImageType oyp = yvu24; - ImageType ovp = yvu24 + frameSize; - ImageType oup = yvu24 + frameSize + frameSize; - - memcpy(yvu24, yuv420sp, frameSize * sizeof(unsigned char)); - - for (int j = 0; j < height; j += 2) - { - unsigned char u = 0, v = 0; - int uvp = frameSize + (j >> 1) * width; - ovp = yvu24 + frameSize + j * width; - oup = ovp + frameSize; - - ImageType iuvp = yuv420sp + uvp; - - for (int i = 0; i < width; i += 2) - { - v = *iuvp++; - u = *iuvp++; - - *ovp++ = v; - *oup++ = u; - - *ovp++ = v; - *oup++ = u; - - } - memcpy(ovp, ovp - width, width * sizeof(unsigned char)); - memcpy(oup, oup - width, width * sizeof(unsigned char)); - } -} - - -JNIEXPORT void JNICALL Java_com_android_camera_Mosaic_allocateMosaicMemory( - JNIEnv* env, jobject thiz, jint width, jint height) -{ - tWidth[HR] = width; - tHeight[HR] = height; - tWidth[LR] = int(width / H2L_FACTOR); - tHeight[LR] = int(height / H2L_FACTOR); - - for(int i=0; i<MAX_FRAMES; i++) - { - tImage[LR][i] = ImageUtils::allocateImage(tWidth[LR], tHeight[LR], - ImageUtils::IMAGE_TYPE_NUM_CHANNELS); - tImage[HR][i] = ImageUtils::allocateImage(tWidth[HR], tHeight[HR], - ImageUtils::IMAGE_TYPE_NUM_CHANNELS); - } - - AllocateTextureMemory(tWidth[HR], tHeight[HR], tWidth[LR], tHeight[LR]); -} - -JNIEXPORT void JNICALL Java_com_android_camera_Mosaic_freeMosaicMemory( - JNIEnv* env, jobject thiz) -{ - for(int i = 0; i < MAX_FRAMES; i++) - { - ImageUtils::freeImage(tImage[LR][i]); - ImageUtils::freeImage(tImage[HR][i]); - } - - FreeTextureMemory(); -} - - -void decodeYUV444SP(unsigned char* rgb, unsigned char* yuv420sp, int width, - int height) -{ - int frameSize = width * height; - - for (int j = 0, yp = 0; j < height; j++) - { - int vp = frameSize + j * width, u = 0, v = 0; - int up = vp + frameSize; - - for (int i = 0; i < width; i++, yp++, vp++, up++) - { - int y = (0xff & ((int) yuv420sp[yp])) - 16; - if (y < 0) y = 0; - - v = (0xff & yuv420sp[vp]) - 128; - u = (0xff & yuv420sp[up]) - 128; - - int y1192 = 1192 * y; - int r = (y1192 + 1634 * v); - int g = (y1192 - 833 * v - 400 * u); - int b = (y1192 + 2066 * u); - - if (r < 0) r = 0; else if (r > 262143) r = 262143; - if (g < 0) g = 0; else if (g > 262143) g = 262143; - if (b < 0) b = 0; else if (b > 262143) b = 262143; - - //rgb[yp] = 0xff000000 | ((r << 6) & 0xff0000) | ((g >> 2) & 0xff00) | ((b >> 10) & 0xff); - int p = j*width*3+i*3; - rgb[p+0] = (r<<6 & 0xFF0000)>>16; - rgb[p+1] = (g>>2 & 0xFF00)>>8; - rgb[p+2] = b>>10 & 0xFF; - } - } -} - -static int count = 0; - -void ConvertYVUAiToPlanarYVU(unsigned char *planar, unsigned char *in, int width, - int height) -{ - int planeSize = width * height; - unsigned char* Yptr = planar; - unsigned char* Vptr = planar + planeSize; - unsigned char* Uptr = Vptr + planeSize; - - for (int i = 0; i < planeSize; i++) - { - *Yptr++ = *in++; - *Vptr++ = *in++; - *Uptr++ = *in++; - in++; // Alpha - } -} - -JNIEXPORT jfloatArray JNICALL Java_com_android_camera_Mosaic_setSourceImageFromGPU( - JNIEnv* env, jobject thiz) -{ - double t0, t1, time_c; - t0 = now_ms(); - int ret_code = Mosaic::MOSAIC_RET_OK; - - if(frame_number_HR<MAX_FRAMES && frame_number_LR<MAX_FRAMES) - { - double last_tx = mTx; - - sem_wait(&gPreviewImage_semaphore); - ConvertYVUAiToPlanarYVU(tImage[LR][frame_number_LR], gPreviewImage[LR], - tWidth[LR], tHeight[LR]); - - sem_post(&gPreviewImage_semaphore); - - ret_code = AddFrame(LR, frame_number_LR, gTRS); - - if(ret_code == Mosaic::MOSAIC_RET_OK || ret_code == Mosaic::MOSAIC_RET_FEW_INLIERS) - { - // Copy into HR buffer only if this is a valid frame - sem_wait(&gPreviewImage_semaphore); - ConvertYVUAiToPlanarYVU(tImage[HR][frame_number_HR], gPreviewImage[HR], - tWidth[HR], tHeight[HR]); - sem_post(&gPreviewImage_semaphore); - - frame_number_LR++; - frame_number_HR++; - } - } - else - { - gTRS[1] = gTRS[2] = gTRS[3] = gTRS[5] = gTRS[6] = gTRS[7] = 0.0f; - gTRS[0] = gTRS[4] = gTRS[8] = 1.0f; - } - - UpdateWarpTransformation(gTRS); - - gTRS[9] = frame_number_HR; - gTRS[10] = ret_code; - - jfloatArray bytes = env->NewFloatArray(11); - if(bytes != 0) - { - env->SetFloatArrayRegion(bytes, 0, 11, (jfloat*) gTRS); - } - return bytes; -} - - - -JNIEXPORT jfloatArray JNICALL Java_com_android_camera_Mosaic_setSourceImage( - JNIEnv* env, jobject thiz, jbyteArray photo_data) -{ - double t0, t1, time_c; - t0 = now_ms(); - - int ret_code = Mosaic::MOSAIC_RET_OK; - - if(frame_number_HR<MAX_FRAMES && frame_number_LR<MAX_FRAMES) - { - jbyte *pixels = env->GetByteArrayElements(photo_data, 0); - - YUV420toYVU24_NEW(tImage[HR][frame_number_HR], (ImageType)pixels, - tWidth[HR], tHeight[HR]); - - env->ReleaseByteArrayElements(photo_data, pixels, 0); - - double last_tx = mTx; - - t0 = now_ms(); - GenerateQuarterResImagePlanar(tImage[HR][frame_number_HR], tWidth[HR], - tHeight[HR], tImage[LR][frame_number_LR]); - - - sem_wait(&gPreviewImage_semaphore); - decodeYUV444SP(gPreviewImage[LR], tImage[LR][frame_number_LR], - gPreviewImageWidth[LR], gPreviewImageHeight[LR]); - sem_post(&gPreviewImage_semaphore); - - ret_code = AddFrame(LR, frame_number_LR, gTRS); - - if(ret_code == Mosaic::MOSAIC_RET_OK || ret_code == Mosaic::MOSAIC_RET_FEW_INLIERS) - { - frame_number_LR++; - frame_number_HR++; - } - - } - else - { - gTRS[1] = gTRS[2] = gTRS[3] = gTRS[5] = gTRS[6] = gTRS[7] = 0.0f; - gTRS[0] = gTRS[4] = gTRS[8] = 1.0f; - } - - UpdateWarpTransformation(gTRS); - - gTRS[9] = frame_number_HR; - gTRS[10] = ret_code; - - jfloatArray bytes = env->NewFloatArray(11); - if(bytes != 0) - { - env->SetFloatArrayRegion(bytes, 0, 11, (jfloat*) gTRS); - } - return bytes; -} - -JNIEXPORT void JNICALL Java_com_android_camera_Mosaic_setBlendingType( - JNIEnv* env, jobject thiz, jint type) -{ - blendingType = int(type); -} - -JNIEXPORT void JNICALL Java_com_android_camera_Mosaic_setStripType( - JNIEnv* env, jobject thiz, jint type) -{ - stripType = int(type); -} - -JNIEXPORT void JNICALL Java_com_android_camera_Mosaic_reset( - JNIEnv* env, jobject thiz) -{ - frame_number_HR = 0; - frame_number_LR = 0; - - gProgress[LR] = 0.0; - gProgress[HR] = 0.0; - - gCancelComputation[LR] = false; - gCancelComputation[HR] = false; - - Init(LR,MAX_FRAMES); -} - -JNIEXPORT jint JNICALL Java_com_android_camera_Mosaic_reportProgress( - JNIEnv* env, jobject thiz, jboolean hires, jboolean cancel_computation) -{ - if(bool(hires)) - gCancelComputation[HR] = cancel_computation; - else - gCancelComputation[LR] = cancel_computation; - - if(bool(hires)) - return (jint) gProgress[HR]; - else - return (jint) gProgress[LR]; -} - -JNIEXPORT jint JNICALL Java_com_android_camera_Mosaic_createMosaic( - JNIEnv* env, jobject thiz, jboolean value) -{ - high_res = bool(value); - - int ret; - - if(high_res) - { - LOGV("createMosaic() - High-Res Mode"); - double t0, t1, time_c; - - gProgress[HR] = 0.0; - t0 = now_ms(); - - Init(HR, frame_number_HR); - - for(int k = 0; k < frame_number_HR; k++) - { - if (gCancelComputation[HR]) - break; - AddFrame(HR, k, NULL); - gProgress[HR] += TIME_PERCENT_ALIGN/frame_number_HR; - } - - if (gCancelComputation[HR]) - { - ret = Mosaic::MOSAIC_RET_CANCELLED; - } - else - { - gProgress[HR] = TIME_PERCENT_ALIGN; - - t1 = now_ms(); - time_c = t1 - t0; - LOGV("AlignAll - %d frames [HR]: %g ms", frame_number_HR, time_c); - - ret = Finalize(HR); - - gProgress[HR] = 100.0; - } - - high_res = false; - } - else - { - LOGV("createMosaic() - Low-Res Mode"); - gProgress[LR] = TIME_PERCENT_ALIGN; - - ret = Finalize(LR); - - gProgress[LR] = 100.0; - } - - return (jint) ret; -} - -JNIEXPORT jintArray JNICALL Java_com_android_camera_Mosaic_getFinalMosaic( - JNIEnv* env, jobject thiz) -{ - int y,x; - int width = mosaicWidth; - int height = mosaicHeight; - int imageSize = width * height; - - // Convert back to RGB24 - resultBGR = ImageUtils::allocateImage(mosaicWidth, mosaicHeight, - ImageUtils::IMAGE_TYPE_NUM_CHANNELS); - ImageUtils::yvu2bgr(resultBGR, resultYVU, mosaicWidth, mosaicHeight); - - LOGV("MosBytes: %d, W = %d, H = %d", imageSize, width, height); - - int* image = new int[imageSize]; - int* dims = new int[2]; - - for(y=0; y<height; y++) - { - for(x=0; x<width; x++) - { - image[y*width+x] = (0xFF<<24) | (resultBGR[y*width*3+x*3+2]<<16)| - (resultBGR[y*width*3+x*3+1]<<8)| (resultBGR[y*width*3+x*3]); - } - } - - dims[0] = width; - dims[1] = height; - - ImageUtils::freeImage(resultBGR); - - jintArray bytes = env->NewIntArray(imageSize+2); - if (bytes == 0) { - LOGE("Error in creating the image."); - delete[] image; - return 0; - } - env->SetIntArrayRegion(bytes, 0, imageSize, (jint*) image); - env->SetIntArrayRegion(bytes, imageSize, 2, (jint*) dims); - delete[] image; - delete[] dims; - return bytes; -} - -JNIEXPORT jbyteArray JNICALL Java_com_android_camera_Mosaic_getFinalMosaicNV21( - JNIEnv* env, jobject thiz) -{ - int y,x; - int width; - int height; - - width = mosaicWidth; - height = mosaicHeight; - - int imageSize = 1.5*width * height; - - // Convert YVU to NV21 format in-place - ImageType V = resultYVU+mosaicWidth*mosaicHeight; - ImageType U = V+mosaicWidth*mosaicHeight; - for(int j=0; j<mosaicHeight/2; j++) - { - for(int i=0; i<mosaicWidth; i+=2) - { - V[j*mosaicWidth+i] = V[(2*j)*mosaicWidth+i]; // V - V[j*mosaicWidth+i+1] = U[(2*j)*mosaicWidth+i]; // U - } - } - - LOGV("MosBytes: %d, W = %d, H = %d", imageSize, width, height); - - unsigned char* dims = new unsigned char[8]; - - dims[0] = (unsigned char)(width >> 24); - dims[1] = (unsigned char)(width >> 16); - dims[2] = (unsigned char)(width >> 8); - dims[3] = (unsigned char)width; - - dims[4] = (unsigned char)(height >> 24); - dims[5] = (unsigned char)(height >> 16); - dims[6] = (unsigned char)(height >> 8); - dims[7] = (unsigned char)height; - - jbyteArray bytes = env->NewByteArray(imageSize+8); - if (bytes == 0) { - LOGE("Error in creating the image."); - ImageUtils::freeImage(resultYVU); - return 0; - } - env->SetByteArrayRegion(bytes, 0, imageSize, (jbyte*) resultYVU); - env->SetByteArrayRegion(bytes, imageSize, 8, (jbyte*) dims); - delete[] dims; - ImageUtils::freeImage(resultYVU); - return bytes; -} - -#ifdef __cplusplus -} -#endif |