PageRenderTime 49ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/jni/hdrprocessing/almashot-hdr.cpp

https://gitlab.com/adam.lukaitis/OpenCamera
C++ | 551 lines | 326 code | 102 blank | 123 comment | 42 complexity | dafb11ae109539e482e6fdbffeb95f82 MD5 | raw file
  1. /*
  2. The contents of this file are subject to the Mozilla Public License
  3. Version 1.1 (the "License"); you may not use this file except in
  4. compliance with the License. You may obtain a copy of the License at
  5. http://www.mozilla.org/MPL/
  6. Software distributed under the License is distributed on an "AS IS"
  7. basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
  8. License for the specific language governing rights and limitations
  9. under the License.
  10. The Original Code is collection of files collectively known as Open Camera.
  11. The Initial Developer of the Original Code is Almalence Inc.
  12. Portions created by Initial Developer are Copyright (C) 2013
  13. by Almalence Inc. All Rights Reserved.
  14. */
  15. #include <stdio.h>
  16. #include <string.h>
  17. #include <jni.h>
  18. #include <android/log.h>
  19. #include "ImageConversionUtils.h"
  20. #include "almashot.h"
  21. #include "hdr.h"
  22. #define MAX_HDR_FRAMES 4
  23. static unsigned char *yuv[MAX_HDR_FRAMES] = {NULL, NULL, NULL, NULL};
  24. static void *instance = NULL;
  25. static int almashot_inited = 0;
  26. static Uint8 *OutPic = NULL;
  27. // This triggers openmp constructors and destructors to be called upon library load/unload
  28. void __attribute__((constructor)) initialize_openmp() {}
  29. void __attribute__((destructor)) release_openmp() {}
  30. extern "C" JNIEXPORT jstring JNICALL Java_com_almalence_plugins_processing_hdr_AlmaShotHDR_Initialize
  31. (
  32. JNIEnv* env,
  33. jobject thiz
  34. )
  35. {
  36. char status[1024];
  37. int err=0;
  38. if (almashot_inited == 0)
  39. {
  40. err = AlmaShot_Initialize(0);
  41. if (err == 0)
  42. almashot_inited = 1;
  43. }
  44. sprintf (status, " err: %d\n", err);
  45. return env->NewStringUTF(status);
  46. }
  47. extern "C" JNIEXPORT jint JNICALL Java_com_almalence_plugins_processing_hdr_AlmaShotHDR_Release
  48. (
  49. JNIEnv*,
  50. jobject
  51. )
  52. {
  53. int i;
  54. if (almashot_inited == 1)
  55. {
  56. AlmaShot_Release();
  57. almashot_inited = 0;
  58. }
  59. return 0;
  60. }
  61. // this is a very common operation - use ImageConversion jni interface instead (? - need to avoid global yuv array then?)
  62. extern "C" JNIEXPORT jstring JNICALL Java_com_almalence_plugins_processing_hdr_AlmaShotHDR_HDRConvertFromJpeg
  63. (
  64. JNIEnv* env,
  65. jobject thiz,
  66. jintArray in,
  67. jintArray in_len,
  68. jint nFrames,
  69. jint sx,
  70. jint sy
  71. )
  72. {
  73. int i;
  74. int *jpeg_length;
  75. unsigned char * *jpeg;
  76. char status[1024];
  77. Uint8 *inp[4];
  78. int x, y;
  79. int x0_out, y0_out, w_out, h_out;
  80. jpeg = (unsigned char**)env->GetIntArrayElements(in, NULL);
  81. jpeg_length = (int*)env->GetIntArrayElements(in_len, NULL);
  82. DecodeAndRotateMultipleJpegs(yuv, jpeg, jpeg_length, sx, sy, nFrames, 0, 0, 0, true);
  83. env->ReleaseIntArrayElements(in, (jint*)jpeg, JNI_ABORT);
  84. env->ReleaseIntArrayElements(in_len, (jint*)jpeg_length, JNI_ABORT);
  85. //sprintf (status, "frames total: %d\nsize0: %d\nsize1: %d\nsize2: %d\n", (int)nFrames, jpeg_length[0], jpeg_length[1], jpeg_length[2]);
  86. sprintf (status, "frames total: %d\n", (int)nFrames);
  87. return env->NewStringUTF(status);
  88. }
  89. extern "C" JNIEXPORT jstring JNICALL Java_com_almalence_plugins_processing_hdr_AlmaShotHDR_HDRAddYUVFrames
  90. (
  91. JNIEnv* env,
  92. jobject thiz,
  93. jintArray in,
  94. jint nFrames,
  95. jint sx,
  96. jint sy
  97. )
  98. {
  99. int i;
  100. unsigned char * *yuvIn;
  101. char status[1024];
  102. // Uint8 *inp[4];
  103. // int x, y;
  104. // int x0_out, y0_out, w_out, h_out;
  105. yuvIn = (unsigned char**)env->GetIntArrayElements(in, NULL);
  106. // __android_log_print(ANDROID_LOG_ERROR, "CameraTest", "START INPUT SAVE");
  107. // for (int i=0; i<nFrames; ++i)
  108. // {
  109. // char str[256];
  110. // sprintf(str, "/sdcard/DCIM/hdrin%02d.yuv", i);
  111. // FILE *f = fopen (str, "wb");
  112. // fwrite(yuvIn[i], sx*sy+2*((sx+1)/2)*((sy+1)/2), 1, f);
  113. // fclose(f);
  114. // }
  115. // __android_log_print(ANDROID_LOG_ERROR, "CameraTest", "INPUT SAVCED");
  116. // pre-allocate uncompressed yuv buffers
  117. // for (i=0; i<nFrames; ++i)
  118. // {
  119. // yuv[i] = (unsigned char*)malloc(sx*sy+2*((sx+1)/2)*((sy+1)/2));
  120. //
  121. // if (yuv[i]==NULL)
  122. // {
  123. // i--;
  124. // for (;i>=0;--i)
  125. // {
  126. // free(yuv[i]);
  127. // yuv[i] = NULL;
  128. // }
  129. // break;
  130. // }
  131. //
  132. // yuv[i] = yuvIn[i];
  133. // }
  134. for (i=0; i<nFrames; ++i)
  135. yuv[i] = yuvIn[i];
  136. env->ReleaseIntArrayElements(in, (jint*)yuvIn, JNI_ABORT);
  137. //sprintf (status, "frames total: %d\nsize0: %d\nsize1: %d\nsize2: %d\n", (int)nFrames, jpeg_length[0], jpeg_length[1], jpeg_length[2]);
  138. sprintf (status, "frames total: %d\n", (int)nFrames);
  139. return env->NewStringUTF(status);
  140. }
  141. extern "C" JNIEXPORT jstring JNICALL Java_com_almalence_plugins_processing_hdr_AlmaShotHDR_HDRPreview
  142. (
  143. JNIEnv* env,
  144. jobject thiz,
  145. jint nFrames,
  146. jint sx,
  147. jint sy,
  148. jintArray jpview,
  149. jint expoPref,
  150. jint colorPref,
  151. jint ctrstPref,
  152. jint microPref,
  153. jint noSegmPref,
  154. jint noisePref,
  155. jboolean mirror
  156. )
  157. {
  158. int i;
  159. int x, y;
  160. Uint8 *pview_rgb;
  161. Uint32 *pview;
  162. int nTable[3] = {1,3,7};
  163. // __android_log_print(ANDROID_LOG_ERROR, "CameraTest", "Preview CALLED %d %d", sx, sy);
  164. pview = (Uint32 *)env->GetIntArrayElements(jpview, NULL);
  165. /*Debug logs
  166. FILE * pFile;
  167. pFile = fopen ("/sdcard/DCIM/hdrparams.txt","wb");
  168. fprintf (pFile, "Hdr_Preview params:\nExpo pref %d\nColor pref %d\nContrast pref %d\nMicro contrast pref %d\nSX %d\nSY %d\nnFrames %d\nnoSegmPref %d",expoPref,colorPref,ctrstPref,microPref,sx,sy,nFrames,noSegmPref);
  169. fclose (pFile);
  170. for (int i=0; i<nFrames; ++i)
  171. {
  172. char str[256];
  173. sprintf(str, "/sdcard/DCIM/hdrin%02d.yuv", i);
  174. FILE *f = fopen (str, "wb");
  175. fwrite(yuv[i], sx*sy+2*((sx+1)/2)*((sy+1)/2), 1, f);
  176. fclose(f);
  177. }
  178. */
  179. pview_rgb = (Uint8*)malloc((sx/4)*(sy/4)*3);
  180. if (pview_rgb)
  181. {
  182. if (noisePref<0) // eval version
  183. {
  184. // __android_log_print(ANDROID_LOG_ERROR, "CameraTest", "Hdr_Preview eval version called");
  185. Hdr_Preview(&instance, yuv, pview_rgb, NULL, NULL, 256,
  186. expoPref, colorPref, ctrstPref, microPref, sx, sy, nFrames, 1, noSegmPref, 0, 0, 1, 0);
  187. }
  188. else
  189. {
  190. // __android_log_print(ANDROID_LOG_ERROR, "CameraTest", "Hdr_Preview called");
  191. Hdr_Preview(&instance, yuv, pview_rgb, NULL, NULL, 256*nTable[noisePref],
  192. expoPref, colorPref, ctrstPref, microPref, sx, sy, nFrames, 1, noSegmPref, 1, 1, 1, 0);
  193. }
  194. // __android_log_print(ANDROID_LOG_ERROR, "CameraTest", "Hdr_Preview success");
  195. // char s[1024];
  196. //
  197. // sprintf(s, "/sdcard/DCIM/preview.bin");
  198. // FILE *f=fopen(s, "wb");
  199. // fwrite (pview_rgb, (sx/4)*(sy/4)*3, 1, f);
  200. // fclose(f);
  201. // __android_log_print(ANDROID_LOG_ERROR, "CameraTest", "PREVIEW SAVCED");
  202. // __android_log_print(ANDROID_LOG_ERROR, "CameraTest", "AlmaShot_Preview2RGBi start");
  203. AlmaShot_Preview2RGBi(pview_rgb, pview_rgb, sx/4, sy/4, 0, 0, sx/4, sy/4, (sx/4)*3);
  204. // __android_log_print(ANDROID_LOG_ERROR, "CameraTest", "AlmaShot_Preview2RGBi success");
  205. // construct preview in a form suitable for android bitmap
  206. for (y=0; y<sy/4; ++y)
  207. {
  208. int vy = (sy/4)-1-y;
  209. for (x=0; x<sx/4; ++x)
  210. {
  211. int vx;
  212. if (mirror) vx = (sx/4)-1-x;
  213. else vx = x;
  214. pview[vx*(sy/4)+vy] = // rotate 90 degree for portrait layout
  215. ((Uint32)pview_rgb[(y*(sx/4)+x)*3]<<16) +
  216. ((Uint32)pview_rgb[(y*(sx/4)+x)*3+1]<<8) +
  217. (Uint32)pview_rgb[(y*(sx/4)+x)*3+2] +
  218. (255<<24);
  219. }
  220. }
  221. free (pview_rgb);
  222. }
  223. env->ReleaseIntArrayElements(jpview, (jint*)pview, JNI_ABORT);
  224. return env->NewStringUTF("ok");
  225. }
  226. extern "C" JNIEXPORT jstring JNICALL Java_com_almalence_plugins_processing_hdr_AlmaShotHDR_HDRPreview2
  227. (
  228. JNIEnv* env,
  229. jobject thiz,
  230. jint sx,
  231. jint sy,
  232. jintArray jpview,
  233. jboolean mirror
  234. )
  235. {
  236. int i;
  237. int x, y;
  238. Uint8 *pview_rgb;
  239. Uint32 *pview;
  240. //__android_log_print(ANDROID_LOG_INFO, "CameraTest", "Preview2 CALLED %d %d", sx, sy);
  241. pview = (Uint32 *)env->GetIntArrayElements(jpview, NULL);
  242. pview_rgb = (Uint8*)malloc((sx/4)*(sy/4)*3);
  243. if (pview_rgb)
  244. {
  245. Hdr_Preview2(instance, pview_rgb, 0,0,0,0,0);
  246. AlmaShot_Preview2RGBi(pview_rgb, pview_rgb, sx/4, sy/4, 0, 0, sx/4, sy/4, (sx/4)*3);
  247. // construct preview in a form suitable for android bitmap
  248. for (y=0; y<sy/4; ++y)
  249. {
  250. int vy = (sy/4)-1-y;
  251. for (x=0; x<sx/4; ++x)
  252. {
  253. int vx;
  254. if (mirror) vx = (sx/4)-1-x;
  255. else vx = x;
  256. pview[vx*(sy/4)+vy] = // rotate 90 degree for portrait layout
  257. ((Uint32)pview_rgb[(y*(sx/4)+x)*3]<<16) +
  258. ((Uint32)pview_rgb[(y*(sx/4)+x)*3+1]<<8) +
  259. (Uint32)pview_rgb[(y*(sx/4)+x)*3+2] +
  260. (255<<24);
  261. }
  262. }
  263. free (pview_rgb);
  264. }
  265. /* debug
  266. {
  267. FILE *fd1;
  268. int ch;
  269. fd1 = fopen("/mnt/sdcard/HdrCameraInput/map.bmp","wb");
  270. fwrite(header,54,1,fd1);
  271. // write output data
  272. for (y=sy-1;y>=0;--y) // bmp images are stored bottom-up
  273. for (x=0;x<sx;++x)
  274. for (ch=2;ch>=0;--ch) // bmp colors are stored BGR
  275. {
  276. fwrite(&debug[(x+y*sx)*3+ch],1,1,fd1);
  277. }
  278. fclose(fd1);
  279. }
  280. */
  281. env->ReleaseIntArrayElements(jpview, (jint*)pview, JNI_ABORT);
  282. return env->NewStringUTF("ok");
  283. }
  284. extern "C" JNIEXPORT jstring JNICALL Java_com_almalence_plugins_processing_hdr_AlmaShotHDR_HDRPreview2a
  285. (
  286. JNIEnv* env,
  287. jobject thiz,
  288. jint sx,
  289. jint sy,
  290. jintArray jpview,
  291. jboolean jrot,
  292. jint exposure,
  293. jint vividness,
  294. jint contrast,
  295. jint microcontrast,
  296. jboolean mirror
  297. )
  298. {
  299. int i;
  300. int x, y;
  301. Uint8 *pview_rgb;
  302. Uint32 *pview;
  303. //__android_log_print(ANDROID_LOG_INFO, "CameraTest", "Preview2a CALLED %d %d", sx, sy);
  304. pview = (Uint32 *)env->GetIntArrayElements(jpview, NULL);
  305. pview_rgb = (Uint8*)malloc((sx/4)*(sy/4)*3);
  306. if (pview_rgb)
  307. {
  308. Hdr_Preview2(instance, pview_rgb, 1, exposure, vividness, contrast, microcontrast);
  309. AlmaShot_Preview2RGBi(pview_rgb, pview_rgb, sx/4, sy/4, 0, 0, sx/4, sy/4, (sx/4)*3);
  310. // construct preview in a form suitable for android bitmap
  311. if (jrot)
  312. {
  313. for (y=0; y<sy/4; ++y)
  314. {
  315. int vy = (sy/4)-1-y;
  316. for (x=0; x<sx/4; ++x)
  317. {
  318. int vx;
  319. if (mirror) vx = (sx/4)-1-x;
  320. else vx = x;
  321. pview[vx*(sy/4)+vy] = // rotate 90 degree for portrait layout
  322. ((Uint32)pview_rgb[(y*(sx/4)+x)*3]<<16) +
  323. ((Uint32)pview_rgb[(y*(sx/4)+x)*3+1]<<8) +
  324. (Uint32)pview_rgb[(y*(sx/4)+x)*3+2] +
  325. (255<<24);
  326. }
  327. }
  328. }
  329. else
  330. {
  331. for (y=0; y<sy/4; ++y)
  332. {
  333. int vy = y;
  334. //if (mirror) vy = (sy/4)-1-y;
  335. for (x=0; x<sx/4; ++x)
  336. {
  337. int vx = x;
  338. if (mirror) vx = (sx/4)-1-x;
  339. pview[vy*(sx/4)+vx] =
  340. ((Uint32)pview_rgb[(y*(sx/4)+x)*3]<<16) +
  341. ((Uint32)pview_rgb[(y*(sx/4)+x)*3+1]<<8) +
  342. (Uint32)pview_rgb[(y*(sx/4)+x)*3+2] +
  343. (255<<24);
  344. }
  345. }
  346. }
  347. free (pview_rgb);
  348. }
  349. env->ReleaseIntArrayElements(jpview, (jint*)pview, JNI_ABORT);
  350. return env->NewStringUTF("ok");
  351. }
  352. extern "C" JNIEXPORT jbyteArray JNICALL Java_com_almalence_plugins_processing_hdr_AlmaShotHDR_HDRProcess
  353. (
  354. JNIEnv* env,
  355. jobject thiz,
  356. jint sx,
  357. jint sy,
  358. jintArray jcrop,
  359. jint orientation,
  360. jboolean mirror
  361. )
  362. {
  363. Uint8 *OutNV21;
  364. int *crop;
  365. int x,y;
  366. int tmp;
  367. int allocSize;
  368. unsigned char *data;
  369. jbyteArray jdata = env->NewByteArray(0);
  370. //__android_log_print(ANDROID_LOG_INFO, "CameraTest", "PROCESSING CALLED %d %d", sx, sy);
  371. if (OutPic)
  372. {
  373. //__android_log_print(ANDROID_LOG_INFO, "HDR", "OutPic is not NULL, freeing");
  374. free(OutPic);
  375. //__android_log_print(ANDROID_LOG_INFO, "HDR", "OutPic successfuly freed");
  376. }
  377. allocSize = sx*sy+(sx+1)*(sy+1)/2;
  378. OutPic = (Uint8 *)malloc(allocSize);
  379. crop = (int*)env->GetIntArrayElements(jcrop, NULL);
  380. //__android_log_print(ANDROID_LOG_INFO, "HDR", "About to call Hdr_Process(%d)", (int)OutPic);
  381. Hdr_Process(instance, &OutPic, &crop[0], &crop[1], &crop[2], &crop[3], 1);
  382. //__android_log_print(ANDROID_LOG_INFO, "CameraTest", "Hdr_Process() call returned");
  383. int flipLeftRight, flipUpDown;
  384. int rotate90 = orientation == 90 || orientation == 270;
  385. if (mirror)
  386. flipUpDown = flipLeftRight = orientation == 180 || orientation == 90;
  387. else
  388. flipUpDown = flipLeftRight = orientation == 180 || orientation == 270;
  389. OutNV21 = OutPic;
  390. if (rotate90)
  391. OutNV21 = (Uint8 *)malloc(allocSize);
  392. TransformNV21(OutPic, OutNV21, sx, sy, crop, flipLeftRight, flipUpDown, rotate90);
  393. if (rotate90)
  394. {
  395. free(OutPic);
  396. OutPic = OutNV21;
  397. }
  398. jdata = env->NewByteArray(allocSize);
  399. data = (unsigned char*)env->GetByteArrayElements(jdata, NULL);
  400. memcpy (data, OutPic, allocSize);
  401. // char s[1024];
  402. //
  403. // sprintf(s, "/sdcard/DCIM/result.bin");
  404. // FILE *f=fopen(s, "wb");
  405. // fwrite (data, allocSize, 1, f);
  406. // fclose(f);
  407. env->ReleaseIntArrayElements(jcrop, (jint*)crop, JNI_ABORT);
  408. env->ReleaseByteArrayElements(jdata, (jbyte*)data, 0);
  409. return jdata;
  410. }
  411. extern "C" JNIEXPORT jint JNICALL Java_com_almalence_plugins_processing_hdr_AlmaShotHDR_HDRFreeInstance
  412. (
  413. JNIEnv*,
  414. jobject
  415. )
  416. {
  417. //__android_log_print(ANDROID_LOG_INFO, "HDR", "HDRFreeInstance() called");
  418. if (OutPic)
  419. {
  420. //__android_log_print(ANDROID_LOG_INFO, "HDR", "OutPic is not NULL, calling free()");
  421. free(OutPic);
  422. //__android_log_print(ANDROID_LOG_INFO, "HDR", "free() returned");
  423. OutPic = NULL;
  424. }
  425. if (instance)
  426. {
  427. //__android_log_print(ANDROID_LOG_INFO, "HDR", "Instance is not NULL, calling Hdr_FreeInstance()");
  428. Hdr_FreeInstance(instance, 0);
  429. //__android_log_print(ANDROID_LOG_INFO, "HDR", "Hdr_FreeInstance() returned");
  430. instance = NULL;
  431. }
  432. }
  433. extern "C" JNIEXPORT jint JNICALL Java_com_almalence_plugins_processing_hdr_AlmaShotHDR_HDRStopProcessing
  434. (
  435. JNIEnv*,
  436. jobject
  437. )
  438. {
  439. //__android_log_print(ANDROID_LOG_INFO, "HDR", "HDRStopProcessing() called");
  440. Hdr_Cancel(instance);
  441. //__android_log_print(ANDROID_LOG_INFO, "HDR", "Hdr_Cancel() returned");
  442. }