From 8ddb3932729e7c64b694b9223578971d2c63fe02 Mon Sep 17 00:00:00 2001 From: boyeon-son Date: Mon, 10 Sep 2018 12:21:10 +0900 Subject: [PATCH] Initialize Smart Camera project Change-Id: I2346e53f399de069ee56bf5469a244702674ca46 --- .cproject | 495 ++++++++++++++++++++++++++++++++++++++++++++++++++ .exportMap | 5 + .gitignore | 5 + .project | 46 +++++ .tproject | 12 ++ LICENSE.APLv2 | 202 ++++++++++++++++++++ NOTICE | 3 + inc/controller.h | 26 +++ inc/log.h | 89 +++++++++ inc/resource_camera.h | 25 +++ project_def.prop | 11 ++ shared/res/icon.png | Bin 0 -> 57662 bytes src/controller.c | 179 ++++++++++++++++++ src/resource_camera.c | 401 ++++++++++++++++++++++++++++++++++++++++ tizen-manifest.xml | 11 ++ 15 files changed, 1510 insertions(+) create mode 100755 .cproject create mode 100755 .exportMap create mode 100755 .gitignore create mode 100755 .project create mode 100755 .tproject create mode 100755 LICENSE.APLv2 create mode 100755 NOTICE create mode 100755 inc/controller.h create mode 100755 inc/log.h create mode 100755 inc/resource_camera.h create mode 100755 project_def.prop create mode 100755 shared/res/icon.png create mode 100755 src/controller.c create mode 100755 src/resource_camera.c create mode 100755 tizen-manifest.xml diff --git a/.cproject b/.cproject new file mode 100755 index 0000000..653551a --- /dev/null +++ b/.cproject @@ -0,0 +1,495 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.exportMap b/.exportMap new file mode 100755 index 0000000..de30516 --- /dev/null +++ b/.exportMap @@ -0,0 +1,5 @@ +{ + global: main; + _IO_*; + local: *; +}; diff --git a/.gitignore b/.gitignore new file mode 100755 index 0000000..71606e4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.vsproject +.sign +.settings +/Debug +/SA_Report/ diff --git a/.project b/.project new file mode 100755 index 0000000..95d301c --- /dev/null +++ b/.project @@ -0,0 +1,46 @@ + + + SeoulIotCamera + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.core.ccnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + 0 + + 26 + + org.eclipse.ui.ide.multiFilter + 1.0-projectRelativePath-matches-false-false-*/.tpk + + + + 0 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-project_def.prop + + + + diff --git a/.tproject b/.tproject new file mode 100755 index 0000000..468a834 --- /dev/null +++ b/.tproject @@ -0,0 +1,12 @@ + + + + + mobile-4.0 + + + + + + + diff --git a/LICENSE.APLv2 b/LICENSE.APLv2 new file mode 100755 index 0000000..d645695 --- /dev/null +++ b/LICENSE.APLv2 @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/NOTICE b/NOTICE new file mode 100755 index 0000000..ba98e27 --- /dev/null +++ b/NOTICE @@ -0,0 +1,3 @@ +Copyright (c) 2018 Samsung Electronics Co., Ltd. All rights reserved. +Except as noted, this software is licensed under Apache License, Version 2. +Please, see the LICENSE.APLv2 file for Apache License, Version 2 terms and conditions. diff --git a/inc/controller.h b/inc/controller.h new file mode 100755 index 0000000..e53055e --- /dev/null +++ b/inc/controller.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * 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. + */ + +#ifndef __CONTROLLER_H__ +#define __CONTROLLER_H__ + +#ifdef LOG_TAG +#undef LOG_TAG +#endif + +#define LOG_TAG "SIC" + +#endif diff --git a/inc/log.h b/inc/log.h new file mode 100755 index 0000000..14d3ae1 --- /dev/null +++ b/inc/log.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * 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. + */ + +#ifndef __LOG_H__ +#define __LOG_H__ + +#include + +#if !defined(_D) +#define _D(fmt, arg...) dlog_print(DLOG_DEBUG, LOG_TAG, "[%s:%d] " fmt "\n", __func__, __LINE__, ##arg) +#endif + +#if !defined(_I) +#define _I(fmt, arg...) dlog_print(DLOG_INFO, LOG_TAG, "[%s:%d] " fmt "\n", __func__, __LINE__, ##arg) +#endif + +#if !defined(_W) +#define _W(fmt, arg...) dlog_print(DLOG_WARN, LOG_TAG, "[%s:%d] " fmt "\n", __func__, __LINE__, ##arg) +#endif + +#if !defined(_E) +#define _E(fmt, arg...) dlog_print(DLOG_ERROR, LOG_TAG, "[%s:%d] " fmt "\n", __func__, __LINE__, ##arg) +#endif + +#define retvm_if(expr, val, fmt, arg...) do { \ + if (expr) { \ + _E(fmt, ##arg); \ + _E("(%s) -> %s() return", #expr, __FUNCTION__); \ + return val; \ + } \ +} while (0) + +#define retv_if(expr, val) do { \ + if (expr) { \ + _E("(%s) -> %s() return", #expr, __FUNCTION__); \ + return (val); \ + } \ +} while (0) + +#define retm_if(expr, fmt, arg...) do { \ + if (expr) { \ + _E(fmt, ##arg); \ + _E("(%s) -> %s() return", #expr, __FUNCTION__); \ + return; \ + } \ +} while (0) + +#define ret_if(expr) do { \ + if (expr) { \ + _E("(%s) -> %s() return", #expr, __FUNCTION__); \ + return; \ + } \ +} while (0) + +#define goto_if(expr, val) do { \ + if (expr) { \ + _E("(%s) -> goto", #expr); \ + goto val; \ + } \ +} while (0) + +#define break_if(expr) { \ + if (expr) { \ + _E("(%s) -> break", #expr); \ + break; \ + } \ +} + +#define continue_if(expr) { \ + if (expr) { \ + _E("(%s) -> continue", #expr); \ + continue; \ + } \ +} + +#endif diff --git a/inc/resource_camera.h b/inc/resource_camera.h new file mode 100755 index 0000000..f952ea1 --- /dev/null +++ b/inc/resource_camera.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * 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. + */ + +#ifndef __RESOURCE_CAMERA_H__ +#define __RESOURCE_CAMERA_H__ + +typedef void (*capture_completed_cb)(const void *image, unsigned int size, void *user_data); + +int resource_camera_capture(capture_completed_cb capture_completed_cb, void *data); +void resource_camera_close(void); + +#endif diff --git a/project_def.prop b/project_def.prop new file mode 100755 index 0000000..a6e3023 --- /dev/null +++ b/project_def.prop @@ -0,0 +1,11 @@ +APPNAME = iotcamerasample + +type = app +profile = iot-headless-4.0 + +USER_SRCS = src/iotcamerasample.c +USER_DEFS = +USER_INC_DIRS = inc +USER_OBJS = +USER_LIBS = +USER_EDCS = diff --git a/shared/res/icon.png b/shared/res/icon.png new file mode 100755 index 0000000000000000000000000000000000000000..9765b1bda7e5bddf0925555ab204b887a873bf24 GIT binary patch literal 57662 zcmdU&2Y{Bv)wXAQhoyJerGpfaq9DE5J1S~atXN|Avn3kQ*!`l$D2ie%v3Ct9iU9$! zARxVWkS4wCvh_dLJny{>uV6_upZ~zTGjrz5nKS2}_RLfEz7vl>A}6zMrgJXms3ZHI zY~lal(^KvD>g2b^T99$|k!M`zTvj!Ff*bL4ZRavixU^rt6HmP4s_U=1?vksn&O54K zzr3rjz3Spie}9p4H!U1_%FscltgqRlVCl}j$J~4S-;TNJ8N(x+7h3`nl`#k2P&{pByWKUm|WHre-Q&QDvN|NLL>eBs{vzbanwhZioN zJGS84sb!<)^<4YLj*;(APaB_}{rHg`PwISo_N#pxR#|@M=aVL{SlzDou*{}cyWI5m zFU-HLv`K<1ysdlpgBp)d`cVb&Nq{W}Uo#k#HS@`5165LsT%de5} z>?1C(+C}&Fcb6RQ-k5&c{R7 zy7#VDF8L2`$QMnT+~ofJq^mw~`{~`c9rRZ2+SX>NC*SKnrfJs!!_G=?drjKur?+d^ za@tX~4yxYeyu|ZH^lmrd<|peMGOSbO`OD}^=eFH2 zF15Vz`RA`HTQmLjt9v`Q;`-ZWl(lL9e%;#-Prdz$vgey^PQK)vtY`nH;DL+ZtK55( zdv^W8(|25rZ3aB|@R$V))~sGV|L945&pPj`({C*sI^o>$rQvN1Z=raO>);PO5s%U;2-D zaK|ApHomX#Ut4|FY-ag|E0?t?PU^X=vwP>Vo(X?=r0pwbUy!u>m=?K%uOGj%z`5-o zU-jwimgz~iUvlS)={J^d=~a5fv(4P?7a#T4Yn(f$f75n@zIwmc=jqP%e|A{wcly-Z z`DyJo<5TN@nzH!Qtdb#J{@l0eqzQd<`(|Evd;M#Nw0h%?zAf*b`c8w^L)y>o-JsL> zlP9wA`t1$o5 zBa^E>&@}JMd#j(+_?SmJAKBsL`v>KndSrv`J+4jcde83$e)P!UU${f=D7ky=5gqMx?DE{&Z(hHo^1_FD_WS(c z@#|`*b)5A3gWFA>*!SJT+GIR>!IXC!zmfg=7-QI$QDYM*~dhkFJe z*`~?dst;9bpZkY<`%OBuY1RAs9nxaV!-+?|`;S30tIixa^U9N(tZ(z`Q=N{i+vL$N z7hZVzdud(&)+Xtyw@>iD~U1v@1noes{ zFM8sTKBvAg;^ZZ-JU6IH=ZDVh`{r|_Pk#HPdtRy5>3>FaoqA`@qmFs;&F3GRRriuw zmlRz3_PXmosH)iMDUE|Kr?;YB*&QrD1Y7eb*W9_$} zIQFGFvmU7P`JjUj?XdBQwNF-l@~Tq@w;tX4k2N0oD)X_UA8Y(m{mP8syjtLL0@>std)?Rd(nS2Jcm{`#q}jXZJVDfLbn`s(4Y-1FMdSFRe=>mRqB zQF>qM85574ctXE_ob>Fw=dKz%IWOyiI`7}qCjauB*YEzHVVx&6e|PGFKi<&#<0ncR zeEdL<*Is?DYrl?1cRc<5lXv{>;$CU1p17v)>FbZrSljaD;X7`-e`)nCtyZ?G_fn^0 z$8@;pcbC8R`0&REzkcNFC%t~e#!tGuwdv)NFMTrL<1>nfRqFHk(Jg-0;)tOSO-mWM z_LK#uEO|Ne<(kL!=(g*vcCTIjV!h`+?tkOBD_`FH#54ao=k{lgz3SzqH-ECWsQ#_( zO9z!+QS|bzBeDmlzMtJRby4=T+TB0ve9cwe8?^s?(YBNNojtL4zZcJY?7ZPC{`|<8 z8Qou)Gw^>0R(|l($-i6Gbk!A;ubBKo^VH_~&5t>5!*QEOoP6Avms-7a__2o{`}x$b zr#?S*?vtIL>d|4|A#0yn`_#OrmVGef%$v?^Gy0X$A6|6Sd#lfU>5R>z$6k5YnO)C# zaqy{Up8fv7H%GqNZ0^Tze*AKkm&Y9c=<%;VGk563ceaiGa`dYo)Olyk{M1EnjlN>^ zt>+Crzt+$XK6`88=0`ty^wy7V{om3aX*u^SsPuY+GaKA?-9N9b-tDw*OGiw5dULN^ zKim2E`u0NyPtTn`zvHUW)uyzXbm_=bo|<*U&{{*sTzBV=dmp&(m^-Gl8{V_sQ}re< z`Qnq+M_<3|nzL8jGIQ6+r`~^R!lqXiy}h~1=1Vu_SwSx1u)atpr=e2)d)pJ$% zLzf=1^o(=AK6LyCUwkm-go#%@bM9Ts`u(X%`Gw`Tl+SQ4-`*@?XwrSd`V2cOvAFP- zKjx47ORsK=F53Oxf=zuMe0EHq8hswR*juwcHXz=JuvaM>=t+3bJyv2_xj7#_YST*qr>pdH_lkx@499Ei~2v_f9X?0JDkw< z?Y2jEZr$^>c9(Tuc<4u+KI%2O-Nk2oJ!kO9!AJf6nEGAYwSKG1mB0VjvXV_Z?pZl< zW!9=c)Ow=*7iV96^K;WC?7Zvcny3_{09TwNGyAS86`kY(vBH+}v7SBoA#^yw{s zFW*#kLe&+29sT0n$DH1_!QgK{dE>IK?{&ZC=0%ySYNQ-=_i3qbbpP=F(XFqTbHeMJ zP9Of(ZJ#v1<+#g-o%88ecYHc3;qr}Hr)I9X>(-5n=WROsgu(64ST^dsqPs`d>sjNz z``@a*sMhcrf12NN@l9*$-E-AfnL*e;B*F(|2*KGPcX=YMsT9Znn=Z%>?r@_n~gHC>E?m-)msPuWGf0d2ga%0<^E;*=WtUaHYRgBt*RPm4p!|WghmSpc+V8f1c>VVG7Okmv`iG~Fc)Q!VS8TX`L-(>r zXPxl*$4`Ge;;k{iyL`;%TRs`}hl>l=*L&vBX-jr~a`U#D<#Xpe)3wKvPj=jLRl#Qk zyOz~la@(~nN~cZvc)^V=HorOcgt6!D?7gYaf__WxnbYg6vc>baEdJAF<8OR+$Be~C z6r|pD=k&5ic0E+NU&=#IJ~ZX-oVzzZb6C%=U03$Hwsd{T%l)QbIKBBZwaT6^oAOqz zn(c2ZoU?J>v>8v#cy9Ri;g62H;*T$uZWzC@&fAM7Png{BUtiwTvBNn#Pb=Q^>5YqT zY_R2pWtC4@{l~mNwJg76&%3)$`R3)~N9#QLXnAtd6FW*S=-76V?Kkr-IP&D4Mz_yQf&Wh47dMTpt?0I)agY+wM0#Qez+jqzAB7t5&&n>(x6tB{`*gQc}_( ziHV8LQd3hiGcqzOS@QdeADY`(-57430* z_7u6o!a`S2P+;kz-Nv`bc&3$`b6HuL9-!U3cY8qg>;arT9xMaH;jz7d3;|9~ zPIh=YKw4T_h0n~)^c`UPjva3IuHBAs`}Xa{CTn(SNy)fv+qORc#TQ>Nl1t1p;{Q*l z>fbb|rktkMl&J`)CsmG_KrnRVAB{!jJ)v7K#JKK+>UAuNU{0=iXz~LB` zfXAqm3)93y2VY1F1KC8UvH*HKj+-p1rfOvaYdF*}F=WDk;^fRdY7CnlZOBTHMZ^JN>j74-RR8 z5`ro|(ZnNq7>b8!Su-mJBM!(pIXSL!<;pHMH`nyo<-Xgr$!*!P*|04dZyoHRi4!J_ zH+jY88NL6tsrferY6xcEe*Mn0Dey|$@U*K{tEOXA0^%k!+_r7oDhw+SFmk*TV1(o| zas|}>8g5{C5n&$u;1SA#DdZuK5nR1`br1BW&70l&^&6Zm0W%8=3jX@ZCu3i-BL6jT zL*0CX(D%RCseGNLgr?b)zWw?SPEAX_!PdxD_3G7iSvJjW*s#HEHbY@NbPJUhND4#U z#YY~Vv}kH9p~^}=BQu`v3HBqNP>$-9{2DcCcz~Inzg@eIX?p&iJ%#s;{rKZoOa$Qm zs?&0)oAmy#f@%t|;HC8H-Mg!e$_KKtvpY3xP~Wk8UAuOz2NRuhb>QUL}A zf*pW}<8hi&mFJ1}gW&}xG?iBks8y?$v!=S$tJk>o8#b)B9o4O4$A0|0@&2NtHr^)a@~eSrmHE-xq)C%X&0Dm1 zDl;?dr2PE61iRLAD_5@ch6_g+29cAopot#R5G}gO5W>USrfHKf_t+sWvuPW*@ui1d z*`~GrdenBo?cCDl7S<|A2v4T4ToK=jG?KLtHR_z6VrgX$xMXiZ}{}MuwM>fX6_}qm0TyXR2jgCJt|T z%R^nI8%DUq{5Gz{4tI-7t)Ai{FJH3*b>XE4Ax=6F;^61hNp(Zl`VLKWbu{u-R(V{O z*$8#mA-{2cquksoAKG$srHM~9-d`RAHO9B#Km0*K+XSWe?%n5awzD15v}u!sEp~ar zW(XJGa2l`r$sT8mOFVX{OF8Tqmt>~0gMF7`qckbWoUoC}Tr-`X7`Gv57pYvM~BAZ@~v>esKI)23~^S1VPnG_Y}Ao?EeEg+B$N2%yLi zq)|o+g@%v;#KR~F4Wu$`hB#p&O_|c#Os(T;28NU!Ae7sPGGMLS_n5Z%z7_Tk8+oiu^LqE`TYt{%S*IEA4&#k3nkDex z41W<&O`#;)5LId3qUGos)vI^5%N4hH@ghGJY822w8b>3E%Mr&g&~X?;Wk?f;CSyUv zDBMxOF@lOZ9_7l8xzvx&a+_+sDC`*YeLDg0MulHSrcOMvaneh=D1?p|KcN7mocM@K zSK{y}FO5Yugv9n&hc(F6P z8DC;&Q**5G547^%8Sj4t?0*ERDUj5xS+lAQ8|96uQKM!%c9nMDu>u$jL?hK80R)Xa z8Z90g99}|Te9|&9an?^9#w@Pi$}K(eI+tw+7)ds@h9fh?2O!WxP)W!4VrZIr$&)cC&y*`elplJ$Tik7k zOEtT*yNwM+2BtatF%?jwyo^!GShY@6V)~dI*5ds+>8(70DV<4&U=qix+>h~v?V()) zoAS$-FL!x)c~srblA~;CVZ?4XzF+~7W6Zedgolb z4nr{<3dc7X#nosUg9kj($cM)Ch$F2KV{*w-0r2rxxi31N8-Zzn`b!qVQoEe7uvj!( zTS-HQ=JAfnmOg}`mtKT&)Gt6)PI-jrOgqG6*jCX90h`Xsh^=I&UDc{q?cDmH zgWkZtR^Pvc&(AIttB6DS$8vKk_v6}Y*|KF`Pa3U}20=zpgUEx14;zmWLqm!m8M^gG ze9y@@xk)v;yQ~BoHP(p*pdHQFRXn4%%(2S_%!)8ZXS`CsyZ}_1kb0pLk|r*F6_OXm z(MxGU%HVP0rL8#faiLt*3oiqMJ&9fN^y}TH&*R3LVr70dMn7x%wF=NGxnIBjSJ~45 z=Wr(6CTH9-8!qE?&h6aqvpVh!XvV{Nke>(8Hxh_8KwE4T)RK}u<>zTOe=qq`&pox#H60RdiTi4%ovuRmzQ97A1Xi$d!Op3 z@i+lXTn&&RNsEts8VU`gvHlU(ZFi`9u}WX-PR1JpG*Ud8R<$u=e6W66H$s$miX}2V zbNLgyIZh_VmO}^9p)SfJBrnuGzHG=N0K@VJiqk$hfz0KO0h_RR$&z6`di0z&apHvW z#zTmJCN4UeV*r?cLBM zxNkaNVDqp&R+3ugifn`$wg%l^#{}iK6wyHS8ziIn{{(EHY)1C_pp)v{E8&M@@T(na z7h&j>Ry)ExXaY~2L43%?QC_wo&BFpVaMG77UHWw6#*I5!K0D&Qy%44YxSs^738V!n z&6+oV%5I%C;xWqb)>f3gx95|_qqvkO#5mAVp0o^wZjvE>MihK4I(2j7wwanKHqxw9 z+gP&s&k7JXpoCp=%*GrtMANX<51;WE$#KO@{oxvBqzWfvLy!&?nHEu-pdm*9s14Ge z{7{zC)Qep4iAS>FLl$&+ctVng-)h#V*~kixusb_v7`@13(CQy_H2bHxq&|K7o|BVP z>BK5_Zn<$I570$UKq*8ayc&R#`}6R_BM*=CB~*HAO?xS`pv2B`t+CK;SIY*e*gCD> zAX&ULw$o*EWV39v>-F*2VSX$woe8CrXy}8-`0QwPP{H*wUTL1v;Ov;R07Zt{p*SN` zqZ51JNULqCpAZ+ORTewvn$mpJgxkB(GRDADHks>w;och;+0 zCxIPWIPD^u#;E~eRZpy)KGLEqR9=`St~6zk ziA_{Ld9o2Sbiq!cEm`IoG-!~pd*`lU7QSWmY_)PfI1T?Gs3rj0q%_LQd$eY)nzi&m zn3N)0U`ctU389Hjqi~d^TqJt0aiZMl7eL|5$f<1Lm{IM2q8Zz7h)iQz#58PMLd!E1 z{jN7E3j`iW1Df|OBIp4%mLKR8ubcFWr$;3tUCC4DAjAt8_>jTKW;EkMS&GwXv>J(vKXc%}H(e>&#aNA4m;C{D(oXQ$$9tdLWIloUJm> zXGiOq^rLR-#CRAPAL`?aSsUUV?NT0b%7o>R4-neu3E;3^$)rQ5yz*rS)dMd#02(!F zWH~l*=JuEdGEGa0%PF;K{cUhpOT)D{y^P2brM&vUR_aC3ZRf0MkZ+# z1vGf1pg>e!sIY_rB91bW*{or0w=>6p*|f(c7THC;X~eo}OQ`jXXtb7FJ;heWH1Xw= zEYI(DEuTpWR&sWiC%arL8yegfupjhR2c&*E(nr&i|?A$#qyRsQO z)0Jdbv-)g$-?7#0+Op9V?u^cvEJZUPGQIro&N~#g$Nm=61aVQ=->ca5IXjn7X zmDR{}Im_&Nb$0}6GzUi|Y@9?>u?LnBV{%z84NTtwVzN2yEi+J&iF_Qo$YX4b&Zr`e zBThS^bIOCOTsha5shv^c(lc`0)E&9*>+%L}?5<3=-Q<;}*}Y%uoQ*QeU7L+lotycI z+q!tRZ!2|k#lVAabRgP|eCV=)Yyu4jT{LWB4~x63?5xA=H1G6J$B%!}SoVAEx?fOD z7?w`4(Q{Mv>ecLtxYb@bMj(qyiOUgJuU1H&=xPK&OG%ZD54lf@{Hj%|xbl=NcX;z^ zuEV_DZo-;ES1r{>r4=Z3cHC$PmKsndkonv;P!nq9q#&Q(X5=^WC9s zTDp39OXce{t?rn<4)D@AqXSWjZ6 zNyMCqZi#ikCE16&w0_-P=Z-U7+QgS!!HW4_4v*b%sY0iT%)GaQQ@`vZT|)b?w%TZA zI=f2T3U)d(_1~mJ^!z7-G!qHT(Nbq zjG9(khTS4eNp_{?%V@hjN0V&RL<-Ztb*M?X2fN%;4t5=A#?Z?t|7R1+4B(v*}dc|nOM;N)Zg(y)bIG!)v5SiO3~( z>(;Hez1Px)Ib01DD1-olCoZ}`QW{0Yhgk6=4<16rm8Y_VfLf(Wt}84xgJx#Cdrxj= z#@JmHYEPX;F0+L%;iexIGk=-@7!fi&U6`d>}BU%1JraZ161?T2#o->mU|#0Kt0Cb>;X>3KCoGP3Xi|q6&`n` z9eYOCxGZtlnq9JH2#rkiL=O!DLf!@hAH&H$_hlQ5IJXbM8j@(Q;MYt}N$yi(2GUeO zna~haNJXM6uIWm2LMap)6N8CIa-qdu&G*-2j1s1%RGZ?g?beB$8-8AUH*U^Gw{Gn= zSF27XS7fURl9+ZAjVaL;xn>LBa;?hOyDU4-_1~ zU$e*$64p!Fjm^+iI--trmumJJhqLco^tR{2YR;WImo+k)pDhw0BTlnj&04iCvzL5Q z=sEivRiZH}soX1XA#w5u$rGPw3ROnsM3)NCc{Y~DF$E$k+14~%)tof<=GC2D$<_i_ zu)WYF+qA`qO)1>tDs5ZtI)3q>Ym@k$FU#?o0F`Vy9mc^cP8i0OPZ>JgMI)xUZ`T#L zI`wQVH{I9_mHIW*OlR1XgO<_hT!0mgOp6=A$32(=H_A75pO;jpkxRd3xJ&JQYK0E0 zv)Y_WZ^95@(yXmEqovfSS@SYW?t^1R!U~~Ra#CXAi5L=tsKE%KfuUE=0VJG2L=1d{ zc;&;RIHC9zl8+;gZ9CI%xUNLG&UJ5D!`*UfGq-ug77u2!=~-{n7p~{(H(g6Rte|cV z!qr(+Cv*X}KM+G2N2~BZ_Tggp^1oKP+D)tZvt|xD%9(OKsMbzPmw}x9-wR?4z&bovvG&UPOBybGt_g!b** zH&04RZn4{X3x(tq$3PMGk@2Yz8eTjqLkJyX32104BRLAWE~F7mxjZ+_D}lNbLOD73 z|9n~-H*WSuH*4xL*EV~qYmrspa_xYC>uKtf!w~2tK&6Z7Bn;zGIWEJ}+~;%GyDMIp z<0{z*O|;9EBBoith8kKnI?JuBzr}|P`^S{4sWuv|q|FAFzc)`b=&?NV&8Kzj6dy{9v&K0S{j|ej6A=k z>ss=v2NXWL-?-20B15QN((3gZm86NwlTNjB#+`P=chhs@Y`bcY(d4Asp#~$8O%dxU zQ?N#9)HVRB7^yxU0p%}mJa`d^6>F}67>!neYvoNyN~J2U&gJ*Gs>hsDp;M@L7)Mv0 zfzGX5DIqf}>l`yrg<->yYW7aH&)V!IVNg86WE_mksDg$g1Q3k^z+l>>9AyYmAar3` z@(BT)sh4+6xU>j$p*-cv?4Y5zxX`s|RKpD!GQ>Ui+;d(BMm2TEJIWvzU5FFn4iuIe zPWRq>udBOqnQNBS!R>O<5ur6CHaZC-a2c&8$OGitYH>y#WPrx+LpOrxCN7HmFh;jb zz^#4CP`7#1^M0nnuAvLVp{;hz+t16_6k}a#>s5i z!Bs!<43}K9eg&vh$Rf{rz_yz>yp)$iN%-U$!8`WEB(?xf6~* z&b4aU(w`M;=PaJE9^$kM8S>B+55rL(e&klITH{|B?v^muHD39e-&HfSX$`HojPW2E zIMzHr3M~Y*eMe*rJOS-_qG>;xt|LIBj$j>c!)mwn&EfuIA)2k!DY3siwxO-enr5rE z_Q*@FnZ;_^dySK5>)25_m2#5x78#ioqVXY^&=J(?hDZHlm{m`?-0fOA$L*T^h1)fK zqAOgz7#2S|kfo>UxrhfSWZ@KIPyhi?p73Xb#Me*4Q7WJa;oqCKFIC@svpe(5Gd*Zb zN0h|~ICwR!tE|tk9~p(TbYaK;!V51{?4H?$w@xc|IrB!iMNLn1>(g7o9f2F$^?CqV zQ$4`3(2xb(c-r0#(!RjEb<14Q+|S+a#WP%z#kqk{Xfr1IOE-nI4LXiEOQ78(NVa3u zqihL!-pHkzYpwo-p7wb-x4meaFQ6X@lOT-4)VOW-6lY7cf21VIuD7xqv~(Fqp6iO% zEO&+TzH)^#Cc2_!v;AHh1G4r~7I`|s(MZ(vZFlzl)Tv1O})LZ4%LCGVIBQD;1?zzXe4H-BNEm+^1)~V*Iu6oza-MYxlJLpt!rC@AS zS{NIl-vbh0_sIiH|1e(xYEoiSaz}0D#jGBWAPfTt2*i*(CXI4Q%?|OS)juj?orh;*f=0>f%h3(QrORAC!)30T?NXObca@8GdLXMbZs2udx!`sh`k^QFX&^~o z(rPm_Iq8PJ#I3DOEzi1=t*J&#Xn*j*O|5VSJvH7*Acb*+_+&eeEnGCiB{b_01JW)J z3{Xa`)e!+~VEZThpjD~s%DSB3$~vFm%C~KFiA$!rw3+{MDJ$ogylDMC%&rNu?PHR1 zD69I_Xwmi;UVr`d?y}1+^ZGHu7zvbrvu2*L6&Wy<4tjy6IMozm0+ zADx9WWoCh@1?yeI*>Ah5*>)+l#n#{1<6ON7e|HU+PI7rE#jZikYTjlH7RoRxnckU6 z@W@oCHYm-k2~D21h)3~|m$nxb6;HJX)4pN)1+mu2w%FRD;@d+*C;*tm5k?$gqy>EO z%t@~N*vtG$vIoxd9$=*U={Xw7jA%{Od$MY{g!X;imragv&wX&MTe|97*Ry9&$2v(5 zSEJM*=@X`*;h^>C(ZemUk7kS?Ki=z%@!6QMvyOKke)ypueHaiv^?dk{i46pT%F>~s zV*?u*&OZ3%Hroh(XVmMiR`sf`RQ$Q+ zS2;p^OvTD3&}*aTFHBIrJ=a?yM8XtOk>Uywlv-@3NvjsR(t6GO)a!x57_n)%V(K-U zn_e*>8M%093Z1KxQRHUS?c-|9ALHiCnd3JthaY~pJLHfg`aoU{Mz0GmywJ^< zF~i@^f}a_NkrFx%{6F~M1HUN?4^se)k%c^5SRcFcu3fu&-=|NXip|*e4d1#ZxoK|L zW6${STxfSsd2A>?2*MSoX1e0M_8z2Y>WzUG12Lijs7;5l&6Ee#@|lh`H3M*AZY`Jg z$us`e8`p^6e*3MPJbAKv@4fe&eFo02L!35YG#V=dD2z0Uewl8^jvec-IpOCpd)b}0Vv(U8yo~Pof{{l$%u^c()i#C7ql}#LNRyv#=K$80t+rl2$Mll|STuSHi{L%X1Mqf7|Zs7 z~>zPG#0BHaG9(YOR~&HzgQ_HH~@zgiR0+HACaNl2OLm zi{YC$Z|*w)`a)+UGFoH^?mt530$-g3K-F%(BWQQ2DyDmF3PU?c7IlOUo6rI6sLspR zwJmkwB!jxbj&UG)DnrMhOlWg2(0)`_p`T$4N2&u<7_xP(6iZk1UeXA~hf@=ZQlYPO z#&}m;tGUIa>2$xqDvw^ZPkb-HiT0Sv)>>`d9t-)X6>A;9pc@SY1nT9;5hHSG!L-Ws z4A20ZmzU?JO`GOY^3!PfYF`N*riLCik&g?@iJCeUh()mY=fTY)TvV^_wmOc z`|{{4JE<&n;*g;@JUG<q?l#FfE$OQ$KYXlmF}gT7^p-5l9mv~NlPGM z;=IXjPrr-(+u9|XPHi*-F6$=k(8x4WG*t&9*_82*qa>MP3HD^*wpuM+)%ElI8pr-8)*fnX-cZA#9r>qKC$8%H_?rL|cS+Rc}+#aC*CT zyVNU3BbY+T7r@+Qfi69{AlEKb`?q53bM>naq`MA-Di7?8Cz=|eeq?M0Rp_hNR z+HL7@oZD$ryX_Gx)=fWZ%|5&+Ox*ta2d@D$iAOyRNbh5553GFxAbrDJms}8mL~o}K zdMCY~=@(;R5Yf@eo`iJ$`t|c8mFXFN>8UmlQU*F}E@>`Xn8I<;Lyy7Y)1oQ#1?@+& z*_17}vtr2?sNzE&&f5)xm{T1-5lc(YkfyTKjhBNLv)i|n@AV_q8ee3iEd!b94({hbRI(G>f1&UHqN<_Jl$5CJg93kXtT;sF^t9f3_2?c|H$6AQ- zC*Z<3d2+}FD0E~NvBUL>vdB_7Lb*_;Xp|REd>kINA(Thwu!qA7tql)G8>NKAokq-t zSx!PpV;JSB5n;Y)8TRr>-ziVHH(FlgN(|UUdygb~*M-qZJO-*YI05hsOr~2O0=DJj z6KoW(v`+-*WY|M!yVrV_ z=?KgOY?xSE(T`arv>7@AylAp7bmHO66!M4ykWG&dkW&GqQk)um@epGX&o(uq*|kSE987e)s44iW80;Ino;uUJL<^2iii% zLB$CtoZ#Ml_gybnmmjo)wzIRw0We33fCN}?zx}owHoc+i&~&BiZF=@^TitbSUflqT z-Y?2ZXJ&}5Sy=+ufYDjdgE*mViC)x4h!dR1Q3QoNz3tk4^!XnZ^pUK+26Rs+8yPVl~;3{%5vOyyAs?s12M_|v}JCR zUHsdtVD)NeyDp9Dxo*v>xZbU++f(OzHxy+h_C$aQw(sFueNhdeK4D`O=LP^%D*6Kg zvkxOS+$2fYbIv)(KQGJ_iSgiPG|3k5(NQ_IV!fsAwYlwGc8w}-(&_>?asFa=_oyYV zeZxwwXUl5t*!HztzjpjZsa#i7xZ7pe?7}9FQLfIS8IUv{nF3IH5z-zU`S{Q&Egte> zc-f*Afok2wEr%F-F`@)?fgLXhKIOrO<2DzYkA(6fw{h&#u2ai4u4CIauGF5@Ey=8I zH0gX;FgKs7EU{L=2r>c=<6ZuQbO;?zq$gkd`5=Q4&fVT}lMrw0R;bc0`U z!W(bA(VchRd49U11F#m#@S$wt)L-7HgG)$HbG0+mT|%vF8`WiQ#->6y?Vros!(&#s zfi`llAK1VRI4Ik7Xk5#!S=+$h>*QKpQ?TR;%+RLFQz+Y#Mqkp>A3G>+WbCrc*vkA7 zlKolBde)ndR{ExTZTA4NzRxaLL2Qg*x!aKwm~Nnpp0`T1KdfLQ+P^t&uViH8*c4qY%cWD%c6tfkc-Emi@Yb;4|U^255q7I9@6#(9N&Z(X%DYW_n_L}jVZCu z%U-It%U}!}9vXtUfE0)dRfh8L&=VOw>@F+kWVyKu7Q5wZzq7|so!hw89_z4UiX?k1 z)in3Ys~*bZXb3L85uO#Hl3ni2C8e%+UWTiZR_4B* z_DzLe*h^0OE3LNv)U-MVwzjt4YG>Z-?Te}9<@Pk);*!#m0vaDyLYzt{sKQjHv_g1f zAo68Q;y4V(LtBj69lHzsMfvR6v;7ke-24W3Mgzt}htQz|@+3b@i^h`@T;t~D2>#pcg9zP+KnMrk9h#K0>xUt(WliPEX|%?FF8rMg1fSh?&B zSFNdi?$0K|(tV> z`Gox_Pi@4;<`$Xv^SO2?hH1$(6W9*rB@9j+4UVTl$0!&~`BIWJj!^mJAsa(+UzAZx zdd!$H{-U01MW#WfNG>68OoKQ9hz^QFN9KbMKInTZGXZ%x_{2*GQJc^Q9`Q*}(fGS; z7him_8$Nuv*PY86^rxO}b=tb3tmvktuOV`)>afEO^N00ZQ$iQel{vONs2j-CO-zP{of0*CG7MJwE1ET z=iUjqW$x1*iEc>$6WyFo-tl0?Mwg`dy68aYfSx#b(4G3_$b%NPi8`#T;kWNdE!(_l z(+BoNmJ$>owY}Q*Y(ixSUmGW36yH|ka@eoEW z2LL!Vma| zwc(7Ghs^{o`8W@Zg~Nso^I&U~`pj59apY4c9S4V6v;%!`((6FsJ$K#Zet+eao{w)1 zCuUai@8GL_e129fB~-KZwKaQ*)#t;{h-GKIDJ##%(T#Ogve1Wip|5E0NLTVjCoTs+ z1IaqwEPIM@i_yJGnttIcwH@%d%%qGCtV5wd3JV12q;aYUg+jo{g9lz26&em&$O|8G z*l_|VhvE1yzx>iqgFK$e2C8x6CieZJs{Tcz`)njJnpsEVN9DhaT#9KZnDNEseX|hpt#o;1-y4VA3&5TAZXO1#yk+QX8#BnU!57TT)76 zyL8!+`eiTVNe}EoTzRrLG&yD<+t`h_bj2vy2UP3z&)aKpe4EFf3*NgqB90)0$|F?9 zpi(IaT~7H*6RNxvi!aB92@tiBV$`l!zRVrb{V>;~O*8km4<`C!H?Bw3SjmmAhcxxz zciE0MHN}j_*V1CN9||dZ?X}ms$usA<`SztW|K^%aG#)q)8itL~gNE~AkO%0>D@e1? z*cySUTr-Adz<97^6Z9jG(8~|(Pg(41e-)#A=gwWvTmF7QEuTMc-a>mCZh@^)EfFl? z3gbb74oyn=nu8xdLTq}#g*@?!k}t)HGgGi;ax0AE#sv!(xtTL(xrb^ua*J#V+t}#> zn@epY5xZyWKViqIlz+rG}V zKBS8qYtM7ptAh4NVysg`kAbC87y%dMS(P!TksSeBU?$Jl^_`sw7x+B@)9-Q`>sC!<}n%Cp_FlZW{!+?1=Z zo^QGRL>7qY9upQbO9gL&P2Z{O*Vt)$bdQ&{5Jy`DB5g(|<&h5!Cp(ibXEjUA*{-C~LDqh1His=@g)Qn`G;)oOVzGSXu_kBk zSnEn{wqVmo{j`lR)J672pyHv;iQ_3#Y@emGPXCy(R!qH=+Xqx*wlA_JY_N^Wcr(ZV z3di>%3W-J>9vsHPQCWPxKq6l~PyF#T%6o;)xEL7zlBS(pV(&BkO?LPr9t#DmZGZre zO;Gf)ji_Vs5lFtffU5{&dU|5)M_|%<_?v6oisKp>hYq*~Z{6Mt%)^4jE zR0S<&h%8|`M3E>oHfEKYc2!np5540glep}G9c2^I6p}}qLr2;$9dG(>Kunmo52&$> z65CBZWTSNeT2YaJix&((`BH{-$U`|s9Lf=AgopVm7f#P=2&XRaCZ?vl;&bou7NcF> zQ%|fe)6PDWGqb>CG;7bD6~e?8PN%5b4J)EwIbXfyFK?JmBcEtfv~8lyr&?Wm>5AJEhIToVFmKX6oj=khvSk>@ zR-q>^w3*W2V+Z)-EWOVtCI5RP)r@JjNGP_E@@QgG(v$YAi|?sw9EEVCF^u8@&=X?$ ziW5rFkQN_@hY^ZgI!D4`$Jv)CI{InXV`l{-Y#4X+|0qo!0P-a=WJF&ki$cGq+P%h9 zzRPM(qk+-MG{}3Z8ll`|;4M22Lo`K(?V=M@n)s3{Yu3q?)ylJu=S4=-t{}PCQpb(Bz7KH72ahm_+5S-@u{OlCfFpAI8>!@!+Dp4H6z$o=b0JJf;(P2=U~{)51LEV`$bjWS7;>cS)ySk9c3d2he^1uwtaf(&Uj5eTfV( zZG%S|fH|kLQB*lCYO3nsT9~zS=FFM?wjIE73B{cxc%&b?$TLNAB$@K}oA?`;u@P!v zI6{eAy^P$7QCqm(KC#2MEuw=2wO6*0{Rr{YCmV-0r=yW)ooj*J-Fm@Vz0U>-GvM|M zstE>tJL508M{5!5o<^HODWOpGut)h?><1n-LbNa>pDB-!hGbp-a5NGD&KTL~AeXoW zQCw*WGK2E%T@R=km8rMLu3xil{%cf)NvXuIot#E-50(eHM~@!uM<$m|j9Ti)`MQuF z=K;2gO{d8(-{E)09=zmes%58~VsRf@+)v8}aMGL!el0~7P94T4Vn5U?51--+VUsS_ z>1>n1Sw>9Rm<$E`1vQpgYQ6Z?l9J-D!%G+`rV2u^C6rM401c1Ip@;HBgP&;^M}u?D z`GZT$@$b(XFS2}A4A2;`MuJSru=5E&Au~FS;DNP*yY`g12368rp8b`IBKw;$Tz_)8 z!U$!DtBsHVML!vxc)Ujw%2ZxsBX8EH(J1vJ)2=VAUS7fUe;6SaXSBN66Dd~V;yX8; zSWfoAZa9V5inxu|FKo~As%7mh~Ld~Z!vmI*hz__g&019hwk^tGS>6;L@ODWP(N zAy~wfR!F0CuM~c!733l-?ckm+z1wmAc_1t5K})cc9J7%J*W>49Ml`fauy=2umviES zZZVJSQu`8Uqk8tYZIX-Kf+gSDBQ=Zs8p?fKZXmD$!iNt1)HdRwgO0w0g)iLUD&@C! z2~}!ED}2Q|N@s{ll@-}d|M^o~5|6!@EZQg+pN5W&LXhE+4XtdEbtu-P1CCN;{Ln}x zpPlgJJw-)tQW5jHCt5{R22FJG!i}+Ck-F@tZ&52>`q9v%O3D`01`lY zFoD+M&?-W>AP|t}<3s>AMxd}gQgTSWG`DNxN;hrBEH`D!6#pFw9ya5&iYZ@4Q>dAR zH1TjY5)b;48omN-H8tT{6Xieo)b?F9ZC{r@f9gyV(vhoRW3e83@*gk;o z3GLg{JlEcz9|YAZqgxekSik=FCXkEViV9RwsDNlPgz~}$scJPu>nQ0u*VsC0?FiRT zK%!}k#Yi4HM0(hTlJAv19TV)QU?Tu*L9sn~P%YcFOW)`|`{HYVo;B zr*@F1HZU^rO4BBEubya!B>x;yv5qqRde8c5@siKp^VjF_Q(mEDk!E>Qs5(`j^6WjC zwe}9~4VM3dqm=SL2r3L_>@r(#Hd`6Sda;uuwY zHBY_VrRN_M1JKIHWO(3Wz%uYi`#hg7a0wxp$5}|as4&$HsA)Uat&811?CuWhCP#Ga za2XZxo}#ozBS!Hs4NY`r9e_>za+E7yHq(z(ZIT$ZNqg*-%LP*r>&y5^>__b;#3?N> zL%L;`+v(At>{4sH)%}B`6j?tCDoo}|Z43Rpf$$CqRV*M0L!|&R-V0FmJPdLN`9_Gq^y7Fhrp9j%ExMena@Rd&nH&Dee_ge1-P((d^rO?RFK9nM2~?P^5)S*f+In=M#osqW_y>nj z2BRFv(EtpJ3wcqR#X$in&Lq?r=oI>L0g)VYo92)7ctkTLO9s#Sm4|-lD<0CJgO9wB zpL{^U(|Hp}0_9#H6X1f!Rm-haa0R>e=6cBQL5C=m5r z5q>PRN*R_Z_RYYjY}0YJjDQ@xlqJMNLvh~N=BYq7Dk=6^*~M$t+Fxa==IUK_mmL;l z`Fo+fdCsTqz^KGdf{6322v0XT#r9cJfaE>bVzU@w(7ROuGl%9ED{mkNer6`a%Y*DV=UF)xKw&j(%#q6ebKSBhII2XoQTwI;%%N zHIh_b@?v!n>|+elG#t4R2}`umSIJ(X z_{fy$Oc`Xw%Oj1lfJ*Phljb@Rh4S+9_L=ga$%lFfX!4LL9y$cm9+wuJ3=xti7q5@# zKNS8@`LKRuOTI$n#?zIjk*T&w2k4^N#%Rjw)vE^DF8wE6zJ$6;-oG_cD+(thB-v40 zReKnFtc}=q&{0s05FeqG7L9b+7&VxDKu6h7VWp9+xMYQ)@EoIP%3$s0NDpLu6t^bsE(n5a2yf`FMJKTJ;Dd z(yB{&Y9DmP4==aP%^}$Q2B%*2&Bam)&c!MP5_}dWkY$&lO6&Ry7yP2&&gegBgi2S{t2E&+0;(5ez}gy{W8l7K$_@w{K|T$VF+)X&hiQ0m zG+J~TuQ+*OoHP#E(8F@#BUIfHcl3)+;wO{~`NbnZkOQyyp{pLzkRyK4lva6o$g@q+ z$98OanysNbEd8?pMTY7oF87Opia@Kt{*Z4cW6%zuM9F0}O zp@quI5SpS@=7&O+C!~Dn!g}KMA{~~cTsU=ya)?V7q3RKhe90G0`dFIl(C6%~%jI?n z^rO36WbMyM*D&uF1r@1|@bOT=FfL=M0O?Sc=#<$X zUHJ;(k$lDXSC%}1p|WA9x)dreJ`Ek3IBF8VC((5ItTEMwxg+k|%noWK3p7S<*64C@;Rufzm3YeCmvM@BpYl zjqh0ES3YUU32D$NtM*&oO1sg0p^eZ_EsHlIe(*Y!@;~HMXUOxbfJy~c8J0@27o95G zCC^hfb)IOA^Yzi_P?-b8WqcWww0Ma_S6YoyI^98#-M+l(g*@40a+YsG0bLNa^jr<=? zx5y2h+OQ7|<$i5v75h)FT5s3%*4E!ev`3XLRvC?=&9O5ZR~{Dc@Xo)ab&y4LC9i7xGCmoe0{MD!5urgm^q=g69ZU~%imq0h0 zFZ2!4Ot9BIRaYKmR{oN3@*X{2^C5O$DP8HE&8W8hI-bfv}r zLm?dqClFOubrXh8^{FoLS^1eJ>rn&qMdJs|Uwo2!1ic#Vf?b-djrddQ~P z@y7aJ0~5V)`)m9EIjE6pUO5nCT29W(%d2Uh+WEa1@I+I(nS~L$K_g`J5D3ZoPeU1s z5cx_Y*XlJ=`63J7wzuLQTfTfbkIwQS&96GmQuqE`sGIVCGoVT#LQ@oQnVOTEHf`F% zHdQ=f(Z}d*jOItM8iUb8Z}}A?4*G$d%7-CwdC7^%U_{O~AjjFw?|;~{!}Bd4Aemyn zzb!scrN07Q`iG)_lb}jLQd`!VcPK4UMIq`6?FY>(F@k_}g5RW$5yke+hYkW}9Kd?XEQzUukRQ0^7NMWv|@x zwG+T&6#DSD0;1`&kBdyQ56LC)MX~>1olS!p$pSkJiQ^PTspwbpG9e!D!m!-zBA%$k kZ}gYfNaCF}xV$|1>H6z0+kD +#include +#include +#include +#include "controller.h" +#include "log.h" +#include "resource_camera.h" + +#define EVENT_INTERVAL_SECOND 1.0f +#define CAMERA_CAPTURE_INTERVAL_MS 10000 +#define IMAGE_FILE_PREFIX "CAM_" + +typedef struct app_data_s { + Ecore_Timer *event_timer; +} app_data; + +static long long int __get_monotonic_ms(void) +{ + long long int ret_time = 0; + struct timespec time_s; + + if (0 == clock_gettime(CLOCK_MONOTONIC, &time_s)) + ret_time = time_s.tv_sec* 1000 + time_s.tv_nsec / 1000000; + else + _E("Failed to get ms"); + + return ret_time; +} + +static int __image_data_to_file(const char *filename, const void *image_data, unsigned int size) +{ + FILE *fp = NULL; + char *data_path = NULL; + char file[PATH_MAX] = {'\0', }; + + // 실습 8. 파일로 저장하기 + data_path = app_get_data_path(); + + snprintf(file, PATH_MAX, "%s%s.jpg", data_path, filename); + free(data_path); + data_path = NULL; + + _D("File : %s", file); + + fp = fopen(file, "w"); + if (!fp) { + _E("Failed to open file: %s", file); + return -1; + } + + if (fwrite(image_data, size, 1, fp) != 1) { + _E("Failed to write image to file : %s", file); + fclose(fp); + return -1; + } + + fclose(fp); + + return 0; +} + +static void __resource_camera_capture_completed_cb(const void *image, unsigned int size, void *user_data) +{ + char filename[PATH_MAX] = {'\0', }; + + snprintf(filename, PATH_MAX, "%s%lld", IMAGE_FILE_PREFIX, __get_monotonic_ms()); + + __image_data_to_file(filename, image, size); +} + +static Eina_Bool _control_interval_event_cb(void *data) +{ + int ret = 0; + + static long long int last_captured_time = 0; + long long int now = __get_monotonic_ms(); + + if (now > last_captured_time + CAMERA_CAPTURE_INTERVAL_MS) { +// 실습 2. 촬영 시작 + ret = resource_camera_capture(__resource_camera_capture_completed_cb, NULL); + if (ret < 0) + _E("Failed to capture camera"); + + last_captured_time = now; + } + + return ECORE_CALLBACK_RENEW; +} + +static bool service_app_create(void *data) +{ + app_data *ad = (app_data *)data; + + // 실습 1. 타이머 추가 + ad->event_timer = ecore_timer_add(EVENT_INTERVAL_SECOND, _control_interval_event_cb, ad); + if (!ad->event_timer) { + _E("Failed to add action timer"); + return false; + } + + return true; +} + +static void service_app_terminate(void *data) +{ + app_data *ad = (app_data *)data; + + if (ad->event_timer) + ecore_timer_del(ad->event_timer); + + resource_camera_close(); + + free(ad); +} + +static void service_app_control(app_control_h app_control, void *data) +{ + /* APP_CONTROL */ +} + +static void service_app_lang_changed(app_event_info_h event_info, void *user_data) +{ + /*APP_EVENT_LANGUAGE_CHANGED*/ +} + +static void service_app_region_changed(app_event_info_h event_info, void *user_data) +{ + /*APP_EVENT_REGION_FORMAT_CHANGED*/ +} + +static void service_app_low_battery(app_event_info_h event_info, void *user_data) +{ + /*APP_EVENT_LOW_BATTERY*/ +} + +static void service_app_low_memory(app_event_info_h event_info, void *user_data) +{ + /*APP_EVENT_LOW_MEMORY*/ +} + +int main(int argc, char* argv[]) +{ + app_data *ad = NULL; + int ret = 0; + service_app_lifecycle_callback_s event_callback; + app_event_handler_h handlers[5] = {NULL, }; + + ad = calloc(1, sizeof(app_data)); + retv_if(!ad, -1); + + event_callback.create = service_app_create; + event_callback.terminate = service_app_terminate; + event_callback.app_control = service_app_control; + + service_app_add_event_handler(&handlers[APP_EVENT_LOW_BATTERY], APP_EVENT_LOW_BATTERY, service_app_low_battery, &ad); + service_app_add_event_handler(&handlers[APP_EVENT_LOW_MEMORY], APP_EVENT_LOW_MEMORY, service_app_low_memory, &ad); + service_app_add_event_handler(&handlers[APP_EVENT_LANGUAGE_CHANGED], APP_EVENT_LANGUAGE_CHANGED, service_app_lang_changed, &ad); + service_app_add_event_handler(&handlers[APP_EVENT_REGION_FORMAT_CHANGED], APP_EVENT_REGION_FORMAT_CHANGED, service_app_region_changed, &ad); + + ret = service_app_main(argc, argv, &event_callback, ad); + + return ret; +} diff --git a/src/resource_camera.c b/src/resource_camera.c new file mode 100755 index 0000000..67e5ffe --- /dev/null +++ b/src/resource_camera.c @@ -0,0 +1,401 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * 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 +#include +#include + +#include "controller.h" +#include "log.h" +#include "resource_camera.h" +#define DEFAULT_CAMERA_IMAGE_WIDTH 320 //int +#define DEFAULT_CAMERA_IMAGE_HEIGHT 240 //int +#define DEFAULT_CAMERA_IMAGE_QUALITY 100 //1~100 + +// 실습 3. 카메라 데이터 +struct __camera_data { + camera_h cam_handle; + + void *captured_file; + unsigned int image_size; + + capture_completed_cb capture_completed_cb; + void *capture_completed_cb_data; + + bool is_capturing; + bool is_focusing; + bool is_af_enabled; +}; + +static struct __camera_data *camera_data = NULL; + +static const char * __cam_err_to_str(camera_error_e err) +{ + const char *err_str; + + switch (err) { + case CAMERA_ERROR_NONE: + err_str = "CAMERA_ERROR_NONE"; + break; + case CAMERA_ERROR_INVALID_PARAMETER: + err_str = "CAMERA_ERROR_INVALID_PARAMETER"; + break; + case CAMERA_ERROR_INVALID_STATE: + err_str = "CAMERA_ERROR_INVALID_STATE"; + break; + case CAMERA_ERROR_OUT_OF_MEMORY: + err_str = "CAMERA_ERROR_OUT_OF_MEMORY"; + break; + case CAMERA_ERROR_DEVICE: + err_str = "CAMERA_ERROR_DEVICE"; + break; + case CAMERA_ERROR_INVALID_OPERATION: + err_str = "CAMERA_ERROR_INVALID_OPERATION"; + break; + case CAMERA_ERROR_SOUND_POLICY: + err_str = "CAMERA_ERROR_SOUND_POLICY"; + break; + case CAMERA_ERROR_SECURITY_RESTRICTED: + err_str = "CAMERA_ERROR_SECURITY_RESTRICTED"; + break; + case CAMERA_ERROR_DEVICE_BUSY: + err_str = "CAMERA_ERROR_DEVICE_BUSY"; + break; + case CAMERA_ERROR_DEVICE_NOT_FOUND: + err_str = "CAMERA_ERROR_DEVICE_NOT_FOUND"; + break; + case CAMERA_ERROR_SOUND_POLICY_BY_CALL: + err_str = "CAMERA_ERROR_SOUND_POLICY_BY_CALL"; + break; + case CAMERA_ERROR_SOUND_POLICY_BY_ALARM: + err_str = "CAMERA_ERROR_SOUND_POLICY_BY_ALARM"; + break; + case CAMERA_ERROR_ESD: + err_str = "CAMERA_ERROR_ESD"; + break; + case CAMERA_ERROR_PERMISSION_DENIED: + err_str = "CAMERA_ERROR_PERMISSION_DENIED"; + break; + case CAMERA_ERROR_NOT_SUPPORTED: + err_str = "CAMERA_ERROR_NOT_SUPPORTED"; + break; + case CAMERA_ERROR_RESOURCE_CONFLICT: + err_str = "CAMERA_ERROR_RESOURCE_CONFLICT"; + break; + case CAMERA_ERROR_SERVICE_DISCONNECTED: + err_str = "CAMERA_ERROR_SERVICE_DISCONNECTED"; + break; + default: + err_str = "Unknown"; + break; + } + return err_str; +} + +static void __print_thread_id(char *msg) +{ + pthread_t id; + id = pthread_self(); + _D("[%s] tid %u", msg, (unsigned int)id); + +} + +static void __print_camera_state(camera_state_e previous, camera_state_e current, bool by_policy, void *user_data) +{ + switch (current) { + case CAMERA_STATE_CREATED: + _D("Camera state: CAMERA_STATE_CREATED"); + break; + + case CAMERA_STATE_PREVIEW: + _D("Camera state: CAMERA_STATE_PREVIEW"); + break; + + case CAMERA_STATE_CAPTURING: + _D("Camera state: CAMERA_STATE_CAPTURING"); + break; + + case CAMERA_STATE_CAPTURED: + _D("Camera state: CAMERA_STATE_CAPTURED"); + break; + + default: + _D("Camera state: CAMERA_STATE_NONE"); + break; + } +} + +static bool __camera_attr_supported_af_mode_cb(camera_attr_af_mode_e mode, void *user_data) +{ + struct __camera_data *camera_data = user_data; + + _I("Auto-Focus Mode [%d]", mode); + + if (mode != CAMERA_ATTR_AF_NONE) + camera_data->is_af_enabled = true; + + return true; +} + +static void __capturing_cb(camera_image_data_s *image, camera_image_data_s *postview, camera_image_data_s *thumbnail, void *user_data) +{ + struct __camera_data *camera_data = user_data; + if (image == NULL) { + _E("Image is NULL"); + return; + } + + __print_thread_id("CAPTURING"); + + free(camera_data->captured_file); + camera_data->captured_file = malloc(image->size); + if (camera_data->captured_file == NULL) + return; + + _D("Now is on Capturing: Image size[%d x %d]", image->width, image->height); + +// 실습 6. 이미지 파일 복사 + memcpy(camera_data->captured_file, image->data, image->size); + camera_data->image_size = image->size; + + return; +} + +static void __completed_cb(void *user_data) +{ + int ret = 0; + struct __camera_data *camera_data = user_data; + + _D("Capture is completed"); + +// 실습 7. 촬영 종료 + if (camera_data->capture_completed_cb) + camera_data->capture_completed_cb(camera_data->captured_file, camera_data->image_size, camera_data->capture_completed_cb_data); + + camera_data->capture_completed_cb = NULL; + free(camera_data->captured_file); + camera_data->captured_file = NULL; + + if (!camera_data->cam_handle) { + _E("Camera is NULL"); + return; + } + + ret = camera_start_preview(camera_data->cam_handle); + if (ret != CAMERA_ERROR_NONE) { + _E("Failed to start preview [%s]", __cam_err_to_str(ret)); + return; + } + + ret = camera_stop_preview(camera_data->cam_handle); + if (ret != CAMERA_ERROR_NONE) { + _E("Failed to stop preview [%s]", __cam_err_to_str(ret)); + return; + } + + if (camera_data->is_focusing) + camera_data->is_focusing = false; + + if (camera_data->is_capturing) + camera_data->is_capturing = false; + + return; +} + +static void __start_capture(void *user_data) +{ + int ret = 0; + struct __camera_data *camera_data = user_data; + + ret = camera_start_capture(camera_data->cam_handle, __capturing_cb, __completed_cb, camera_data); + if (ret != CAMERA_ERROR_NONE) { + _E("Failed to start capturing [%s]", __cam_err_to_str(ret)); + camera_data->is_focusing = false; + return; + } + + camera_data->is_capturing = true; +} + +static void __camera_focus_cb(camera_focus_state_e state, void *user_data) +{ + struct __camera_data *camera_data = user_data; + _D("Camera focus state: [%d]", state); + + if (camera_data->is_af_enabled && state == CAMERA_FOCUS_STATE_FOCUSED && !camera_data->is_capturing) { + __start_capture(camera_data); + } +} + +static void __camera_preview_cb(camera_preview_data_s *frame, void *user_data) +{ + __print_thread_id("PREVIEW Callback"); +} + +static int __init(void) +{ + int ret = CAMERA_ERROR_NONE; + + camera_data = malloc(sizeof(struct __camera_data)); + if (camera_data == NULL) { + _E("Failed to allocate Camera data"); + return -1; + } + memset(camera_data, 0, sizeof(struct __camera_data)); + + ret = camera_create(CAMERA_DEVICE_CAMERA0, &(camera_data->cam_handle)); + if (ret != CAMERA_ERROR_NONE) { + _E("Failed to create camera [%s]", __cam_err_to_str(ret)); + goto ERROR; + } + + ret = camera_attr_set_image_quality(camera_data->cam_handle, DEFAULT_CAMERA_IMAGE_QUALITY); + if (ret != CAMERA_ERROR_NONE) { + _E("Failed to set image quality [%s]", __cam_err_to_str(ret)); + goto ERROR; + } + + ret = camera_set_preview_resolution(camera_data->cam_handle, DEFAULT_CAMERA_IMAGE_WIDTH, DEFAULT_CAMERA_IMAGE_HEIGHT); + if (ret != CAMERA_ERROR_NONE) { + _E("Failed to set preview resolution [%s]", __cam_err_to_str(ret)); + goto ERROR; + } + + ret = camera_set_capture_resolution(camera_data->cam_handle, DEFAULT_CAMERA_IMAGE_WIDTH, DEFAULT_CAMERA_IMAGE_HEIGHT); + if (ret != CAMERA_ERROR_NONE) { + _E("Failed to set capture resolution [%s]", __cam_err_to_str(ret)); + goto ERROR; + } + + ret = camera_set_capture_format(camera_data->cam_handle, CAMERA_PIXEL_FORMAT_JPEG); + if (ret != CAMERA_ERROR_NONE) { + _E("Failed to set capture format [%s]", __cam_err_to_str(ret)); + goto ERROR; + } + + ret = camera_set_state_changed_cb(camera_data->cam_handle, __print_camera_state, NULL); + if (ret != CAMERA_ERROR_NONE) { + _E("Failed to set state changed callback [%s]", __cam_err_to_str(ret)); + goto ERROR; + } + +// 실습 4. 카메라 초기화 + ret = camera_set_preview_cb(camera_data->cam_handle, __camera_preview_cb, camera_data); + if (ret != CAMERA_ERROR_NONE) { + _E("Failed to set preview callback [%s]", __cam_err_to_str(ret)); + goto ERROR; + } + + ret = camera_set_focus_changed_cb(camera_data->cam_handle, __camera_focus_cb, camera_data); + if (ret != CAMERA_ERROR_NONE) { + _E("Failed to set focus changed callback [%s]", __cam_err_to_str(ret)); + goto ERROR; + } + + ret = camera_attr_foreach_supported_af_mode(camera_data->cam_handle, __camera_attr_supported_af_mode_cb, camera_data); + if (ret != CAMERA_ERROR_NONE) { + _E("Failed to set auto focus attribute check callback [%s]", __cam_err_to_str(ret)); + goto ERROR; + } + + return 0; + +ERROR: + if (camera_data->cam_handle) + camera_destroy(camera_data->cam_handle); + + free(camera_data); + camera_data = NULL; + return -1; +} + +int resource_camera_capture(capture_completed_cb capture_completed_cb, void *user_data) +{ + camera_state_e state; + int ret = CAMERA_ERROR_NONE; + + if (camera_data == NULL) { + _I("Camera is not initialized"); + ret = __init(); + if (ret < 0) { + _E("Failed to initialize camera"); + return -1; + } + } + + ret = camera_get_state(camera_data->cam_handle, &state); + if (ret != CAMERA_ERROR_NONE) { + _E("Failed to get camera state [%s]", __cam_err_to_str(ret)); + return -1; + } + + if (state == CAMERA_STATE_CAPTURING) { + _D("Camera is now capturing"); + return -1; + } + + if (state == CAMERA_STATE_PREVIEW) { + _I("Capturing is not completed"); + ret = camera_stop_preview(camera_data->cam_handle); + if (ret != CAMERA_ERROR_NONE) { + _E("Failed to stop preview [%s]", __cam_err_to_str(ret)); + return -1; + } + camera_data->is_capturing = false; + camera_data->is_focusing = false; + } + + // 실습 5. 사진 찍기 + camera_data->capture_completed_cb = capture_completed_cb; + camera_data->capture_completed_cb_data = user_data; + + ret = camera_start_preview(camera_data->cam_handle); + if (ret != CAMERA_ERROR_NONE) { + _E("Failed to start preview [%s]", __cam_err_to_str(ret)); + } + + if (!camera_data->is_af_enabled) { + __start_capture(camera_data); + } else { + ret = camera_start_focusing(camera_data->cam_handle, true); + + if (ret == CAMERA_ERROR_NOT_SUPPORTED) { + camera_data->is_af_enabled = false; + return -1; + } + + camera_data->is_focusing = true; + } + + return 0; +} + +void resource_camera_close(void) +{ + if (camera_data == NULL) + return; + + camera_stop_preview(camera_data->cam_handle); + + camera_destroy(camera_data->cam_handle); + camera_data->cam_handle = NULL; + + free(camera_data->captured_file); + camera_data->captured_file = NULL; + + free(camera_data); + camera_data = NULL; +} diff --git a/tizen-manifest.xml b/tizen-manifest.xml new file mode 100755 index 0000000..71aeceb --- /dev/null +++ b/tizen-manifest.xml @@ -0,0 +1,11 @@ + + + + + + icon.png + + + http://tizen.org/privilege/camera + + -- 2.7.4