extern "C" JNIEXPORT jint JNICALL Java_com_almalence_plugins_processing_night_AlmaShotNight_Process ( JNIEnv* env, jobject thiz, jint sx, jint sy, jint sxo, jint syo, jint iso, jint noisePref, jint DeGhostPref, jint lumaEnh, jint chromaEnh, jint nImages, jintArray jcrop, jint orientation, jboolean mirror, jfloat zoom, jint cameraIndex, jboolean isHALv3 ) { Uint8 *OutPic, *OutNV21; int *crop; int nTable[3] = {256/2, 256, 3*256/2}; int deghostTable[3] = {3*256/4, 256, 3*256/2}; crop = (int*)env->GetIntArrayElements(jcrop, NULL); if (isHALv3) { //__android_log_print(ANDROID_LOG_ERROR, "Almalence", "sx:%d sy:%d sxo:%d syo:%d", sx, sy, sxo, syo); // find zoomed region in the frame int sx_zoom = (int)(sx/zoom) + 2*SIZE_GUARANTEE_BORDER; int sy_zoom = (int)(sy/zoom) + 2*SIZE_GUARANTEE_BORDER; sx_zoom -= sx_zoom&3; sy_zoom -= sy_zoom&3; if (sx_zoom > sx) sx_zoom = sx; if (sy_zoom > sy) sy_zoom = sy; // in-place crop of input frames according to the zoom value if ((sx_zoom < sx) || (sy_zoom < sy)) { int x0 = (sx-sx_zoom)/2; int y0 = (sy-sy_zoom)/2; x0 -= x0&1; y0 -= y0&1; for (int i=0; i<nImages; ++i) { // Y part for (int y=0; y<sy_zoom; ++y) memmove(&yuv[i][y*sx_zoom], &yuv[i][x0+(y+y0)*sx], sx_zoom); // UV part for (int y=0; y<sy_zoom/2; ++y) memmove(&yuv[i][sx_zoom*sy_zoom+y*sx_zoom], &yuv[i][sx*sy+x0+(y+y0/2)*sx], sx_zoom); } } int gamma = (int)(0.5f/*fgamma*/ * 256 + 0.5f); // threshold at which profiles are switched (about 1.5x zoom) int zoomAbove15x = sxo >= 3*(sx_zoom-2*SIZE_GUARANTEE_BORDER)/2; int zoomAbove30x = sxo >= 3*sx_zoom; int sensorGain, filter, sharpen; if (cameraIndex == 100) // Nexus 5 { sensorGain = (int)( 256*powf((float)iso/100, 0.5f) ); // slightly more sharpening and less filtering at low zooms sharpen = 2; filter = 384; // 320; // 256; if (zoomAbove30x) sharpen = 0x80; // fine edge enhancement instead of primitive sharpen else if (zoomAbove15x) sharpen = 1; else filter = 192; } else // 103 = Nexus 6 { sensorGain = (int)( 170*256/100*powf((float)iso/100, 0.5f) ); sharpen = 1; filter = 256; if (zoomAbove30x) sharpen = 0x80; // fine edge enhancement instead of primitive sharpen if (!zoomAbove15x) filter = 320; // slightly more filtering at low zooms (noise interpolation artefacts are evident otherwise) } Super_Process( yuv, &OutPic, sx_zoom, sy_zoom, sxo, syo, nImages, sensorGain, deghostTable[DeGhostPref], 1, // deghostFrames filter, sharpen, gamma, cameraIndex, 0); // externalBuffers //__android_log_print(ANDROID_LOG_ERROR, "Almalence", "Super_Process finished, iso: %d, noise: %d %d", iso, noisePref, nTable[noisePref]); crop[0]=crop[1]=0; crop[2]=sxo; crop[3]=syo; } else { BlurLess_Preview(&instance, yuv, NULL, NULL, NULL, 0, // 256*3, deghostTable[DeGhostPref], 1, 2, nImages, sx, sy, 0, nTable[noisePref], 1, 0, lumaEnh, chromaEnh, 0); crop[0]=crop[1]=crop[2]=crop[3]=-1; BlurLess_Process(instance, &OutPic, &crop[0], &crop[1], &crop[2], &crop[3]); } //__android_log_print(ANDROID_LOG_ERROR, "Almalence", "Before rotation"); int flipLeftRight, flipUpDown; int rotate90 = orientation == 90 || orientation == 270; if (mirror) flipUpDown = flipLeftRight = orientation == 180 || orientation == 90; else flipUpDown = flipLeftRight = orientation == 180 || orientation == 270; // 90/270-degree rotations are out-ot-place OutNV21 = OutPic; if (rotate90) OutNV21 = (Uint8 *)malloc(sx*sy+2*((sx+1)/2)*((sy+1)/2)); TransformNV21(OutPic, OutNV21, sx, sy, crop, flipLeftRight, flipUpDown, rotate90); //__android_log_print(ANDROID_LOG_ERROR, "Almalence", "After rotation"); if (rotate90) { free(OutPic); OutPic = OutNV21; } env->ReleaseIntArrayElements(jcrop, (jint*)crop, JNI_ABORT); return (jint)OutPic; }
extern "C" JNIEXPORT jint JNICALL Java_com_zihuatanejo_finalcamera_plugins_processing_night_AlmaShotNight_Process ( JNIEnv* env, jobject thiz, jint sx, jint sy, jint sxo, jint syo, jint iso, jint noisePref, jint DeGhostPref, jint lumaEnh, jint chromaEnh, jfloat fgamma, jint nImages, jintArray jcrop, jint orientation, jboolean mirror, jfloat zoom, jint cameraIndex, jboolean isCamera2 ) { Uint8 *OutPic, *OutNV21; int *crop; int nTable[3] = {256/2, 256, 3*256/2}; int deghostTable[3] = {3*256/4, 256, 3*256/2}; crop = (int*)env->GetIntArrayElements(jcrop, NULL); if (isCamera2) { //__android_log_print(ANDROID_LOG_ERROR, "Almalence", "sx:%d sy:%d sxo:%d syo:%d", sx, sy, sxo, syo); // find zoomed region in the frame int sx_zoom = (int)(sx/zoom) + 2*SIZE_GUARANTEE_BORDER; int sy_zoom = (int)(sy/zoom) + 2*SIZE_GUARANTEE_BORDER; sx_zoom -= sx_zoom&3; sy_zoom -= sy_zoom&3; if (sx_zoom > sx) sx_zoom = sx; if (sy_zoom > sy) sy_zoom = sy; // in-place crop of input frames according to the zoom value if ((sx_zoom < sx) || (sy_zoom < sy)) { int x0 = (sx-sx_zoom)/2; int y0 = (sy-sy_zoom)/2; x0 -= x0&1; y0 -= y0&1; for (int i=0; i<nImages; ++i) { // Y part for (int y=0; y<sy_zoom; ++y) memmove(&yuv[i][y*sx_zoom], &yuv[i][x0+(y+y0)*sx], sx_zoom); // UV part for (int y=0; y<sy_zoom/2; ++y) memmove(&yuv[i][sx_zoom*sy_zoom+y*sx_zoom], &yuv[i][sx*sy+x0+(y+y0/2)*sx], sx_zoom); } } if (fgamma && (iso>0)) { // iso 100 = +0.1 // iso 800 = -0.05 fgamma += 0.1f - ( logf(iso) * 3.321928095f-6.644f)*0.15f/3.f; if (fgamma < 0.45f) fgamma = 0.45f; if (fgamma > 0.6f) fgamma = 0.6f; } // for SR-only fgamma = 0, gamma will evaluate to 0 also int gamma = (int)(fgamma * 256 + 0.5f); // threshold at which profiles are switched (about 1.5x zoom) int zoomAbove15x = sxo >= 3*(sx_zoom-2*SIZE_GUARANTEE_BORDER)/2; int zoomAbove30x = sxo >= 3*sx_zoom; int sensorGain, deGhostGain, filter, sharpen; switch (cameraIndex) { case 100: // Nexus 5 deGhostGain = 256*80/100; sensorGain = (int)( 256*powf((float)iso/100, 0.5f) ); // slightly more sharpening and less filtering at low zooms sharpen = 2; filter = 384; // 320; // 256; if (zoomAbove30x) sharpen = 0x80; // fine edge enhancement instead of primitive sharpen at high zoom levels else if (zoomAbove15x) sharpen = 1; else filter = 192; break; case 103: // Nexus 6 deGhostGain = 256*50/100; sensorGain = (int)( 107*256/100*powf((float)iso/100, 0.7f) ); sharpen = 1; if (!zoomAbove15x) sharpen = 0x80; // slightly more filtering at low zooms (noise interpolation artefacts are evident otherwise) filter = 256; break; case 105: // Nexus 5X case 106: // Nexus 6P deGhostGain = (256 * (60 - 0.015f * iso) / 100); if (deGhostGain < 56) deGhostGain = 56; sensorGain = (int)(1.7f * 256 * powf(((float)iso) / 100, 0.45f)); sharpen = 2; if (zoomAbove30x) sharpen = 0x80;// fine edge enhancement instead of primitive sharpen at high zoom levels if (zoomAbove15x) filter = 256; else filter = 192; break; case 507: // LG G Flex2 deGhostGain = 256*60/100; sensorGain = (int)( 2*256*powf((float)iso/100, 0.45f) ); sharpen = 1; if (zoomAbove30x) sharpen = 0x80;// fine edge enhancement instead of primitive sharpen at high zoom levels filter = 300; if (!zoomAbove15x) filter = 192;// slightly less filtering at low zooms (somehow sr processing is creating less sharp images here) break; case 2000:// OnePlus 2 deGhostGain = (256 * (50 - 0.01f * iso) / 100); if (deGhostGain < 54) deGhostGain = 54; sensorGain = (int)(1.4f * 256 * powf(((float)iso) / 100, 0.45f)); sharpen = 1; if (zoomAbove30x) sharpen = 0x80;// fine edge enhancement instead of primitive sharpen at high zoom levels filter = 256; if (zoomAbove15x) filter = 160; break; default: __android_log_print(ANDROID_LOG_INFO, "CameraTest", "Error: Unknown camera"); break; } if (zoomAbove30x) sharpen = 0x80; // fine edge enhancement instead of primitive sharpen at high zoom levels //__android_log_print(ANDROID_LOG_ERROR, "Almalence", "Before Super_Process, sensorGain: %d, deghostGain: %d, filter: %d, sharpen: %d, nImages: %d cameraIndex: %d", // sensorGain, deGhostGain, filter, sharpen, nImages, cameraIndex); int err = Super_Process( yuv, NULL, &OutPic, sx_zoom, sy_zoom, sx_zoom, sxo, syo, nImages, sensorGain, deGhostGain*deghostTable[DeGhostPref]/256, 1, // deghostFrames filter, sharpen, gamma, cameraIndex, 0); // externalBuffers //__android_log_print(ANDROID_LOG_ERROR, "Almalence", "Super_Process finished, iso: %d, noise: %d %d", iso, noisePref, nTable[noisePref]); __android_log_print(ANDROID_LOG_INFO, "Almalence", "super processing finished, result code: %d", err); crop[0]=crop[1]=0; crop[2]=sxo; crop[3]=syo; } else { BlurLess_Preview(&instance, yuv, NULL, NULL, NULL, 0, // 256*3, deghostTable[DeGhostPref], 1, 2, nImages, sx, sy, 0, nTable[noisePref], 1, 0, lumaEnh, chromaEnh, 0); crop[0]=crop[1]=crop[2]=crop[3]=-1; BlurLess_Process(instance, &OutPic, &crop[0], &crop[1], &crop[2], &crop[3]); } int flipLeftRight, flipUpDown; int rotate90 = orientation == 90 || orientation == 270; if (mirror) flipUpDown = flipLeftRight = orientation == 180 || orientation == 90; else flipUpDown = flipLeftRight = orientation == 180 || orientation == 270; // 90/270-degree rotations are out-ot-place OutNV21 = OutPic; if (rotate90) OutNV21 = (Uint8 *)malloc(sxo*syo+2*((sxo+1)/2)*((syo+1)/2)); TransformNV21(OutPic, OutNV21, sxo, syo, crop, flipLeftRight, flipUpDown, rotate90); if (rotate90) { free(OutPic); OutPic = OutNV21; } env->ReleaseIntArrayElements(jcrop, (jint*)crop, JNI_ABORT); return (jint)OutPic; }