1 /* Copyright (c) 2010-2014 Samsung Electronics Co., Ltd. All rights reserved.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 #include <image_util.h>
19 #include <unistd.h> /* access */
21 #include <maps_view_plugin.h>
22 #include <maps_condition.h>
24 #include <empty_module.h>
25 #include "maps_condition.h"
28 const plugin::interface_s *__get_plugin_interface(maps_view_h view);
30 static void __convert_rgba_to_bgra(unsigned char *data, int width, int height)
32 int len = width * height;
33 unsigned int *p = (unsigned int *)data;
34 for (int i = 0; i < len; i++)
36 *p = (*p & 0xFF00FF00) |
37 ((*p & 0x00FF0000) >> 16) |
38 ((*p & 0x000000FF) << 16);
43 static bool __encode_bitmap_file(const void *data, int width, int height, const char *file)
46 unsigned char magic[2];
47 } bmpfile_magic = { {'B', 'M'} };
51 unsigned short creator1;
52 unsigned short creator2;
53 unsigned int bmp_offset;
54 } bmpfile_header = { 0, 0, 0, 0x36 };
57 unsigned int header_sz;
60 unsigned short nplanes;
61 unsigned short bitspp;
62 unsigned int compress_type;
63 unsigned int bmp_bytesz;
67 unsigned int nimpcolors;
68 } bmp_dib_v3_header_t = { 0x28, 0, 0, 1, 24, 0, 0, 0, 0, 0, 0 };
71 FILE *fp = fopen(file, "w+");
75 MAPS_LOGE("fopen fail");
78 bmpfile_header.filesz = sizeof(bmpfile_magic) + sizeof(bmpfile_header) + sizeof(bmp_dib_v3_header_t) + (width * height * 3);
79 bmp_dib_v3_header_t.header_sz = sizeof(bmp_dib_v3_header_t);
80 bmp_dib_v3_header_t.width = width;
81 bmp_dib_v3_header_t.height = -height;
82 bmp_dib_v3_header_t.bmp_bytesz = width * height * 3;
84 fwrite(&bmpfile_magic, sizeof(bmpfile_magic), 1, fp);
85 fwrite(&bmpfile_header, sizeof(bmpfile_header), 1, fp);
86 fwrite(&bmp_dib_v3_header_t, sizeof(bmp_dib_v3_header_t), 1, fp);
87 blocks = (unsigned int *)data;
89 for (i = 0; i < height * width; i++) {
90 fwrite(&blocks[i], 3, 1, fp);
96 static image_util_colorspace_e __convert_colorspace(maps_view_colorspace_type_e cs)
99 case MAPS_VIEW_COLORSPACE_RGBA8888:
100 return IMAGE_UTIL_COLORSPACE_RGBA8888;
101 case MAPS_VIEW_COLORSPACE_BGRA8888:
102 return IMAGE_UTIL_COLORSPACE_BGRA8888;
104 return IMAGE_UTIL_COLORSPACE_RGBA8888;
107 static int __encode_to_jpeg(unsigned char *image_buffer, int w, int h,
108 maps_view_colorspace_type_e cs, int quality, const char *file_path)
110 if (!image_buffer || !file_path || (file_path && *file_path == '\0'))
111 return MAPS_ERROR_INVALID_OPERATION;
112 #if (TIZEN_VER >= VERSION(3, 0, 0))
113 image_util_encode_h image_handle = NULL;
114 unsigned long long image_size = 0;
115 int error = IMAGE_UTIL_ERROR_NONE;
118 error = image_util_encode_create(IMAGE_UTIL_JPEG, &image_handle);
119 if (error != IMAGE_UTIL_ERROR_NONE) {
120 MAPS_LOGE("Failed to create the image handle with JPEG format. error=%d", error);
123 error = image_util_encode_set_input_buffer(image_handle, image_buffer);
124 if (error != IMAGE_UTIL_ERROR_NONE) {
125 MAPS_LOGE("Failed to set image_buffer to image handle. error=%d", error);
128 error = image_util_encode_set_resolution(image_handle, w, h);
129 if (error != IMAGE_UTIL_ERROR_NONE) {
130 MAPS_LOGE("Failed to set resolution to image handle. error=%d", error);
133 error = image_util_encode_set_colorspace(image_handle, __convert_colorspace(cs));
134 if (error != IMAGE_UTIL_ERROR_NONE) {
135 MAPS_LOGE("Failed to set colorspace to image handle. error=%d", error);
138 error = image_util_encode_set_quality(image_handle, quality);
139 if (error != IMAGE_UTIL_ERROR_NONE) {
140 MAPS_LOGE("Failed to set quality to image handle. error=%d", error);
143 error = image_util_encode_set_output_path(image_handle, file_path);
144 if (error != IMAGE_UTIL_ERROR_NONE) {
145 MAPS_LOGE("Failed to set path to image handle. error=%d", error);
148 error = image_util_encode_run(image_handle, &image_size);
149 if (error != IMAGE_UTIL_ERROR_NONE) {
150 MAPS_LOGE("Failed to encode with image handle. error=%d", error);
155 image_util_encode_destroy(image_handle);
158 int error = image_util_encode_jpeg(image_buffer, w, h,
159 __convert_colorspace(cs), quality, file_path);
160 if (error != IMAGE_UTIL_ERROR_NONE) {
161 MAPS_LOGD("image_buffer=%p, w=%d, h=%d, cs=%d, quality=%d, file_path=%s",
162 image_buffer, w, h, cs, quality, file_path);
163 MAPS_LOGE("Failed to encode it with JPEG format. error=%d", error);
167 return (error == IMAGE_UTIL_ERROR_NONE ? MAPS_ERROR_NONE : MAPS_ERROR_INVALID_OPERATION);
170 static int __encode_to_bmp(unsigned char *image_buffer, int w, int h,
171 maps_view_colorspace_type_e cs, const char *file_path)
173 if (!image_buffer || !file_path || (file_path && *file_path == '\0'))
174 return MAPS_ERROR_INVALID_OPERATION;
176 int error = MAPS_ERROR_NONE;
178 if (cs == MAPS_VIEW_COLORSPACE_RGBA8888) {
179 __convert_rgba_to_bgra(image_buffer, w, h);
180 cs = MAPS_VIEW_COLORSPACE_BGRA8888;
183 if (!__encode_bitmap_file(image_buffer, w, h, file_path)) {
184 MAPS_LOGE("Failed to store it to a file.");
185 error = MAPS_ERROR_INVALID_OPERATION;
190 static int __build_tmp_path(const char *path, char **tmp_path)
192 if (!path || !tmp_path)
193 return MAPS_ERROR_INVALID_PARAMETER;
195 int error = MAPS_ERROR_NONE;
196 int tmp_path_len = strlen(path);
197 *tmp_path = (char*)malloc(tmp_path_len + 10);
199 return MAPS_ERROR_INVALID_OPERATION;
202 const int retry_max = 20;
203 sprintf(*tmp_path, "%s.tmp", path);
204 while(access(*tmp_path, F_OK) != -1 && ++retry < retry_max) {
205 sprintf(*tmp_path, "%s.tmp%d", path, retry);
207 if (retry >= retry_max) {
208 MAPS_LOGD("There are already too many temporary files.");
209 error = MAPS_ERROR_INVALID_OPERATION;
217 EXPORT_API int maps_view_capture_snapshot(maps_view_h view,
218 maps_view_snapshot_format_type_e type,
222 if (!maps_condition_check_maps_feature())
223 return MAPS_ERROR_NOT_SUPPORTED;
225 return MAPS_ERROR_INVALID_PARAMETER;
226 if (!maps_condition_check_view_service_supported(view, MAPS_SERVICE_VIEW_SNAPSHOT))
227 return MAPS_ERROR_NOT_SUPPORTED;
228 if (type < MAPS_VIEW_SNAPSHOT_BMP || type > MAPS_VIEW_SNAPSHOT_JPEG ||
229 quality < 0 || quality > 100 || !path || (path && *path == '\0'))
230 return MAPS_ERROR_INVALID_PARAMETER;
231 if (!maps_condition_check_privilege())
232 return MAPS_ERROR_PERMISSION_DENIED;
234 int error = MAPS_ERROR_UNKNOWN;
236 unsigned char *image_buffer = NULL;
237 maps_view_colorspace_type_e cs = MAPS_VIEW_COLORSPACE_RGBA8888;
238 char *tmp_path = NULL;
241 if (!__get_plugin_interface(view)->maps_plugin_capture_snapshot) {
242 error = MAPS_ERROR_SERVICE_NOT_AVAILABLE;
246 error = __get_plugin_interface(view)->maps_plugin_capture_snapshot(view,
247 (void**)&image_buffer, &w, &h, &cs);
248 if (error != MAPS_ERROR_NONE) break;
250 if (cs != MAPS_VIEW_COLORSPACE_RGBA8888 && cs != MAPS_VIEW_COLORSPACE_BGRA8888) {
251 MAPS_LOGE("The color space is not supported yet. (%d)", cs);
252 error = MAPS_ERROR_INVALID_OPERATION;
256 error = __build_tmp_path(path, &tmp_path);
257 if (error != MAPS_ERROR_NONE) break;
259 if (type == MAPS_VIEW_SNAPSHOT_JPEG) {
260 error = __encode_to_jpeg(image_buffer, w, h, cs, quality, tmp_path);
261 } else if (type == MAPS_VIEW_SNAPSHOT_BMP) {
262 error = __encode_to_bmp(image_buffer, w, h, cs, tmp_path);
264 error = MAPS_ERROR_INVALID_PARAMETER;
269 if (error == MAPS_ERROR_NONE) {
270 MAPS_LOGD("The snapshot is saved to %s", path);
272 rename(tmp_path, path);
278 g_free(image_buffer);