Galaxy S2 camera module
[exynos_camera.git] / exynos_exif.c
1 /*
2  * Copyright (C) 2013 Paul Kocialkowski
3  *
4  * Based on crespo libcamera and exynos4 hal libcamera:
5  * Copyright 2008, The Android Open Source Project
6  * Copyright 2010, Samsung Electronics Co. LTD
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20  */
21
22 #include <fcntl.h>
23 #include <unistd.h>
24 #include <stdlib.h>
25 #include <stdbool.h>
26 #include <errno.h>
27 #include <malloc.h>
28 #include <sys/stat.h>
29 #include <sys/types.h>
30 #include <sys/time.h>
31 #include <sys/mman.h>
32 #include <sys/ioctl.h>
33
34 #include <Exif.h>
35
36 #define LOG_TAG "exynos_camera"
37 #include <utils/Log.h>
38 #include <cutils/properties.h>
39
40 #include "exynos_camera.h"
41
42 /*
43  * FIXME: This EXIF implementation doesn't work very well, it needs to be fixed.
44  */
45
46 int exynos_exif_attributes_create_static(struct exynos_camera *exynos_camera,
47         exif_attribute_t *exif_attributes)
48 {
49         unsigned char gps_version[] = { 0x02, 0x02, 0x00, 0x00 };
50         char property[PROPERTY_VALUE_MAX];
51         uint32_t av;
52
53         if (exynos_camera == NULL || exif_attributes == NULL)
54                 return -EINVAL;
55
56         // Device
57         property_get("ro.product.brand", property, EXIF_DEF_MAKER);
58         strncpy((char *) exif_attributes->maker, property,
59                 sizeof(exif_attributes->maker) - 1);
60         exif_attributes->maker[sizeof(exif_attributes->maker) - 1] = '\0';
61
62         property_get("ro.product.model", property, EXIF_DEF_MODEL);
63         strncpy((char *) exif_attributes->model, property,
64                 sizeof(exif_attributes->model) - 1);
65         exif_attributes->model[sizeof(exif_attributes->model) - 1] = '\0';
66
67         property_get("ro.build.id", property, EXIF_DEF_SOFTWARE);
68         strncpy((char *) exif_attributes->software, property,
69                 sizeof(exif_attributes->software) - 1);
70         exif_attributes->software[sizeof(exif_attributes->software) - 1] = '\0';
71
72         exif_attributes->ycbcr_positioning = EXIF_DEF_YCBCR_POSITIONING;
73
74         exif_attributes->fnumber.num = EXIF_DEF_FNUMBER_NUM;
75         exif_attributes->fnumber.den = EXIF_DEF_FNUMBER_DEN;
76
77         exif_attributes->exposure_program = EXIF_DEF_EXPOSURE_PROGRAM;
78
79         memcpy(exif_attributes->exif_version, EXIF_DEF_EXIF_VERSION,
80                 sizeof(exif_attributes->exif_version));
81
82         av = APEX_FNUM_TO_APERTURE((double) exif_attributes->fnumber.num /
83                 exif_attributes->fnumber.den);
84         exif_attributes->aperture.num = av * EXIF_DEF_APEX_DEN;
85         exif_attributes->aperture.den = EXIF_DEF_APEX_DEN;
86         exif_attributes->max_aperture.num = av * EXIF_DEF_APEX_DEN;
87         exif_attributes->max_aperture.den = EXIF_DEF_APEX_DEN;
88
89         strcpy((char *) exif_attributes->user_comment, EXIF_DEF_USERCOMMENTS);
90         exif_attributes->color_space = EXIF_DEF_COLOR_SPACE;
91         exif_attributes->exposure_mode = EXIF_DEF_EXPOSURE_MODE;
92
93         // GPS version
94         memcpy(exif_attributes->gps_version_id, gps_version, sizeof(gps_version));
95
96         exif_attributes->compression_scheme = EXIF_DEF_COMPRESSION;
97         exif_attributes->x_resolution.num = EXIF_DEF_RESOLUTION_NUM;
98         exif_attributes->x_resolution.den = EXIF_DEF_RESOLUTION_DEN;
99         exif_attributes->y_resolution.num = EXIF_DEF_RESOLUTION_NUM;
100         exif_attributes->y_resolution.den = EXIF_DEF_RESOLUTION_DEN;
101         exif_attributes->resolution_unit = EXIF_DEF_RESOLUTION_UNIT;
102
103         return 0;
104 }
105
106 int exynos_exif_attributes_create_gps(struct exynos_camera *exynos_camera,
107         exif_attribute_t *exif_attributes)
108 {
109         float gps_latitude_float, gps_longitude_float, gps_altitude_float;
110         int gps_timestamp_int;
111         char *gps_processing_method_string;
112         long gps_latitude, gps_longitude;
113         long gps_altitude, gps_timestamp;
114         double gps_latitude_abs, gps_longitude_abs, gps_altitude_abs;
115
116         struct tm time_info;
117
118         if (exynos_camera == NULL || exif_attributes == NULL)
119                 return -EINVAL;
120
121         gps_latitude_float = exynos_param_float_get(exynos_camera, "gps-latitude");
122         gps_longitude_float = exynos_param_float_get(exynos_camera, "gps-longitude");
123         gps_altitude_float = exynos_param_float_get(exynos_camera, "gps-altitude");
124         if (gps_altitude_float == -1)
125                 gps_altitude_float = (float) exynos_param_int_get(exynos_camera, "gps-altitude");
126         gps_timestamp_int = exynos_param_int_get(exynos_camera, "gps-timestamp");
127         gps_processing_method_string = exynos_param_string_get(exynos_camera, "gps-processing-method");
128
129         if (gps_latitude_float == -1 || gps_longitude_float == -1 ||
130                 gps_altitude_float == -1 || gps_timestamp_int <= 0 ||
131                 gps_processing_method_string == NULL) {
132                 exif_attributes->enableGps = false;
133                 return 0;
134         }
135
136         gps_latitude = (long) (gps_latitude_float * 10000) / 1;
137         gps_longitude = (long) (gps_longitude_float * 10000) / 1;
138         gps_altitude = (long) (gps_altitude_float * 100) / 1;
139         gps_timestamp = (long) gps_timestamp_int;
140
141         if (gps_latitude == 0 || gps_longitude == 0) {
142                 exif_attributes->enableGps = false;
143                 return 0;
144         }
145
146         if (gps_latitude > 0)
147                 strcpy((char *) exif_attributes->gps_latitude_ref, "N");
148         else
149                 strcpy((char *) exif_attributes->gps_latitude_ref, "S");
150
151         if (gps_longitude > 0)
152                 strcpy((char *) exif_attributes->gps_longitude_ref, "E");
153         else
154                 strcpy((char *) exif_attributes->gps_longitude_ref, "W");
155
156         if (gps_altitude > 0)
157                 exif_attributes->gps_altitude_ref = 0;
158         else
159                 exif_attributes->gps_altitude_ref = 1;
160
161
162         gps_latitude_abs = fabs(gps_latitude / 10000.0);
163         gps_longitude_abs = fabs(gps_longitude / 10000.0);
164         gps_altitude_abs = fabs(gps_altitude / 100.0);
165
166         exif_attributes->gps_latitude[0].num = (uint32_t) gps_latitude_abs;
167         exif_attributes->gps_latitude[0].den = 1;
168         exif_attributes->gps_latitude[1].num = 0;
169         exif_attributes->gps_latitude[1].den = 1;
170         exif_attributes->gps_latitude[2].num = 0;
171         exif_attributes->gps_latitude[2].den = 1;
172
173         exif_attributes->gps_longitude[0].num = (uint32_t) gps_longitude_abs;
174         exif_attributes->gps_longitude[0].den = 1;
175         exif_attributes->gps_longitude[1].num = 0;
176         exif_attributes->gps_longitude[1].den = 1;
177         exif_attributes->gps_longitude[2].num = 0;
178         exif_attributes->gps_longitude[2].den = 1;
179
180         exif_attributes->gps_altitude.num = (uint32_t) gps_altitude_abs;
181         exif_attributes->gps_altitude.den = 1;
182
183         gmtime_r(&gps_timestamp, &time_info);
184
185         exif_attributes->gps_timestamp[0].num = time_info.tm_hour;
186         exif_attributes->gps_timestamp[0].den = 1;
187         exif_attributes->gps_timestamp[1].num = time_info.tm_min;
188         exif_attributes->gps_timestamp[1].den = 1;
189         exif_attributes->gps_timestamp[2].num = time_info.tm_sec;
190         exif_attributes->gps_timestamp[2].den = 1;
191         snprintf((char *) exif_attributes->gps_datestamp, sizeof(exif_attributes->gps_datestamp),
192                 "%04d:%02d:%02d", time_info.tm_year + 1900, time_info.tm_mon + 1, time_info.tm_mday);
193
194         exif_attributes->enableGps = true;
195
196         return 0;
197 }
198
199 int exynos_exif_attributes_create_params(struct exynos_camera *exynos_camera,
200         exif_attribute_t *exif_attributes)
201 {
202         uint32_t av, tv, bv, sv, ev;
203         time_t time_data;
204         struct tm *time_info;
205         int rotation;
206         int shutter_speed;
207         int exposure_time;
208         int iso_speed;
209         int exposure;
210
211         int rc;
212
213         if (exynos_camera == NULL || exif_attributes == NULL)
214                 return -EINVAL;
215
216         // Picture size
217         exif_attributes->width = exynos_camera->picture_width;
218         exif_attributes->height = exynos_camera->picture_height;
219
220         // Thumbnail
221         exif_attributes->widthThumb = exynos_camera->jpeg_thumbnail_width;
222         exif_attributes->heightThumb = exynos_camera->jpeg_thumbnail_height;
223         exif_attributes->enableThumb = true;
224
225         // Orientation
226         rotation = exynos_param_int_get(exynos_camera, "rotation");
227         switch (rotation) {
228                 case 90:
229                         exif_attributes->orientation = EXIF_ORIENTATION_90;
230                         break;
231                 case 180:
232                         exif_attributes->orientation = EXIF_ORIENTATION_180;
233                         break;
234                 case 270:
235                         exif_attributes->orientation = EXIF_ORIENTATION_270;
236                         break;
237                 case 0:
238                 default:
239                         exif_attributes->orientation = EXIF_ORIENTATION_UP;
240                         break;
241         }
242
243         // Time
244         time(&time_data);
245         time_info = localtime(&time_data);
246         strftime((char *) exif_attributes->date_time, sizeof(exif_attributes->date_time),
247                 "%Y:%m:%d %H:%M:%S", time_info);
248
249         exif_attributes->focal_length.num = exynos_camera->camera_focal_length;
250         exif_attributes->focal_length.den = EXIF_DEF_FOCAL_LEN_DEN;
251
252         shutter_speed = 100;
253         rc = exynos_v4l2_g_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_EXIF_TV,
254                 &shutter_speed);
255         if (rc < 0)
256                 LOGE("%s: g ctrl failed!", __func__);
257
258         exif_attributes->shutter_speed.num = 1;
259         exif_attributes->shutter_speed.den = shutter_speed;
260
261         exposure_time = shutter_speed;
262         rc = exynos_v4l2_g_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_EXIF_EXPTIME,
263                 &exposure_time);
264         if (rc < 0)
265                 LOGE("%s: g ctrl failed!", __func__);
266
267         exif_attributes->exposure_time.num = 1;
268         exif_attributes->exposure_time.den = exposure_time;
269
270         rc = exynos_v4l2_g_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_EXIF_ISO,
271                 &iso_speed);
272         if (rc < 0)
273                 LOGE("%s: g ctrl failed!", __func__);
274
275         exif_attributes->iso_speed_rating = iso_speed;
276
277         rc = exynos_v4l2_g_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_EXIF_BV,
278                 (int *) &bv);
279         if (rc < 0) {
280                 LOGE("%s: g ctrl failed!", __func__);
281                 goto bv_static;
282         }
283
284         rc = exynos_v4l2_g_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_EXIF_EBV,
285                 (int *) &ev);
286         if (rc < 0) {
287                 LOGE("%s: g ctrl failed!", __func__);
288                 goto bv_static;
289         }
290
291         goto bv_ioctl;
292
293 bv_static:
294         exposure = exynos_param_int_get(exynos_camera, "exposure-compensation");
295         if (exposure < 0)
296                 exposure = EV_DEFAULT;
297
298         av = APEX_FNUM_TO_APERTURE((double) exif_attributes->fnumber.num /
299                 exif_attributes->fnumber.den);
300         tv = APEX_EXPOSURE_TO_SHUTTER((double) exif_attributes->exposure_time.num /
301                 exif_attributes->exposure_time.den);
302         sv = APEX_ISO_TO_FILMSENSITIVITY(iso_speed);
303         bv = av + tv - sv;
304         ev = exposure - EV_DEFAULT;
305
306 bv_ioctl:
307         exif_attributes->brightness.num = bv * EXIF_DEF_APEX_DEN;
308         exif_attributes->brightness.den = EXIF_DEF_APEX_DEN;
309
310         if (exynos_camera->scene_mode == SCENE_MODE_BEACH_SNOW) {
311                 exif_attributes->exposure_bias.num = EXIF_DEF_APEX_DEN;
312                 exif_attributes->exposure_bias.den = EXIF_DEF_APEX_DEN;
313         } else {
314                 exif_attributes->exposure_bias.num = ev * EXIF_DEF_APEX_DEN;
315                 exif_attributes->exposure_bias.den = EXIF_DEF_APEX_DEN;
316         }
317
318         switch (exynos_camera->camera_metering) {
319                 case METERING_CENTER:
320                         exif_attributes->metering_mode = EXIF_METERING_CENTER;
321                         break;
322                 case METERING_MATRIX:
323                         exif_attributes->metering_mode = EXIF_METERING_AVERAGE;
324                         break;
325                 case METERING_SPOT:
326                         exif_attributes->metering_mode = EXIF_METERING_SPOT;
327                         break;
328                 default:
329                         exif_attributes->metering_mode = EXIF_METERING_AVERAGE;
330                         break;
331         }
332
333         if (exynos_camera->flash_mode == FLASH_MODE_BASE)
334                 exif_attributes->flash = EXIF_DEF_FLASH;
335         else
336                 exif_attributes->flash = exynos_camera->flash_mode;
337
338         if (exynos_camera->whitebalance == WHITE_BALANCE_AUTO ||
339                 exynos_camera->whitebalance == WHITE_BALANCE_BASE)
340                 exif_attributes->white_balance = EXIF_WB_AUTO;
341         else
342                 exif_attributes->white_balance = EXIF_WB_MANUAL;
343
344         switch (exynos_camera->scene_mode) {
345                 case SCENE_MODE_PORTRAIT:
346                         exif_attributes->scene_capture_type = EXIF_SCENE_PORTRAIT;
347                         break;
348                 case SCENE_MODE_LANDSCAPE:
349                         exif_attributes->scene_capture_type = EXIF_SCENE_LANDSCAPE;
350                         break;
351                 case SCENE_MODE_NIGHTSHOT:
352                         exif_attributes->scene_capture_type = EXIF_SCENE_NIGHT;
353                         break;
354                 default:
355                         exif_attributes->scene_capture_type = EXIF_SCENE_STANDARD;
356                         break;
357         }
358
359         rc = exynos_exif_attributes_create_gps(exynos_camera, exif_attributes);
360         if (rc < 0) {
361                 LOGE("%s: Failed to create GPS attributes", __func__);
362                 return -1;
363         }
364
365         return 0;
366 }
367
368 int exynos_exif_write_data(void *exif_data, unsigned short tag,
369         unsigned short type, unsigned int count, int *offset, void *start, 
370         void *data, int length)
371 {
372         unsigned char *pointer;
373         int size;
374
375         if (exif_data == NULL || data == NULL || length <= 0)
376                 return -EINVAL;
377
378         pointer = (unsigned char *) exif_data;
379
380         memcpy(pointer, &tag, sizeof(tag));
381         pointer += sizeof(tag);
382
383         memcpy(pointer, &type, sizeof(type));
384         pointer += sizeof(type);
385
386         memcpy(pointer, &count, sizeof(count));
387         pointer += sizeof(count);
388
389         if (offset != NULL && start != NULL) {
390                 memcpy(pointer, offset, sizeof(*offset));
391                 pointer += sizeof(*offset);
392
393                 memcpy((void *) ((int) start + *offset), data, count * length);
394                 *offset += count * length;              
395         } else {
396                 memcpy(pointer, data, count * length);
397                 pointer += count * length;
398         }
399
400         size = (int) pointer - (int) exif_data;
401         return size;
402 }
403
404 int exynos_exif_create(struct exynos_camera *exynos_camera,
405         exif_attribute_t *exif_attributes,
406         camera_memory_t *jpeg_thumbnail_data_memory, int jpeg_thumbnail_size,
407         camera_memory_t **exif_data_memory_p, int *exif_size_p)
408 {
409         // Markers
410         unsigned char exif_app1_marker[] = { 0xff, 0xe1 };
411         unsigned char exif_app1_size[] = { 0x00, 0x00 };
412         unsigned char exif_marker[] = { 0x45, 0x78, 0x69, 0x66, 0x00, 0x00 };
413         unsigned char tiff_marker[] = { 0x49, 0x49, 0x2A, 0x00, 0x08, 0x00, 0x00, 0x00 };
414
415         unsigned char user_comment_code[] = { 0x00, 0x00, 0x00, 0x49, 0x49, 0x43, 0x53, 0x41 };
416         unsigned char exif_ascii_prefix[] = { 0x41, 0x53, 0x43, 0x49, 0x49, 0x0, 0x0, 0x0 };
417
418         camera_memory_t *exif_data_memory;
419         void *exif_data;
420         int exif_data_size;
421         int exif_size;
422
423         void *exif_ifd_data_start, *exif_ifd_start, *exif_ifd_gps, *exif_ifd_thumb;
424
425         void *exif_thumb_data;
426         unsigned int exif_thumb_size;
427
428         unsigned char *pointer;
429         unsigned int offset;
430         void *data;
431         int count;
432
433         unsigned int value;
434
435         if (exynos_camera == NULL || exif_attributes == NULL ||
436                 jpeg_thumbnail_data_memory == NULL || jpeg_thumbnail_size <= 0 ||
437                 exif_data_memory_p == NULL || exif_size_p == NULL)
438                 return -EINVAL;
439
440         exif_data_size = EXIF_FILE_SIZE + jpeg_thumbnail_size;
441
442         if (exynos_camera->callbacks.request_memory != NULL) {
443                 exif_data_memory = exynos_camera->callbacks.request_memory(-1,
444                         exif_data_size, 1, 0);
445                 if (exif_data_memory == NULL) {
446                         LOGE("%s: exif memory request failed!", __func__);
447                         goto error;
448                 }
449         } else {
450                 LOGE("%s: No memory request function!", __func__);
451                 goto error;
452         }
453
454         exif_data = exif_data_memory->data;
455         memset(exif_data, 0, exif_data_size);
456
457         pointer = (unsigned char *) exif_data;
458         exif_ifd_data_start = (void *) pointer;
459
460         // Skip 4 bytes for APP1 marker
461         pointer += 4;
462
463         // Copy EXIF marker
464         memcpy(pointer, exif_marker, sizeof(exif_marker));
465         pointer += sizeof(exif_marker);
466
467         // Copy TIFF marker
468         memcpy(pointer, tiff_marker, sizeof(tiff_marker));
469         exif_ifd_start = (void *) pointer;
470         pointer += sizeof(tiff_marker);
471
472         if (exif_attributes->enableGps)
473                 value = NUM_0TH_IFD_TIFF;
474         else
475                 value = NUM_0TH_IFD_TIFF - 1;
476
477         memcpy(pointer, &value, NUM_SIZE);
478         pointer += NUM_SIZE;
479
480         offset = 8 + NUM_SIZE + value * IFD_SIZE + OFFSET_SIZE;
481
482         // Write EXIF data
483         count = exynos_exif_write_data(pointer, EXIF_TAG_IMAGE_WIDTH,
484                 EXIF_TYPE_LONG, 1, NULL, NULL, &exif_attributes->width, sizeof(exif_attributes->width));
485         pointer += count;
486
487         count = exynos_exif_write_data(pointer, EXIF_TAG_IMAGE_HEIGHT,
488                 EXIF_TYPE_LONG, 1, NULL, NULL, &exif_attributes->height, sizeof(exif_attributes->height));
489         pointer += count;
490
491         count = exynos_exif_write_data(pointer, EXIF_TAG_MAKE,
492                 EXIF_TYPE_ASCII, strlen((char *) exif_attributes->maker) + 1,
493                 &offset, exif_ifd_start, &exif_attributes->maker, sizeof(char));
494         pointer += count;
495
496         count = exynos_exif_write_data(pointer, EXIF_TAG_MODEL,
497                 EXIF_TYPE_ASCII, strlen((char *) exif_attributes->model) + 1,
498                 &offset, exif_ifd_start, &exif_attributes->model, sizeof(char));
499         pointer += count;
500
501         count = exynos_exif_write_data(pointer, EXIF_TAG_ORIENTATION,
502                 EXIF_TYPE_SHORT, 1, NULL, NULL, &exif_attributes->orientation, sizeof(exif_attributes->orientation));
503         pointer += count;
504
505         count = exynos_exif_write_data(pointer, EXIF_TAG_SOFTWARE,
506                 EXIF_TYPE_ASCII, strlen((char *) exif_attributes->software) + 1,
507                 &offset, exif_ifd_start, &exif_attributes->software, sizeof(char));
508         pointer += count;
509
510         count = exynos_exif_write_data(pointer, EXIF_TAG_DATE_TIME,
511                 EXIF_TYPE_ASCII, 20, &offset, exif_ifd_start, &exif_attributes->date_time, sizeof(char));
512         pointer += count;
513
514         count = exynos_exif_write_data(pointer, EXIF_TAG_YCBCR_POSITIONING,
515                 EXIF_TYPE_SHORT, 1, NULL, NULL, &exif_attributes->ycbcr_positioning, sizeof(exif_attributes->ycbcr_positioning));
516         pointer += count;
517
518         count = exynos_exif_write_data(pointer, EXIF_TAG_EXIF_IFD_POINTER,
519                 EXIF_TYPE_LONG, 1, NULL, NULL, &offset, sizeof(offset));
520         pointer += count;
521
522         if (exif_attributes->enableGps) {
523                 exif_ifd_gps = (void *) pointer;
524                 pointer += IFD_SIZE;
525         }
526
527         exif_ifd_thumb = (void *) pointer;
528         pointer += OFFSET_SIZE;
529
530         pointer = (unsigned char *) exif_ifd_start;
531         pointer += offset;
532
533         value = NUM_0TH_IFD_EXIF;
534         memcpy(pointer, &value, NUM_SIZE);
535         pointer += NUM_SIZE;
536
537         offset += NUM_SIZE + NUM_0TH_IFD_EXIF * IFD_SIZE + OFFSET_SIZE;
538
539         count = exynos_exif_write_data(pointer, EXIF_TAG_EXPOSURE_TIME,
540                 EXIF_TYPE_RATIONAL, 1, &offset, exif_ifd_start, &exif_attributes->exposure_time, sizeof(exif_attributes->exposure_time));
541         pointer += count;
542
543         count = exynos_exif_write_data(pointer, EXIF_TAG_FNUMBER,
544                 EXIF_TYPE_RATIONAL, 1, &offset, exif_ifd_start, &exif_attributes->fnumber, sizeof(exif_attributes->fnumber));
545         pointer += count;
546
547         count = exynos_exif_write_data(pointer, EXIF_TAG_EXPOSURE_PROGRAM,
548                 EXIF_TYPE_SHORT, 1, NULL, NULL, &exif_attributes->exposure_program, sizeof(exif_attributes->exposure_program));
549         pointer += count;
550
551         count = exynos_exif_write_data(pointer, EXIF_TAG_ISO_SPEED_RATING,
552                 EXIF_TYPE_SHORT, 1, NULL, NULL, &exif_attributes->iso_speed_rating, sizeof(exif_attributes->iso_speed_rating));
553         pointer += count;
554
555         count = exynos_exif_write_data(pointer, EXIF_TAG_EXIF_VERSION,
556                 EXIF_TYPE_UNDEFINED, 1, NULL, NULL, &exif_attributes->exif_version, sizeof(exif_attributes->exif_version));
557         pointer += count;
558
559         count = exynos_exif_write_data(pointer, EXIF_TAG_DATE_TIME_ORG,
560                 EXIF_TYPE_ASCII, 20, &offset, exif_ifd_start, &exif_attributes->date_time, sizeof(char));
561         pointer += count;
562
563         count = exynos_exif_write_data(pointer, EXIF_TAG_DATE_TIME_DIGITIZE,
564                 EXIF_TYPE_ASCII, 20, &offset, exif_ifd_start, &exif_attributes->date_time, sizeof(char));
565         pointer += count;
566
567         count = exynos_exif_write_data(pointer, EXIF_TAG_SHUTTER_SPEED,
568                 EXIF_TYPE_SRATIONAL, 1, &offset, exif_ifd_start, &exif_attributes->shutter_speed, sizeof(exif_attributes->shutter_speed));
569         pointer += count;
570
571         count = exynos_exif_write_data(pointer, EXIF_TAG_APERTURE,
572                 EXIF_TYPE_RATIONAL, 1, &offset, exif_ifd_start, &exif_attributes->aperture, sizeof(exif_attributes->shutter_speed));
573         pointer += count;
574
575         count = exynos_exif_write_data(pointer, EXIF_TAG_BRIGHTNESS,
576                 EXIF_TYPE_SRATIONAL, 1, &offset, exif_ifd_start, &exif_attributes->brightness, sizeof(exif_attributes->brightness));
577         pointer += count;
578
579         count = exynos_exif_write_data(pointer, EXIF_TAG_EXPOSURE_BIAS,
580                 EXIF_TYPE_SRATIONAL, 1, &offset, exif_ifd_start, &exif_attributes->exposure_bias, sizeof(exif_attributes->exposure_bias));
581         pointer += count;
582
583         count = exynos_exif_write_data(pointer, EXIF_TAG_MAX_APERTURE,
584                 EXIF_TYPE_RATIONAL, 1, &offset, exif_ifd_start, &exif_attributes->max_aperture, sizeof(exif_attributes->max_aperture));
585         pointer += count;
586
587         count = exynos_exif_write_data(pointer, EXIF_TAG_METERING_MODE,
588                 EXIF_TYPE_SHORT, 1, NULL, NULL, &exif_attributes->metering_mode, sizeof(exif_attributes->metering_mode));
589         pointer += count;
590
591         count = exynos_exif_write_data(pointer, EXIF_TAG_FLASH,
592                 EXIF_TYPE_SHORT, 1, NULL, NULL, &exif_attributes->flash, sizeof(exif_attributes->flash));
593         pointer += count;
594
595         count = exynos_exif_write_data(pointer, EXIF_TAG_FOCAL_LENGTH,
596                 EXIF_TYPE_RATIONAL, 1, &offset, exif_ifd_start, &exif_attributes->focal_length, sizeof(exif_attributes->focal_length));
597         pointer += count;
598
599         value = strlen((char *) exif_attributes->user_comment) + 1;
600         memmove(exif_attributes->user_comment + sizeof(user_comment_code), exif_attributes->user_comment, value);
601         memcpy(exif_attributes->user_comment, user_comment_code, sizeof(user_comment_code));
602
603         count = exynos_exif_write_data(pointer, EXIF_TAG_USER_COMMENT,
604                 EXIF_TYPE_UNDEFINED, value + sizeof(user_comment_code), &offset, exif_ifd_start, &exif_attributes->user_comment, sizeof(char));
605         pointer += count;
606
607         count = exynos_exif_write_data(pointer, EXIF_TAG_COLOR_SPACE,
608                 EXIF_TYPE_SHORT, 1, NULL, NULL, &exif_attributes->color_space, sizeof(exif_attributes->color_space));
609         pointer += count;
610
611         count = exynos_exif_write_data(pointer, EXIF_TAG_PIXEL_X_DIMENSION,
612                 EXIF_TYPE_LONG, 1, NULL, NULL, &exif_attributes->width, sizeof(exif_attributes->width));
613         pointer += count;
614
615         count = exynos_exif_write_data(pointer, EXIF_TAG_PIXEL_Y_DIMENSION,
616                 EXIF_TYPE_LONG, 1, NULL, NULL, &exif_attributes->height, sizeof(exif_attributes->height));
617         pointer += count;
618
619         count = exynos_exif_write_data(pointer, EXIF_TAG_EXPOSURE_MODE,
620                 EXIF_TYPE_LONG, 1, NULL, NULL, &exif_attributes->exposure_mode, sizeof(exif_attributes->exposure_mode));
621         pointer += count;
622
623         count = exynos_exif_write_data(pointer, EXIF_TAG_WHITE_BALANCE,
624                 EXIF_TYPE_LONG, 1, NULL, NULL, &exif_attributes->white_balance, sizeof(exif_attributes->white_balance));
625         pointer += count;
626
627         count = exynos_exif_write_data(pointer, EXIF_TAG_SCENCE_CAPTURE_TYPE,
628                 EXIF_TYPE_LONG, 1, NULL, NULL, &exif_attributes->scene_capture_type, sizeof(exif_attributes->scene_capture_type));
629         pointer += count;
630
631         value = 0;
632         memcpy(pointer, &value, OFFSET_SIZE);
633         pointer += OFFSET_SIZE;
634
635         // GPS
636         if (exif_attributes->enableGps) {
637                 pointer = (unsigned char *) exif_ifd_gps;
638                 count = exynos_exif_write_data(pointer, EXIF_TAG_GPS_IFD_POINTER,
639                         EXIF_TYPE_LONG, 1, NULL, NULL, &offset, sizeof(offset));
640
641                 pointer = exif_ifd_start + offset;
642
643                 if (exif_attributes->gps_processing_method[0] == 0)
644                         value = NUM_0TH_IFD_GPS - 1;
645                 else
646                         value = NUM_0TH_IFD_GPS;
647
648                 memcpy(pointer, &value, NUM_SIZE);
649                 pointer += NUM_SIZE;
650
651                 offset += NUM_SIZE + value * IFD_SIZE + OFFSET_SIZE;
652                 
653                 count = exynos_exif_write_data(pointer, EXIF_TAG_GPS_VERSION_ID,
654                         EXIF_TYPE_LONG, 4, NULL, NULL, &exif_attributes->gps_version_id, 1);
655                 pointer += count;
656
657                 count = exynos_exif_write_data(pointer, EXIF_TAG_GPS_LATITUDE_REF,
658                         EXIF_TYPE_ASCII, 2, NULL, NULL, &exif_attributes->gps_latitude_ref, 1);
659                 pointer += count;
660
661                 count = exynos_exif_write_data(pointer, EXIF_TAG_GPS_LATITUDE,
662                         EXIF_TYPE_RATIONAL, 3, &offset, exif_ifd_start, &exif_attributes->gps_latitude, sizeof(exif_attributes->gps_latitude[0]));
663                 pointer += count;
664
665                 count = exynos_exif_write_data(pointer, EXIF_TAG_GPS_LONGITUDE_REF,
666                         EXIF_TYPE_ASCII, 2, NULL, NULL, &exif_attributes->gps_longitude_ref, 1);
667                 pointer += count;
668
669                 count = exynos_exif_write_data(pointer, EXIF_TAG_GPS_LONGITUDE,
670                         EXIF_TYPE_RATIONAL, 3, &offset, exif_ifd_start, &exif_attributes->gps_longitude, sizeof(exif_attributes->gps_longitude[0]));
671
672                 count = exynos_exif_write_data(pointer, EXIF_TAG_GPS_ALTITUDE_REF,
673                         EXIF_TYPE_BYTE, 1, NULL, NULL, &exif_attributes->gps_altitude_ref, 1);
674                 pointer += count;
675
676                 count = exynos_exif_write_data(pointer, EXIF_TAG_GPS_ALTITUDE,
677                         EXIF_TYPE_RATIONAL, 1, &offset, exif_ifd_start, &exif_attributes->gps_altitude, sizeof(exif_attributes->gps_altitude));
678                 pointer += count;
679
680                 count = exynos_exif_write_data(pointer, EXIF_TAG_GPS_TIMESTAMP,
681                         EXIF_TYPE_RATIONAL, 3, &offset, exif_ifd_start, &exif_attributes->gps_timestamp, sizeof(exif_attributes->gps_timestamp[0]));
682                 pointer += count;
683
684                 value = strlen((char *) exif_attributes->gps_processing_method);
685                 if (value > 0) {
686                         value = value > 100 ? 100 : value;
687
688                         data = calloc(1, value + sizeof(exif_ascii_prefix));
689                         memcpy(data, &exif_ascii_prefix, sizeof(exif_ascii_prefix));
690                         memcpy((void *) ((int) data + (int) sizeof(exif_ascii_prefix)), exif_attributes->gps_processing_method, value);
691
692                         count = exynos_exif_write_data(pointer, EXIF_TAG_GPS_PROCESSING_METHOD,
693                                 EXIF_TYPE_UNDEFINED, value + sizeof(exif_ascii_prefix), &offset, exif_ifd_start, data, 1);
694                         pointer += count;
695
696                         free(data);
697                 }
698
699                 count = exynos_exif_write_data(pointer, EXIF_TAG_GPS_DATESTAMP,
700                                 EXIF_TYPE_ASCII, 11, &offset, exif_ifd_start, &exif_attributes->gps_datestamp, 1);
701                 pointer += count;
702
703                 value = 0;
704                 memcpy(pointer, &value, OFFSET_SIZE);
705                 pointer += OFFSET_SIZE;
706         }
707
708         if (exif_attributes->enableThumb && jpeg_thumbnail_data_memory != NULL && jpeg_thumbnail_size > 0) {
709                 exif_thumb_size = (unsigned int) jpeg_thumbnail_size;
710                 exif_thumb_data = (void *) jpeg_thumbnail_data_memory->data;
711
712                 value = offset;
713                 memcpy(exif_ifd_thumb, &value, OFFSET_SIZE);
714
715                 pointer = (unsigned char *) ((int) exif_ifd_start + (int) offset);
716
717                 value = NUM_1TH_IFD_TIFF;
718                 memcpy(pointer, &value, NUM_SIZE);
719                 pointer += NUM_SIZE;
720
721                 offset += NUM_SIZE + NUM_1TH_IFD_TIFF * IFD_SIZE + OFFSET_SIZE;
722
723                 count = exynos_exif_write_data(pointer, EXIF_TAG_IMAGE_WIDTH,
724                                 EXIF_TYPE_LONG, 1, NULL, NULL, &exif_attributes->widthThumb, sizeof(exif_attributes->widthThumb));
725                 pointer += count;
726
727                 count = exynos_exif_write_data(pointer, EXIF_TAG_IMAGE_HEIGHT,
728                                 EXIF_TYPE_LONG, 1, NULL, NULL, &exif_attributes->heightThumb, sizeof(exif_attributes->heightThumb));
729                 pointer += count;
730
731                 count = exynos_exif_write_data(pointer, EXIF_TAG_COMPRESSION_SCHEME,
732                                 EXIF_TYPE_LONG, 1, NULL, NULL, &exif_attributes->compression_scheme, sizeof(exif_attributes->compression_scheme));
733                 pointer += count;
734
735                 count = exynos_exif_write_data(pointer, EXIF_TAG_ORIENTATION,
736                                 EXIF_TYPE_SHORT, 1, NULL, NULL, &exif_attributes->orientation, sizeof(exif_attributes->orientation));
737                 pointer += count;
738
739                 count = exynos_exif_write_data(pointer, EXIF_TAG_X_RESOLUTION,
740                                 EXIF_TYPE_RATIONAL, 1, &offset, exif_ifd_start, &exif_attributes->x_resolution, sizeof(exif_attributes->x_resolution));
741                 pointer += count;
742
743                 count = exynos_exif_write_data(pointer, EXIF_TAG_Y_RESOLUTION,
744                                 EXIF_TYPE_RATIONAL, 1, &offset, exif_ifd_start, &exif_attributes->y_resolution, sizeof(exif_attributes->y_resolution));
745                 pointer += count;
746
747                 count = exynos_exif_write_data(pointer, EXIF_TAG_RESOLUTION_UNIT,
748                                 EXIF_TYPE_SHORT, 1, NULL, NULL, &exif_attributes->resolution_unit, sizeof(exif_attributes->resolution_unit));
749                 pointer += count;
750
751                 count = exynos_exif_write_data(pointer, EXIF_TAG_JPEG_INTERCHANGE_FORMAT,
752                                 EXIF_TYPE_LONG, 1, NULL, NULL, &offset, sizeof(offset));
753                 pointer += count;
754
755                 count = exynos_exif_write_data(pointer, EXIF_TAG_JPEG_INTERCHANGE_FORMAT_LEN,
756                                 EXIF_TYPE_LONG, 1, NULL, NULL, &exif_thumb_size, sizeof(exif_thumb_size));
757                 pointer += count;
758
759                 value = 0;
760                 memcpy(pointer, &value, OFFSET_SIZE);
761
762                 pointer = (unsigned char *) ((int) exif_ifd_start + (int) offset);
763
764                 memcpy(pointer, exif_thumb_data, exif_thumb_size);
765                 offset += exif_thumb_size;
766         } else {
767                 value = 0;
768                 memcpy(exif_ifd_thumb, &value, OFFSET_SIZE);
769                 
770         }
771
772         pointer = (unsigned char *) exif_ifd_data_start;
773
774         memcpy(pointer, exif_app1_marker, sizeof(exif_app1_marker));
775         pointer += sizeof(exif_app1_marker);
776
777         exif_size = offset + 10;
778         value = exif_size - 2;
779         exif_app1_size[0] = (value >> 8) & 0xff;
780         exif_app1_size[1] = value & 0xff;
781
782         memcpy(pointer, exif_app1_size, sizeof(exif_app1_size));
783
784         *exif_data_memory_p = exif_data_memory;
785         *exif_size_p = exif_size;
786
787         return 0;
788
789 error:
790         if (exif_data_memory != NULL && exif_data_memory->release != NULL)
791                 exif_data_memory->release(exif_data_memory);
792
793         *exif_data_memory_p = NULL;
794         *exif_size_p = 0;
795
796         return -1;
797 }