1 /*
2  * Copyright (C) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <config.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <libexif/i18n.h>
20 #include "mnote-huawei-tag.h"
21 
22 typedef struct _MnoteHuaweiTable		MnoteHuaweiTable;
23 
24 struct _MnoteHuaweiTable {
25 	MnoteHuaweiTag tag;
26 	const char *name;
27 	const char *title;
28 	const char *description;
29 	MnoteHuaweiTagType TagType;
30 };
31 
32 static const MnoteHuaweiTable huawei_table[] = {
33 	{MNOTE_HUAWEI_CAPTURE_MODE, "HwMnoteCaptureMode", N_("Capture Mode"), "CaptureMode"},
34 	{MNOTE_HUAWEI_BURST_NUMBER, "HwMnoteBurstNumber", N_("Burst Number"), "BurstNumber"},
35 	{MNOTE_HUAWEI_FRONT_CAMERA, "HwMnoteFrontCamera", N_("Front Camera"), "FrontCamera"},
36 	{MNOTE_HUAWEI_ROLL_ANGLE, "HwMnoteRollAngle", N_("Roll Angle"), "RollAngle"},
37 	{MNOTE_HUAWEI_PITCH_ANGLE, "HwMnotePitchAngle", N_("Pitch Angle"), "PitchAngle"},
38 	{MNOTE_HUAWEI_PHYSICAL_APERTURE, "HwMnotePhysicalAperture", N_("Physical Aperture"), "PhysicalAperture"},
39     {MNOTE_HUAWEI_IS_XMAGE_SUPPORTED, "HwMnoteIsXmageSupported", N_("Is Xmage Supported"), "IsXmageSupported"},
40     {MNOTE_HUAWEI_XMAGE_MODE, "HwMnoteXmageMode", N_("Xmage Mode"), "XmageMode"},
41     {MNOTE_HUAWEI_XMAGE_LEFT, "HwMnoteXmageLeft", N_("Xmage Left"), "XmageLeft"},
42     {MNOTE_HUAWEI_XMAGE_TOP, "HwMnoteXmageTop", N_("Xmage Top"), "XmageTop"},
43     {MNOTE_HUAWEI_XMAGE_RIGHT, "HwMnoteXmageRight", N_("Xmage Right"), "XmageRight"},
44     {MNOTE_HUAWEI_XMAGE_BOTTOM, "HwMnoteXmageBottom", N_("Xmage Bottom"), "XmageBottom"},
45     {MNOTE_HUAWEI_CLOUD_ENHANCEMENT_MODE, "HwMnoteCloudEnhancementMode", N_("Cloud Enhancement Mode"), "CloudEnhancementMode"},
46     {MNOTE_HUAWEI_FOCUS_MODE, "HwMnoteFocusMode", N_("Focus Mode"), "FocusMode"},
47     {MNOTE_HUAWEI_WIND_SNAPSHOT_MODE, "HwMnoteWindSnapshotMode", N_("Wind Snapshot Mode"), "WindSnapshotMode"},
48 	{MNOTE_MOVING_PHOTO_VERSION, "MovingPhotoVersion", N_("Moving Photo Version"),
49 	"MovingPhotoVersion"},
50 	{MNOTE_MICRO_VIDEO_PRESENTATION_TIMESTAMP_US, "MicroVideoPresentationTimestampUS",
51 	N_("Video Presentation Timestamp US"), "VideoPresentationTimestampUS"},
52     {MNOTE_MOVING_PHOTO_ID, "MovingPhotoId", N_("Moving Photo Id"), "MovingPhotoId"},
53 
54 	{0, "HwUnknow", N_("Unknow Tag"), "UnknowTag"},
55 };
56 
57 static const MnoteHuaweiTable huawei_face_table[] = {
58 	{MNOTE_HUAWEI_FACE_INFO, "HwMnoteFacePointer", N_("Face Info"), "FaceInfo", MNOTE_HUAWEI_TAG_TYPE_IFD},
59 	{MNOTE_HUAWEI_FACE_VERSION, "HwMnoteFaceVersion", N_("Face Version"), "FaceVersion"},
60 	{MNOTE_HUAWEI_FACE_COUNT, "HwMnoteFaceCount", N_("Count"), "Count"},
61 	{MNOTE_HUAWEI_FACE_CONF, "HwMnoteFaceConf", N_("Conf"), "Conf"},
62 	{MNOTE_HUAWEI_FACE_SMILE_SCORE, "HwMnoteFaceSmileScore", N_("Smile Score"), "SmileScore"},
63 	{MNOTE_HUAWEI_FACE_RECT, "HwMnoteFaceRect", N_("Rect"), "Rect"},
64 	{MNOTE_HUAWEI_FACE_LEYE_CENTER, "HwMnoteFaceLeyeCenter", N_("LeyeCenter"), "LeyeCenter"},
65 	{MNOTE_HUAWEI_FACE_REYE_CENTER, "HwMnoteFaceReyeCenter", N_("Reye Center"), "ReyeCenter"},
66 	{MNOTE_HUAWEI_FACE_MOUTH_CENTER, "HwMnoteFaceMouthCenter", N_("Mouth Center"), "MouthCenter"},
67 
68 	{0, "HwUnknow", N_("Unknow Tag"), "UnknowTag"},
69 };
70 
71 static const MnoteHuaweiTable huawei_scene_table[] = {
72 	{MNOTE_HUAWEI_SCENE_INFO, "HwMnoteScenePointer", N_("Scene Info"), "SceneInfo", MNOTE_HUAWEI_TAG_TYPE_IFD},
73 	{MNOTE_HUAWEI_SCENE_VERSION, "HwMnoteSceneVersion", N_("Scene Version"), "SceneVersion"},
74 	{MNOTE_HUAWEI_SCENE_FOOD_CONF, "HwMnoteSceneFoodConf", N_("Food Conf"), "FoodConf"},
75 	{MNOTE_HUAWEI_SCENE_STAGE_CONF, "HwMnoteSceneStageConf", N_("Stage Conf"), "StageConf"},
76 	{MNOTE_HUAWEI_SCENE_BLUESKY_CONF, "HwMnoteSceneBlueSkyConf", N_("Blue Sky Conf"), "BlueSkyConf"},
77 	{MNOTE_HUAWEI_SCENE_GREENPLANT_CONF, "HwMnoteSceneGreenPlantConf", N_("GreenPlant Conf"), "GreenPlantConf"},
78 	{MNOTE_HUAWEI_SCENE_BEACH_CONF, "HwMnoteSceneBeachConf", N_("Beach Conf"), "BeachConf"},
79 	{MNOTE_HUAWEI_SCENE_SNOW_CONF, "HwMnoteSceneSnowConf", N_("Snow Conf"), "SnowConf"},
80 	{MNOTE_HUAWEI_SCENE_SUNSET_CONF, "HwMnoteSceneSunsetConf", N_("Sunset Conf"), "SunsetConf"},
81 	{MNOTE_HUAWEI_SCENE_FLOWERS_CONF, "HwMnoteSceneFlowersConf", N_("Flowers Conf"), "FlowersConf"},
82 	{MNOTE_HUAWEI_SCENE_NIGHT_CONF, "HwMnoteSceneNightConf", N_("Night Conf"), "NightConf"},
83 	{MNOTE_HUAWEI_SCENE_TEXT_CONF, "HwMnoteSceneTextConf", N_("Text Conf"), "TextConf"},
84 
85 	{0, "HwUnknow", N_("Unknow Tag"), "UnknowTag"},
86 };
87 
88 #define GET_TAG_INFO(tb, tb_size, tag, idx, ret) do {	\
89 									for (int i = 0; i<tb_size; i++) { \
90 										if (tb[i].tag == tag) {ret = tb[i].idx; return ret;}\
91 									} \
92 									ret = tb[tb_size-1].idx;\
93 								} while (0)
94 
95 const int HUAWEI_TABLE = 9;
96 const int HUAWEI_FACE_TABLE = 8;
97 
get_tag_table(MnoteHuaweiTag tag, int* size)98 const MnoteHuaweiTable* get_tag_table(MnoteHuaweiTag tag, int* size)
99 {
100 	if ((tag >> HUAWEI_TABLE) & 1) {
101 		*size = sizeof (huawei_table) / sizeof (huawei_table[0]);
102 		return huawei_table;
103 	}
104 
105 	if ((tag >> HUAWEI_FACE_TABLE) & 1) {
106 		*size = sizeof (huawei_face_table) / sizeof (huawei_face_table[0]);
107 		return huawei_face_table;
108 	}
109 
110 	*size = sizeof (huawei_scene_table) / sizeof (huawei_scene_table[0]);
111 	return huawei_scene_table;
112 }
113 
get_tag_owner_tag(MnoteHuaweiTag tag)114 MnoteHuaweiTag get_tag_owner_tag(MnoteHuaweiTag tag)
115 {
116 	MnoteHuaweiTag owner_tag = MNOTE_HUAWEI_INFO;
117 	do {
118 		if (((tag >> HUAWEI_TABLE) & 1) ||
119 			(tag == MNOTE_HUAWEI_FACE_INFO) ||
120 			(tag == MNOTE_HUAWEI_SCENE_INFO))
121 			break;
122 
123 		if ((tag >> HUAWEI_FACE_TABLE) & 1) {
124 			owner_tag = MNOTE_HUAWEI_FACE_INFO;
125 			break;
126 		}
127 
128 		owner_tag = MNOTE_HUAWEI_SCENE_INFO;
129 	} while(0);
130 	return owner_tag;
131 }
132 
is_ifd_tag(MnoteHuaweiTag tag)133 int is_ifd_tag(MnoteHuaweiTag tag)
134 {
135 	int b = 0;
136 	if ((tag == MNOTE_HUAWEI_INFO) ||
137 		(tag == MNOTE_HUAWEI_FACE_INFO) ||
138 		(tag == MNOTE_HUAWEI_SCENE_INFO))
139 		b = 1;
140 	return b;
141 }
142 
mnote_huawei_tag_from_name(const char *name)143 MnoteHuaweiTag mnote_huawei_tag_from_name(const char *name)
144 {
145 	int i;
146 	MnoteHuaweiTag hw_tag = MNOTE_HUAWEI_INFO;
147 	int size = sizeof (huawei_table) / sizeof (huawei_table[0]) - 1;
148 	for (i = 0; i < size; i++) {
149 		if (!strcmp(huawei_table[i].name, name)) {
150 			hw_tag = huawei_table[i].tag;
151 			goto End;
152 		}
153 	}
154 
155 	size = sizeof (huawei_face_table) / sizeof (huawei_face_table[0]) - 1;
156 	for (i = 0; i < size; i++) {
157 		if (!strcmp(huawei_face_table[i].name, name)) {
158 			hw_tag = huawei_face_table[i].tag;
159 			goto End;
160 		}
161 	}
162 
163 	size = sizeof (huawei_scene_table) / sizeof (huawei_scene_table[0]) - 1;
164 	for (i = 0; i < size; i++) {
165 		if (!strcmp(huawei_scene_table[i].name, name)) {
166 			hw_tag = huawei_scene_table[i].tag;
167 			goto End;
168 		}
169 	}
170 
171 End:
172 	return hw_tag;
173 }
174 
175 const char *
mnote_huawei_tag_get_name(MnoteHuaweiTag tag)176 mnote_huawei_tag_get_name (MnoteHuaweiTag tag)
177 {
178 	const char* p = NULL;
179 	int size = 0;
180 	const MnoteHuaweiTable* tb = get_tag_table(tag, &size);
181 	GET_TAG_INFO(tb, size, tag, name, p);
182 	return p;
183 }
184 
185 const char *
mnote_huawei_tag_get_title(MnoteHuaweiTag tag)186 mnote_huawei_tag_get_title (MnoteHuaweiTag tag)
187 {
188 	const char* p = NULL;
189 	int size = 0;
190 	const MnoteHuaweiTable* tb = get_tag_table(tag, &size);
191 	GET_TAG_INFO(tb, size, tag, title, p);
192 	return p;
193 }
194 
195 const char *
mnote_huawei_tag_get_description(MnoteHuaweiTag tag)196 mnote_huawei_tag_get_description (MnoteHuaweiTag tag)
197 {
198 	const char* p = NULL;
199 	int size = 0;
200 	const MnoteHuaweiTable* tb = get_tag_table(tag, &size);
201 	GET_TAG_INFO(tb, size, tag, description, p);
202 	return p;
203 }
204 
205 MnoteHuaweiTagType
mnote_huawei_tag_type(MnoteHuaweiTag tag)206 mnote_huawei_tag_type (MnoteHuaweiTag tag)
207 {
208 	MnoteHuaweiTagType p = 0;
209 	int size = 0;
210 	const MnoteHuaweiTable* tb = get_tag_table(tag, &size);
211 	GET_TAG_INFO(tb, size, tag, TagType, p);
212 	return p;
213 }
214