2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 1999 - 2006, Digium, Inc.
6 * Mark Spencer <markster@digium.com>
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2. See the LICENSE file
16 * at the top of the source tree.
21 * \brief Image Management
23 * \author Mark Spencer <markster@digium.com>
28 ASTERISK_FILE_VERSION(__FILE__
, "$Revision$")
39 #include "asterisk/sched.h"
40 #include "asterisk/options.h"
41 #include "asterisk/channel.h"
42 #include "asterisk/logger.h"
43 #include "asterisk/file.h"
44 #include "asterisk/image.h"
45 #include "asterisk/translate.h"
46 #include "asterisk/cli.h"
47 #include "asterisk/lock.h"
49 /* XXX Why don't we just use the formats struct for this? */
50 static AST_LIST_HEAD_STATIC(imagers
, ast_imager
);
52 int ast_image_register(struct ast_imager
*img
)
54 if (option_verbose
> 1)
55 ast_verbose(VERBOSE_PREFIX_2
"Registered format '%s' (%s)\n", img
->name
, img
->desc
);
56 AST_LIST_LOCK(&imagers
);
57 AST_LIST_INSERT_HEAD(&imagers
, img
, list
);
58 AST_LIST_UNLOCK(&imagers
);
62 void ast_image_unregister(struct ast_imager
*img
)
66 AST_LIST_LOCK(&imagers
);
67 AST_LIST_TRAVERSE_SAFE_BEGIN(&imagers
, i
, list
) {
69 AST_LIST_REMOVE_CURRENT(&imagers
, list
);
73 AST_LIST_TRAVERSE_SAFE_END
74 AST_LIST_UNLOCK(&imagers
);
75 if (i
&& (option_verbose
> 1))
76 ast_verbose(VERBOSE_PREFIX_2
"Unregistered format '%s' (%s)\n", img
->name
, img
->desc
);
79 int ast_supports_images(struct ast_channel
*chan
)
81 if (!chan
|| !chan
->tech
)
83 if (!chan
->tech
->send_image
)
88 static int file_exists(char *filename
)
92 res
= stat(filename
, &st
);
98 static void make_filename(char *buf
, int len
, char *filename
, const char *preflang
, char *ext
)
100 if (filename
[0] == '/') {
101 if (!ast_strlen_zero(preflang
))
102 snprintf(buf
, len
, "%s-%s.%s", filename
, preflang
, ext
);
104 snprintf(buf
, len
, "%s.%s", filename
, ext
);
106 if (!ast_strlen_zero(preflang
))
107 snprintf(buf
, len
, "%s/%s/%s-%s.%s", ast_config_AST_DATA_DIR
, "images", filename
, preflang
, ext
);
109 snprintf(buf
, len
, "%s/%s/%s.%s", ast_config_AST_DATA_DIR
, "images", filename
, ext
);
113 struct ast_frame
*ast_read_image(char *filename
, const char *preflang
, int format
)
115 struct ast_imager
*i
;
119 struct ast_imager
*found
= NULL
;
122 struct ast_frame
*f
= NULL
;
124 AST_LIST_LOCK(&imagers
);
125 AST_LIST_TRAVERSE(&imagers
, i
, list
) {
126 if (i
->format
& format
) {
128 ast_copy_string(tmp
, i
->exts
, sizeof(tmp
));
130 e
= strsep(&stringp
, "|");
132 make_filename(buf
, sizeof(buf
), filename
, preflang
, e
);
133 if ((len
= file_exists(buf
))) {
137 make_filename(buf
, sizeof(buf
), filename
, NULL
, e
);
138 if ((len
= file_exists(buf
))) {
142 e
= strsep(&stringp
, "|");
150 fd
= open(buf
, O_RDONLY
);
152 if (!found
->identify
|| found
->identify(fd
)) {
153 /* Reset file pointer */
154 lseek(fd
, 0, SEEK_SET
);
155 f
= found
->read_image(fd
,len
);
157 ast_log(LOG_WARNING
, "%s does not appear to be a %s file\n", buf
, found
->name
);
160 ast_log(LOG_WARNING
, "Unable to open '%s': %s\n", buf
, strerror(errno
));
162 ast_log(LOG_WARNING
, "Image file '%s' not found\n", filename
);
164 AST_LIST_UNLOCK(&imagers
);
169 int ast_send_image(struct ast_channel
*chan
, char *filename
)
173 if (chan
->tech
->send_image
) {
174 f
= ast_read_image(filename
, chan
->language
, -1);
176 res
= chan
->tech
->send_image(chan
, f
);
183 static int show_image_formats_deprecated(int fd
, int argc
, char *argv
[])
185 #define FORMAT "%10s %10s %50s %10s\n"
186 #define FORMAT2 "%10s %10s %50s %10s\n"
187 struct ast_imager
*i
;
189 return RESULT_SHOWUSAGE
;
190 ast_cli(fd
, FORMAT
, "Name", "Extensions", "Description", "Format");
191 AST_LIST_TRAVERSE(&imagers
, i
, list
)
192 ast_cli(fd
, FORMAT2
, i
->name
, i
->exts
, i
->desc
, ast_getformatname(i
->format
));
193 return RESULT_SUCCESS
;
196 static int show_image_formats(int fd
, int argc
, char *argv
[])
198 #define FORMAT "%10s %10s %50s %10s\n"
199 #define FORMAT2 "%10s %10s %50s %10s\n"
200 struct ast_imager
*i
;
202 return RESULT_SHOWUSAGE
;
203 ast_cli(fd
, FORMAT
, "Name", "Extensions", "Description", "Format");
204 AST_LIST_TRAVERSE(&imagers
, i
, list
)
205 ast_cli(fd
, FORMAT2
, i
->name
, i
->exts
, i
->desc
, ast_getformatname(i
->format
));
206 return RESULT_SUCCESS
;
209 struct ast_cli_entry cli_show_image_formats_deprecated
= {
210 { "show", "image", "formats" },
211 show_image_formats_deprecated
, NULL
,
214 struct ast_cli_entry cli_image
[] = {
215 { { "core", "show", "image", "formats" },
216 show_image_formats
, "Displays image formats",
217 "Usage: core show image formats\n"
218 " displays currently registered image formats (if any)\n", NULL
, &cli_show_image_formats_deprecated
},
221 int ast_image_init(void)
223 ast_cli_register_multiple(cli_image
, sizeof(cli_image
) / sizeof(struct ast_cli_entry
));