ce9869716a55f4e02eac1c0231ff4f0d6bf7e1b5
[platform/core/api/maps-service.git] / src / api / maps_view_snapshot.cpp
1 /* Copyright (c) 2010-2014 Samsung Electronics Co., Ltd. All rights reserved.
2  *
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <stdlib.h>
18 #include <image_util.h>
19
20 #include <maps_view_plugin.h>
21 #include <maps_condition.h>
22 #include <module.h>
23 #include <empty_module.h>
24 #include "maps_condition.h"
25
26
27 const plugin::interface_s *__get_plugin_interface(maps_view_h view);
28
29 static void __convert_rgba_to_bgra(unsigned char *data, int width, int height)
30 {
31         int len = width * height;
32         unsigned int *p = (unsigned int *)data;
33         for (int i = 0; i < len; i++)
34         {
35                 *p = (*p & 0xFF00FF00) |
36                         ((*p & 0x00FF0000) >> 16) |
37                         ((*p & 0x000000FF) << 16);
38                 p++;
39         };
40 }
41
42 static bool __encode_bitmap_file(const void *data, int width, int height, const char *file)
43 {
44        struct {
45               unsigned char magic[2];
46        } bmpfile_magic = { {'B', 'M'} };
47
48        struct {
49               unsigned int filesz;
50               unsigned short creator1;
51               unsigned short creator2;
52               unsigned int bmp_offset;
53        } bmpfile_header = { 0, 0, 0, 0x36 };
54
55        struct {
56               unsigned int header_sz;
57               unsigned int width;
58               unsigned int height;
59               unsigned short nplanes;
60               unsigned short bitspp;
61               unsigned int compress_type;
62               unsigned int bmp_bytesz;
63               unsigned int hres;
64               unsigned int vres;
65               unsigned int ncolors;
66               unsigned int nimpcolors;
67        } bmp_dib_v3_header_t = { 0x28, 0, 0, 1, 24, 0, 0, 0, 0, 0, 0 };
68
69        unsigned int *blocks;
70        FILE *fp = fopen(file, "w+");
71        int i;
72
73        if (fp == NULL) {
74               MAPS_LOGE("fopen fail");
75               return false;
76        }
77        bmpfile_header.filesz = sizeof(bmpfile_magic) + sizeof(bmpfile_header) + sizeof(bmp_dib_v3_header_t) + (width * height * 3);
78        bmp_dib_v3_header_t.header_sz = sizeof(bmp_dib_v3_header_t);
79        bmp_dib_v3_header_t.width = width;
80        bmp_dib_v3_header_t.height = -height;
81        bmp_dib_v3_header_t.bmp_bytesz = width * height * 3;
82
83        fwrite(&bmpfile_magic, sizeof(bmpfile_magic), 1, fp);
84        fwrite(&bmpfile_header, sizeof(bmpfile_header), 1, fp);
85        fwrite(&bmp_dib_v3_header_t, sizeof(bmp_dib_v3_header_t), 1, fp);
86        blocks = (unsigned int *)data;
87
88        for (i = 0; i < height * width; i++) {
89               fwrite(&blocks[i], 3, 1, fp);
90        }
91        fclose(fp);
92            return true;
93 }
94
95 static image_util_colorspace_e __convert_colorspace(maps_view_colorspace_type_e cs)
96 {
97         switch (cs) {
98                 case MAPS_VIEW_COLORSPACE_RGBA8888:
99                         return IMAGE_UTIL_COLORSPACE_RGBA8888;
100                 case MAPS_VIEW_COLORSPACE_BGRA8888:
101                         return IMAGE_UTIL_COLORSPACE_BGRA8888;
102         }
103         return IMAGE_UTIL_COLORSPACE_RGBA8888;
104 }
105
106 EXPORT_API int maps_view_capture_snapshot(maps_view_h view,
107                                                                 maps_view_snapshot_format_type_e type,
108                                                                 int quality,
109                                                                 const char *path)
110 {
111         if (!maps_condition_check_maps_feature())
112                 return MAPS_ERROR_NOT_SUPPORTED;
113         if (!view)
114                 return MAPS_ERROR_INVALID_PARAMETER;
115         if (!maps_condition_check_view_service_supported(view, MAPS_SERVICE_VIEW_SNAPSHOT))
116                 return MAPS_ERROR_NOT_SUPPORTED;
117         if (type < MAPS_VIEW_SNAPSHOT_BMP || type > MAPS_VIEW_SNAPSHOT_JPEG ||
118                 quality < 0 || quality > 100 || !path || (path && *path == '\0'))
119                 return MAPS_ERROR_INVALID_PARAMETER;
120         if (!maps_condition_check_privilege())
121                 return MAPS_ERROR_PERMISSION_DENIED;
122
123         int error = MAPS_ERROR_UNKNOWN;
124         int w, h;
125         unsigned char *image_buffer = NULL;
126         maps_view_colorspace_type_e cs = MAPS_VIEW_COLORSPACE_RGBA8888;
127         char *fname = NULL;
128
129         do {
130                 if (!__get_plugin_interface(view)->maps_plugin_capture_snapshot)
131                         return  MAPS_ERROR_SERVICE_NOT_AVAILABLE;
132
133                 error = __get_plugin_interface(view)->maps_plugin_capture_snapshot(view,
134                                                                                                 (void**)&image_buffer, &w, &h, &cs);
135                 if (error != MAPS_ERROR_NONE) break;
136                 if (cs != MAPS_VIEW_COLORSPACE_RGBA8888 && cs != MAPS_VIEW_COLORSPACE_BGRA8888) {
137                         MAPS_LOGE("The color space is not supported yet. (%d)", cs);
138                         error = MAPS_ERROR_INVALID_OPERATION;
139                         break;
140                 }
141
142                 int fname_len = strlen(path) + 4;
143                 fname = (char*)malloc(fname_len + 1);
144                 if (!fname)
145                         return MAPS_ERROR_INVALID_OPERATION;
146
147                 memset(fname, 0, fname_len + 1);
148                 sprintf(fname, "%s.tmp", path);
149
150                 if (type == MAPS_VIEW_SNAPSHOT_JPEG) {
151                         error = image_util_encode_jpeg(image_buffer, w, h,
152                                                                                         __convert_colorspace(cs), quality, fname);
153                         if (error != IMAGE_UTIL_ERROR_NONE) {
154                                 MAPS_LOGD("image_buffer=%p, w=%d, h=%d, cs=%d, quality=%d, fname=%s",
155                                         image_buffer, w, h, cs, quality, fname);
156                                 MAPS_LOGE("Failed to encode it with JPEG format. error=%d", error);
157                                 error = MAPS_ERROR_INVALID_OPERATION;
158                         }
159                 } else if (type == MAPS_VIEW_SNAPSHOT_BMP) {
160                         if (cs == MAPS_VIEW_COLORSPACE_RGBA8888) {
161                                 MAPS_LOGD("RGBA -> BGRA");
162                                 __convert_rgba_to_bgra(image_buffer, w, h);
163                                 cs = MAPS_VIEW_COLORSPACE_BGRA8888;
164                         }
165                         if (!__encode_bitmap_file(image_buffer, w, h, fname)) {
166                                 MAPS_LOGE("Failed to store it to a file.");
167                                 error = MAPS_ERROR_INVALID_OPERATION;
168                         }
169                 } else {
170                         error = MAPS_ERROR_INVALID_PARAMETER;
171                 }
172         } while (0);
173
174         if (fname) {
175                 if (error == MAPS_ERROR_NONE) {
176                         remove(path);
177                         rename(fname, path);
178                 } else {
179                         remove(fname);
180                 }
181                 free(fname);
182         }
183         g_free(image_buffer);
184         return error;
185 }