resetting manifest requested domain to floor
[platform/upstream/libexif.git] / libexif / samsung / mnote-samsung-entry.c
1 /*
2  * libexif
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Sangchul Lee <sc11.lee@samsung.com>
7  *
8  * This library is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU Lesser General Public License as published by the
10  * Free Software Foundation; either version 2.1 of the License, or (at your option)
11  * any later version.
12  *
13  * This library is distributed in the hope that it will be useful, but WITHOUT ANY
14  * WARRANTY; without even the implied warranty of MERCHANTABILITY or
15  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16  * License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with this library; if not, write to the Free Software Foundation, Inc., 51
20  * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  *
22  */
23
24 #include <config.h>
25 #include "mnote-samsung-entry.h"
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30
31 #include <libexif/exif-format.h>
32 #include <libexif/exif-utils.h>
33 #include <libexif/exif-entry.h>
34 #include <libexif/i18n.h>
35
36 #define CF(format,target,v,maxlen)                              \
37 {                                                               \
38         if (format != target) {                                 \
39                 snprintf (v, maxlen,                            \
40                         _("Invalid format '%s', "               \
41                         "expected '%s'."),                      \
42                         exif_format_get_name (format),          \
43                         exif_format_get_name (target));         \
44                 break;                                          \
45         }                                                       \
46 }
47
48 #define CF2(format,target1,target2,v,maxlen)                    \
49 {                                                               \
50         if ((format != target1) && (format != target2)) {       \
51                 snprintf (v, maxlen,                            \
52                         _("Invalid format '%s', "               \
53                         "expected '%s' or '%s'."),              \
54                         exif_format_get_name (format),          \
55                         exif_format_get_name (target1),         \
56                         exif_format_get_name (target2));        \
57                 break;                                          \
58         }                                                       \
59 }
60
61 #define CC(number,target,v,maxlen)                                      \
62 {                                                                       \
63         if (number != target) {                                         \
64                 snprintf (v, maxlen,                                    \
65                         _("Invalid number of components (%i, "          \
66                         "expected %i)."), (int) number, (int) target);  \
67                 break;                                                  \
68         }                                                               \
69 }
70
71 #define CC2(number,t1,t2,v,maxlen)                                      \
72 {                                                                       \
73         if ((number < t1) || (number > t2)) {                           \
74                 snprintf (v, maxlen,                                    \
75                         _("Invalid number of components (%i, "          \
76                         "expected %i or %i)."), (int) number,           \
77                         (int) t1, (int) t2);                            \
78                 break;                                                  \
79         }                                                               \
80 }
81
82 static const struct {
83         ExifTag tag;
84         ExifFormat fmt;
85         struct {
86                 int index;
87                 const char *string;
88         } elem[20];
89 } items[] = {
90 #ifndef NO_VERBOSE_TAG_DATA
91   { MNOTE_SAMSUNG_TAG_MNOTE_VERSION, EXIF_FORMAT_UNDEFINED,
92     { {0x30313030, N_("MakerNote Version")},
93       {0, NULL}}},
94   { MNOTE_SAMSUNG_TAG_DEVICE_ID, EXIF_FORMAT_LONG,
95     { {0x00001000, N_("Compact")},
96       {0x00002000, N_("DSLR")},
97       {0x00003000, N_("Camcorder")},
98       {0, NULL}}},
99   { MNOTE_SAMSUNG_TAG_SERIAL_NUM, EXIF_FORMAT_ASCII,
100     { {0, NULL}}},
101   { MNOTE_SAMSUNG_TAG_FAVOR_TAGGING, EXIF_FORMAT_LONG,
102     { {0x00000000, N_("Bad")},
103       {0x00000001, N_("Good")},
104       {0, NULL}}},
105   { MNOTE_SAMSUNG_TAG_SRW_COMPRESS, EXIF_FORMAT_LONG,
106     { {0x00000000, N_("Uncompressed Mode")},
107       {0x00000001, N_("Lossless Compression Mode (Type 1)")},
108       {0x00000002, N_("Lossless Compression Mode (Type 2)")},
109       {0, NULL}}},
110   { MNOTE_SAMSUNG_TAG_COLOR_SPACE, EXIF_FORMAT_LONG,
111     { {0x00000001, N_("sRGB (Standard RGB)")},
112       {0x0000FFFF, N_("Adobe RGB (Adobe RGB)")},
113       {0, NULL}}},
114   { MNOTE_SAMSUNG_TAG_SCENE_RESULT, EXIF_FORMAT_LONG,
115     { {0x00000000, N_("Smart")},
116       {0x00000001, N_("Portrait")},
117       {0x00000002, N_("Night")},
118       {0x00000003, N_("Night Portrait")},
119       {0x00000004, N_("Backlight")},
120       {0x00000005, N_("Backlight Portrait")},
121       {0x00000006, N_("Macro")},
122       {0x00000007, N_("White")},
123       {0x00000008, N_("Landscape")},
124       {0x00000009, N_("Macro Text")},
125       {0x0000000A, N_("BLSunset")},
126       {0x0000000B, N_("Bluesky")},
127       {0x0000000C, N_("Macro Portrait")},
128       {0x0000000D, N_("Natural Green")},
129       {0x0000000E, N_("Color")},
130       {0x0000000F, N_("Color Hidden")},
131       {0x00000010, N_("Tripod")},
132       {0x00000011, N_("Action")},
133       {0, NULL}}},
134   { MNOTE_SAMSUNG_TAG_FACE_DETECTION, EXIF_FORMAT_LONG,
135     { {0x00000000, N_("FALSE")},
136       {0x00000001, N_("TRUE")},
137       {0, NULL}}},
138   { MNOTE_SAMSUNG_TAG_FACE_RECOG, EXIF_FORMAT_LONG,
139     { {0x00000000, N_("FALSE")},
140       {0x00000001, N_("TRUE")},
141       {0, NULL}}},
142
143 #endif
144   { 0, 0, { { 0, NULL } } }
145 };
146
147 static const struct {
148         ExifTag tag;
149         ExifFormat fmt;
150         struct {
151                 short index;
152                 const char *string;
153         } elem[20];
154 } subitems[] = {
155 #ifndef NO_VERBOSE_TAG_DATA
156   { MNOTE_SAMSUNG_SUBTAG_MODEL_ID_CLASS, EXIF_FORMAT_UNDEFINED,
157     { {0x1, N_("Essential")},
158       {0x2, N_("PlusOnel")},
159       {0x3, N_("Intelligent")},
160       {0x4, N_("Style")},
161       {0x5, N_("Wannabe")},
162       {0x6, N_("Expertise")},
163       {0x7, N_("NX")},
164       {0x8, N_("GX")},
165       {0x9, N_("HD")},
166       {0xA, N_("SD")},
167       {0, NULL}}},
168   { MNOTE_SAMSUNG_SUBTAG_MODEL_ID_DEVEL, EXIF_FORMAT_UNDEFINED,
169     { {0x0, N_("OWN")},
170       {0x7, N_("TSOE")},
171       {0xA, N_("ODM")},
172       {0, NULL}}},
173   { MNOTE_SAMSUNG_SUBTAG_COLOR_ID, EXIF_FORMAT_SHORT,
174     { {0x0000, N_("Red")},
175       {0x0100, N_("Yellow")},
176       {0x0200, N_("Green")},
177       {0x0300, N_("Blue")},
178       {0x0400, N_("Magenta")},
179       {0x0500, N_("Black")},
180       {0x0600, N_("Gray")},
181       {0x0700, N_("Un-classification")},
182       {0, NULL}}},
183 #endif
184   { 0, 0, { { 0, NULL } } }
185 };
186
187
188 /*for setting data in an entry*/
189 void mnote_samsung_entry_set_value_by_index (MnoteSamsungEntry *entry, int index)
190 {
191         int i;
192         unsigned char* v;
193
194         v = entry->data;
195         for (i = 0; (items[i].tag != entry->tag); i++);
196         exif_set_long(v, entry->order,(ExifLong)items[i].elem[index].index);
197 }
198
199 void mnote_samsung_entry_set_value_by_subtag (MnoteSamsungEntry *entry, MnoteSamsungSubTag stag1, int sindex1, MnoteSamsungSubTag stag2, int sindex2, ExifShort sval)
200 {
201
202         unsigned char* v;
203         ExifLong result = 0;
204         int i;
205
206         switch(entry->tag){
207                 case MNOTE_SAMSUNG_TAG_MODEL_ID:
208                         v = entry->data;
209                         for(i = 0 ; (subitems[i].tag != stag1) ; i++);
210                         result |= subitems[i].elem[sindex1].index;
211                         result <<= 4;
212                         for(i = 0 ; (subitems[i].tag != stag2) ; i++);
213                         result |= subitems[i].elem[sindex2].index;
214                         result <<= 20;
215                         result |= sval;
216                         exif_set_long(v, entry->order, result);
217                         break;
218
219                 case MNOTE_SAMSUNG_TAG_COLOR_INFO:
220                         v = entry->data;
221                         for(i = 0 ; (subitems[i].tag != stag1) ; i++);
222                         result |= subitems[i].elem[sindex1].index;
223                         result <<= 16;
224                         result |= sval;
225                         exif_set_long(v, entry->order, result);
226                         break;
227
228                 default:
229                         fprintf (stdout,_("inappropriate using mnote_samsung_entry_set_value_by_subtag - %i bytes"), entry->size);
230                         break;
231
232         }
233
234 }
235
236 void mnote_samsung_entry_set_value_by_string (MnoteSamsungEntry *entry, unsigned char* string, unsigned int len)
237 {
238         /* for MNOTE_TAG_SERIAL_NUM */
239         int i;
240         unsigned char* v;
241
242         v = entry->data;
243         for (i = 0; (items[i].tag != entry->tag); i++);
244         if(items[i].elem[0].string == NULL)
245                 strncpy(v, string, len);
246 }
247
248 char *mnote_samsung_entry_get_value (const MnoteSamsungEntry *entry, char *v, unsigned int maxlen)
249 {
250         char buf[30]={0};
251         char v1[512]={0};
252         size_t v1_maxlen= sizeof(v1);
253         ExifLong     vl;
254         ExifShort    vs = 0,vs1 = 0;
255         ExifRational vr;
256         ExifSRational vsr;
257         int i, j;
258         char c, c1;
259         double r;
260
261         if (!entry)
262                 return (NULL);
263
264         memset (v, 0, maxlen);
265         maxlen--;
266
267         if ((!entry->data) && (entry->components > 0))
268                 return (v);
269
270         switch (entry->tag) {
271
272         case MNOTE_SAMSUNG_TAG_MNOTE_VERSION:
273                 CF (entry->format,  EXIF_FORMAT_UNDEFINED, v, maxlen);
274                 CC (entry->components, 4, v, maxlen);
275                 vl = exif_get_long (entry->data, entry->order);
276                 snprintf (v, maxlen, _("Samsung MakerNote Version: %li"), (long int)vl);
277                 break;
278
279         case MNOTE_SAMSUNG_TAG_DEVICE_ID:
280                 CF (entry->format,  EXIF_FORMAT_LONG, v, maxlen);
281                 CC (entry->components, 1, v, maxlen);
282                 vl = exif_get_long (entry->data, entry->order);
283
284                 for (i = 0; (items[i].tag != entry->tag); i++);
285                 if (!items[i].tag) {
286                         snprintf (v, maxlen, _("Internal error (unknown value %li)"),(long int) vl);
287                         break;
288                 }
289                 CF (entry->format, items[i].fmt, v, maxlen);
290                 /* find the value */
291                 for (j = 0; items[i].elem[j].string && (items[i].elem[j].index < vl); j++);
292                 if (items[i].elem[j].index != vl) {
293                         snprintf (v, maxlen, _("Unknown value %li"), (long int)vl);
294                         break;
295                 }
296
297                 snprintf (v, maxlen, _("Device ID: %s"),  _(items[i].elem[j].string));
298                 break;
299
300         case MNOTE_SAMSUNG_TAG_MODEL_ID:
301                 CF (entry->format,  EXIF_FORMAT_LONG, v, maxlen);
302                 CC (entry->components, 1, v, maxlen);
303                 vl = exif_get_long (entry->data, entry->order);
304                 c = vl >> 24;                           /* Class info */
305                 c1 = vl >> 20;                          /* Development info */
306                 c1 = ~(c << 4) & c1;
307                 vs = (ExifShort)(0x0000FFFF & vl);      /* PID */
308
309                 for (i = 0; (subitems[i].tag != MNOTE_SAMSUNG_SUBTAG_MODEL_ID_CLASS); i++);
310                 CF (EXIF_FORMAT_UNDEFINED, subitems[i].fmt, v, maxlen);
311                 /* find the value */
312                 for (j = 0; subitems[i].elem[j].string && (subitems[i].elem[j].index < c); j++);
313                 if (subitems[i].elem[j].index != c ) {
314                         snprintf (v, maxlen, _("Unknown Class info value %d in MNOTE_SAMSUNG_TAG_MODEL_ID"), c);
315                         break;
316                 }
317                 snprintf (v, maxlen, _("Model ID: ClassInfo=%s, "), _(subitems[i].elem[j].string));
318
319                 for (i = 0; (subitems[i].tag != MNOTE_SAMSUNG_SUBTAG_MODEL_ID_DEVEL); i++);
320                 CF (EXIF_FORMAT_UNDEFINED, subitems[i].fmt, v, maxlen);
321                 /* find the value */
322                 for (j = 0; subitems[i].elem[j].string && (subitems[i].elem[j].index < c1); j++);
323                 if (subitems[i].elem[j].index != c1 ) {
324                         snprintf (v, maxlen, _("Unknown Development info. value %d in MNOTE_SAMSUNG_TAG_MODEL_ID"), c1);
325                         break;
326                 }
327                 snprintf (v1, v1_maxlen, _("DevelopmentInfo=%s, PID=%d"), _(subitems[i].elem[j].string), vs);
328                 strncat (v, v1, strlen(v1));
329
330                 break;
331
332         case MNOTE_SAMSUNG_TAG_COLOR_INFO:
333                 CF (entry->format,  EXIF_FORMAT_SHORT, v, maxlen);
334                 CC (entry->components, 2, v, maxlen);
335                 vl = exif_get_long (entry->data, entry->order);
336                 vs = vl >> 16;                          /* Color ID */
337                 vs1 = (ExifShort)(0x0000FFFF & vl);     /* Color Score */
338
339                 for (i = 0; (subitems[i].tag != MNOTE_SAMSUNG_SUBTAG_COLOR_ID); i++);
340                 CF (EXIF_FORMAT_SHORT, subitems[i].fmt, v, maxlen);
341                 /* find the value */
342                 for (j = 0; subitems[i].elem[j].string && (subitems[i].elem[j].index < vs); j++);
343                 if (subitems[i].elem[j].index != vs ) {
344                         snprintf (v, maxlen, _("Unknown Color ID value %d in MNOTE_SAMSUNG_TAG_COLOR_INFO"), vs);
345                         break;
346                 }
347                 snprintf (v, maxlen, _("Color Info: ColorID=%s, ColorScore=0x%x"), _(subitems[i].elem[j].string), vs1);
348                 break;
349
350         case MNOTE_SAMSUNG_TAG_SERIAL_NUM:
351                 CF (entry->format,  EXIF_FORMAT_ASCII, v, maxlen);
352                 strncpy (v1, (char *)entry->data, MIN(v1_maxlen, entry->size));
353                 snprintf(v, maxlen, _("Serial Number: %s"), _(v1));
354                 break;
355
356         case MNOTE_SAMSUNG_TAG_IMAGE_COUNT:
357         case MNOTE_SAMSUNG_TAG_GPS_INFO01:
358         case MNOTE_SAMSUNG_TAG_GPS_INFO02:
359         case MNOTE_SAMSUNG_TAG_PREVIEW_IMAGE:
360         case MNOTE_SAMSUNG_TAG_FAVOR_TAGGING:
361                 CF (entry->format,  EXIF_FORMAT_LONG, v, maxlen);
362                 CC (entry->components, 1, v, maxlen);
363                 vl = exif_get_long (entry->data, entry->order);
364
365                 for (i = 0; (items[i].tag != entry->tag); i++);
366
367                 if (!items[i].tag) {
368                         snprintf (v, maxlen, _("Internal error (unknown value %li)"), (long int)vl);
369                         break;
370                 }
371                 CF (entry->format, items[i].fmt, v, maxlen);
372                 /* find the value */
373                 for (j = 0; items[i].elem[j].string && (items[i].elem[j].index < vl); j++);
374                 if (items[i].elem[j].index != vl) {
375                         snprintf (v, maxlen, _("Unknown value %li"),(long int) vl);
376                         break;
377                 }
378                 snprintf(v, maxlen, _("Favorite Tagging: %s"), _(items[i].elem[j].string));
379                 break;
380
381         case MNOTE_SAMSUNG_TAG_SRW_COMPRESS:
382                 CF (entry->format,  EXIF_FORMAT_LONG, v, maxlen);
383                 CC (entry->components, 1, v, maxlen);
384                 vl = exif_get_long (entry->data, entry->order);
385
386                 for (i = 0; (items[i].tag != entry->tag); i++);
387
388                 if (!items[i].tag) {
389                         snprintf (v, maxlen, _("Internal error (unknown value %li)"), (long int)vl);
390                         break;
391                 }
392                 CF (entry->format, items[i].fmt, v, maxlen);
393                 /* find the value */
394                 for (j = 0; items[i].elem[j].string && (items[i].elem[j].index < vl); j++);
395                 if (items[i].elem[j].index != vl) {
396                         snprintf (v, maxlen, _("Unknown value %li"),(long int) vl);
397                         break;
398                 }
399                 snprintf(v, maxlen, _("SRW Compression: %s"), _(items[i].elem[j].string));
400                 break;
401
402         case MNOTE_SAMSUNG_TAG_COLOR_SPACE:
403                 CF (entry->format,  EXIF_FORMAT_LONG, v, maxlen);
404                 CC (entry->components, 1, v, maxlen);
405                 vl = exif_get_long (entry->data, entry->order);
406
407                 for (i = 0; (items[i].tag != entry->tag); i++);
408
409                 if (!items[i].tag) {
410                         snprintf (v, maxlen, _("Internal error (unknown value %li)"),(long int) vl);
411                         break;
412                 }
413                 CF (entry->format, items[i].fmt, v, maxlen);
414                 /* find the value */
415                 for (j = 0; items[i].elem[j].string && (items[i].elem[j].index < vl); j++);
416                 if (items[i].elem[j].index != vl) {
417                         snprintf (v, maxlen, _("Unknown value %li"),(long int) vl);
418                         break;
419                 }
420                 snprintf(v, maxlen, _("Color Space: %s"), _(items[i].elem[j].string));
421                 break;
422
423         case MNOTE_SAMSUNG_TAG_AE:
424         case MNOTE_SAMSUNG_TAG_AF:
425         case MNOTE_SAMSUNG_TAG_AWB01:
426         case MNOTE_SAMSUNG_TAG_AWB02:
427         case MNOTE_SAMSUNG_TAG_IPC:
428         case MNOTE_SAMSUNG_TAG_SCENE_RESULT:
429                 CF (entry->format,  EXIF_FORMAT_LONG, v, maxlen);
430                 CC (entry->components, 1, v, maxlen);
431                 vl = exif_get_long (entry->data, entry->order);
432
433                 for (i = 0; (items[i].tag != entry->tag); i++);
434
435                 if (!items[i].tag) {
436                         snprintf (v, maxlen, _("Internal error (unknown value %li)"), (long int) vl);
437                         break;
438                 }
439                 CF (entry->format, items[i].fmt, v, maxlen);
440                 /* find the value */
441                 for (j = 0; items[i].elem[j].string && (items[i].elem[j].index < vl); j++);
442                 if (items[i].elem[j].index != vl) {
443                         snprintf (v, maxlen, _("Unknown value %li"), (long int) vl);
444                         break;
445                 }
446                 snprintf(v, maxlen, _("Scene Result: %s"), _(items[i].elem[j].string));
447                 break;
448
449         case MNOTE_SAMSUNG_TAG_SADEBUG_INFO01:
450         case MNOTE_SAMSUNG_TAG_SADEBUG_INFO02:
451         case MNOTE_SAMSUNG_TAG_FACE_DETECTION:
452                 CF (entry->format,  EXIF_FORMAT_LONG, v, maxlen);
453                 CC (entry->components, 1, v, maxlen);
454                 vl = exif_get_long (entry->data, entry->order);
455
456                 for (i = 0; (items[i].tag != entry->tag); i++);
457
458                 if (!items[i].tag) {
459                         snprintf (v, maxlen, _("Internal error (unknown value %li)"), (long int) vl);
460                         break;
461                 }
462                 CF (entry->format, items[i].fmt, v, maxlen);
463                 /* find the value */
464                 for (j = 0; items[i].elem[j].string && (items[i].elem[j].index < vl); j++);
465                 if (items[i].elem[j].index != vl) {
466                         snprintf (v, maxlen, _("Unknown value %li"), (long int) vl);
467                         break;
468                 }
469                 snprintf(v, maxlen, _("Face Detection: %s"), _(items[i].elem[j].string));
470                 break;
471
472         case MNOTE_SAMSUNG_TAG_FACE_FEAT01:
473         case MNOTE_SAMSUNG_TAG_FACE_FEAT02:
474         case MNOTE_SAMSUNG_TAG_FACE_RECOG:
475                 CF (entry->format,  EXIF_FORMAT_LONG, v, maxlen);
476                 CC (entry->components, 1, v, maxlen);
477                 vl = exif_get_long (entry->data, entry->order);
478
479                 for (i = 0; (items[i].tag != entry->tag); i++);
480
481                 if (!items[i].tag) {
482                         snprintf (v, maxlen, _("Internal error (unknown value %li)"),(long int) vl);
483                         break;
484                 }
485                 CF (entry->format, items[i].fmt, v, maxlen);
486                 /* find the value */
487                 for (j = 0; items[i].elem[j].string && (items[i].elem[j].index < vl); j++);
488                 if (items[i].elem[j].index != vl) {
489                         snprintf (v, maxlen, _("Unknown value %li"), (long int)vl);
490                         break;
491                 }
492                 snprintf(v, maxlen, _("Face Recognition: %s"), _(items[i].elem[j].string));
493
494                 break;
495
496         case MNOTE_SAMSUNG_TAG_LENS_INFO:
497         case MNOTE_SAMSUNG_TAG_THIRDPARTY:
498
499
500         default:
501                 switch (entry->format) {
502                 case EXIF_FORMAT_ASCII:
503                         strncpy (v, (char *)entry->data, MIN (maxlen, entry->size));
504                         break;
505                 case EXIF_FORMAT_SHORT:
506                         CC (entry->components, 1, v, maxlen);
507                         vs = exif_get_short (entry->data, entry->order);
508                         snprintf (v, maxlen, "%hu", vs);
509                         break;
510                 case EXIF_FORMAT_LONG:
511                         CC (entry->components, 1, v, maxlen);
512                         vl = exif_get_long (entry->data, entry->order);
513                         snprintf (v, maxlen, "%li", (long int) vl);
514                         break;
515                 case EXIF_FORMAT_RATIONAL:
516                         CC (entry->components, 1, v, maxlen);
517                         vr = exif_get_rational (entry->data, entry->order);
518                         if (!vr.denominator) {
519                                 strncpy (v, _("Infinite"), maxlen);
520                         } else {
521                                 r = (double)vr.numerator / vr.denominator;
522                                 snprintf (v, maxlen, "%2.3f", r);
523                         }
524                         break;
525                 case EXIF_FORMAT_SRATIONAL:
526                         CC (entry->components, 1, v, maxlen);
527                         vsr = exif_get_srational (entry->data, entry->order);
528                         if (!vsr.denominator) {
529                                 strncpy (v, _("Infinite"), maxlen);
530                         } else {
531                                 r = (double)vsr.numerator / vsr.denominator;
532                                 snprintf (v, maxlen, "%2.3f", r);
533                         }
534                         break;
535                 case EXIF_FORMAT_UNDEFINED:
536                 default:
537                         snprintf (v, maxlen, _("%i bytes unknown data: "),
538                                   entry->size);
539                         for (i = 0; i < (int)entry->size; i++) {
540                                 sprintf (buf, "%02x", entry->data[i]);
541                                 strncat (v, buf, maxlen - strlen (v));
542                         }
543                         break;
544                 }
545                 break;
546         }
547
548         return (v);
549 }