| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2005-09-14 20:46:50 +00:00
										 |  |  |  * Asterisk -- An open source telephony toolkit. | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2006-01-03 22:16:23 +00:00
										 |  |  |  * Copyright (C) 1999 - 2006, Digium, Inc. | 
					
						
							| 
									
										
										
										
											2005-09-14 20:46:50 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Mark Spencer <markster@digium.com> | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2005-09-14 20:46:50 +00:00
										 |  |  |  * See http://www.asterisk.org for more information about
 | 
					
						
							|  |  |  |  * the Asterisk project. Please do not directly contact | 
					
						
							|  |  |  |  * any of the maintainers of this project for assistance; | 
					
						
							|  |  |  |  * the project provides a web site, mailing lists and IRC | 
					
						
							|  |  |  |  * channels for your use. | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * This program is free software, distributed under the terms of | 
					
						
							| 
									
										
										
										
											2005-09-14 20:46:50 +00:00
										 |  |  |  * the GNU General Public License Version 2. See the LICENSE file | 
					
						
							|  |  |  |  * at the top of the source tree. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-10-24 20:12:06 +00:00
										 |  |  | /*! \file
 | 
					
						
							| 
									
										
										
										
											2005-09-14 20:46:50 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2005-10-24 20:12:06 +00:00
										 |  |  |  * \brief Image Management | 
					
						
							| 
									
										
										
										
											2005-12-30 21:18:06 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * \author Mark Spencer <markster@digium.com>  | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-07 18:54:56 +00:00
										 |  |  | #include "asterisk.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ASTERISK_FILE_VERSION(__FILE__, "$Revision$") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | #include <stdio.h>
 | 
					
						
							|  |  |  | #include <stdlib.h>
 | 
					
						
							|  |  |  | #include <string.h>
 | 
					
						
							|  |  |  | #include <sys/time.h>
 | 
					
						
							|  |  |  | #include <sys/stat.h>
 | 
					
						
							|  |  |  | #include <signal.h>
 | 
					
						
							|  |  |  | #include <errno.h>
 | 
					
						
							|  |  |  | #include <unistd.h>
 | 
					
						
							| 
									
										
										
										
											2005-04-22 13:11:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-21 06:02:45 +00:00
										 |  |  | #include "asterisk/sched.h"
 | 
					
						
							|  |  |  | #include "asterisk/options.h"
 | 
					
						
							|  |  |  | #include "asterisk/channel.h"
 | 
					
						
							|  |  |  | #include "asterisk/logger.h"
 | 
					
						
							|  |  |  | #include "asterisk/file.h"
 | 
					
						
							|  |  |  | #include "asterisk/image.h"
 | 
					
						
							|  |  |  | #include "asterisk/translate.h"
 | 
					
						
							|  |  |  | #include "asterisk/cli.h"
 | 
					
						
							|  |  |  | #include "asterisk/lock.h"
 | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-18 19:54:18 +00:00
										 |  |  | /* XXX Why don't we just use the formats struct for this? */ | 
					
						
							| 
									
										
										
										
											2006-01-03 08:40:55 +00:00
										 |  |  | static AST_LIST_HEAD_STATIC(imagers, ast_imager); | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | int ast_image_register(struct ast_imager *img) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (option_verbose > 1) | 
					
						
							|  |  |  | 		ast_verbose(VERBOSE_PREFIX_2 "Registered format '%s' (%s)\n", img->name, img->desc); | 
					
						
							| 
									
										
										
										
											2006-01-03 08:40:55 +00:00
										 |  |  | 	AST_LIST_LOCK(&imagers); | 
					
						
							|  |  |  | 	AST_LIST_INSERT_HEAD(&imagers, img, list); | 
					
						
							|  |  |  | 	AST_LIST_UNLOCK(&imagers); | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ast_image_unregister(struct ast_imager *img) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2006-01-03 08:40:55 +00:00
										 |  |  | 	struct ast_imager *i; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	AST_LIST_LOCK(&imagers); | 
					
						
							|  |  |  | 	AST_LIST_TRAVERSE_SAFE_BEGIN(&imagers, i, list) {	 | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | 		if (i == img) { | 
					
						
							| 
									
										
										
										
											2006-01-03 08:40:55 +00:00
										 |  |  | 			AST_LIST_REMOVE_CURRENT(&imagers, list); | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-01-03 08:40:55 +00:00
										 |  |  | 	AST_LIST_TRAVERSE_SAFE_END | 
					
						
							|  |  |  | 	AST_LIST_UNLOCK(&imagers); | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | 	if (i && (option_verbose > 1)) | 
					
						
							| 
									
										
										
										
											2004-04-21 03:54:25 +00:00
										 |  |  | 		ast_verbose(VERBOSE_PREFIX_2 "Unregistered format '%s' (%s)\n", img->name, img->desc); | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int ast_supports_images(struct ast_channel *chan) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2005-03-04 06:47:24 +00:00
										 |  |  | 	if (!chan || !chan->tech) | 
					
						
							| 
									
										
										
										
											2002-01-23 20:56:52 +00:00
										 |  |  | 		return 0; | 
					
						
							| 
									
										
										
										
											2005-03-04 06:47:24 +00:00
										 |  |  | 	if (!chan->tech->send_image) | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | 		return 0; | 
					
						
							|  |  |  | 	return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int file_exists(char *filename) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int res; | 
					
						
							|  |  |  | 	struct stat st; | 
					
						
							|  |  |  | 	res = stat(filename, &st); | 
					
						
							|  |  |  | 	if (!res) | 
					
						
							|  |  |  | 		return st.st_size; | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-02-01 23:05:28 +00:00
										 |  |  | static void make_filename(char *buf, int len, char *filename, const char *preflang, char *ext) | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	if (filename[0] == '/') { | 
					
						
							| 
									
										
										
										
											2006-03-19 15:42:49 +00:00
										 |  |  | 		if (!ast_strlen_zero(preflang)) | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | 			snprintf(buf, len, "%s-%s.%s", filename, preflang, ext); | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			snprintf(buf, len, "%s.%s", filename, ext); | 
					
						
							|  |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2006-03-19 15:42:49 +00:00
										 |  |  | 		if (!ast_strlen_zero(preflang)) | 
					
						
							| 
									
										
										
										
											2006-04-15 22:53:53 +00:00
										 |  |  | 			snprintf(buf, len, "%s/%s/%s-%s.%s", ast_config_AST_DATA_DIR, "images", filename, preflang, ext); | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | 		else | 
					
						
							| 
									
										
										
										
											2006-04-15 22:53:53 +00:00
										 |  |  | 			snprintf(buf, len, "%s/%s/%s.%s", ast_config_AST_DATA_DIR, "images", filename, ext); | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-02-01 23:05:28 +00:00
										 |  |  | struct ast_frame *ast_read_image(char *filename, const char *preflang, int format) | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	struct ast_imager *i; | 
					
						
							|  |  |  | 	char buf[256]; | 
					
						
							|  |  |  | 	char tmp[80]; | 
					
						
							|  |  |  | 	char *e; | 
					
						
							|  |  |  | 	struct ast_imager *found = NULL; | 
					
						
							|  |  |  | 	int fd; | 
					
						
							|  |  |  | 	int len=0; | 
					
						
							|  |  |  | 	struct ast_frame *f = NULL; | 
					
						
							| 
									
										
										
										
											2006-01-03 08:40:55 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	AST_LIST_LOCK(&imagers); | 
					
						
							|  |  |  | 	AST_LIST_TRAVERSE(&imagers, i, list) { | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | 		if (i->format & format) { | 
					
						
							| 
									
										
										
										
											2003-01-30 15:03:20 +00:00
										 |  |  | 			char *stringp=NULL; | 
					
						
							| 
									
										
										
										
											2006-10-25 14:32:08 +00:00
										 |  |  | 			ast_copy_string(tmp, i->exts, sizeof(tmp)); | 
					
						
							| 
									
										
										
										
											2003-01-30 15:03:20 +00:00
										 |  |  | 			stringp=tmp; | 
					
						
							|  |  |  | 			e = strsep(&stringp, "|"); | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | 			while(e) { | 
					
						
							|  |  |  | 				make_filename(buf, sizeof(buf), filename, preflang, e); | 
					
						
							|  |  |  | 				if ((len = file_exists(buf))) { | 
					
						
							|  |  |  | 					found = i; | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				make_filename(buf, sizeof(buf), filename, NULL, e); | 
					
						
							|  |  |  | 				if ((len = file_exists(buf))) { | 
					
						
							|  |  |  | 					found = i; | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2003-01-30 15:03:20 +00:00
										 |  |  | 				e = strsep(&stringp, "|"); | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2006-01-03 08:40:55 +00:00
										 |  |  | 		if (found) | 
					
						
							|  |  |  | 			break;	 | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-01-03 08:40:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | 	if (found) { | 
					
						
							|  |  |  | 		fd = open(buf, O_RDONLY); | 
					
						
							|  |  |  | 		if (fd > -1) { | 
					
						
							|  |  |  | 			if (!found->identify || found->identify(fd)) { | 
					
						
							|  |  |  | 				/* Reset file pointer */ | 
					
						
							|  |  |  | 				lseek(fd, 0, SEEK_SET); | 
					
						
							|  |  |  | 				f = found->read_image(fd,len);  | 
					
						
							|  |  |  | 			} else | 
					
						
							| 
									
										
										
										
											2006-03-24 14:51:15 +00:00
										 |  |  | 				ast_log(LOG_WARNING, "%s does not appear to be a %s file\n", buf, found->name); | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | 			close(fd); | 
					
						
							|  |  |  | 		} else | 
					
						
							|  |  |  | 			ast_log(LOG_WARNING, "Unable to open '%s': %s\n", buf, strerror(errno)); | 
					
						
							|  |  |  | 	} else | 
					
						
							|  |  |  | 		ast_log(LOG_WARNING, "Image file '%s' not found\n", filename); | 
					
						
							| 
									
										
										
										
											2006-01-03 08:40:55 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	AST_LIST_UNLOCK(&imagers); | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | 	return f; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int ast_send_image(struct ast_channel *chan, char *filename) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ast_frame *f; | 
					
						
							|  |  |  | 	int res = -1; | 
					
						
							| 
									
										
										
										
											2005-03-04 06:47:24 +00:00
										 |  |  | 	if (chan->tech->send_image) { | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | 		f = ast_read_image(filename, chan->language, -1); | 
					
						
							|  |  |  | 		if (f) { | 
					
						
							| 
									
										
										
										
											2005-03-04 06:47:24 +00:00
										 |  |  | 			res = chan->tech->send_image(chan, f); | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | 			ast_frfree(f); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return res; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-18 19:54:18 +00:00
										 |  |  | static int show_image_formats_deprecated(int fd, int argc, char *argv[]) | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | { | 
					
						
							|  |  |  | #define FORMAT "%10s %10s %50s %10s\n"
 | 
					
						
							| 
									
										
										
										
											2003-08-16 05:10:35 +00:00
										 |  |  | #define FORMAT2 "%10s %10s %50s %10s\n"
 | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | 	struct ast_imager *i; | 
					
						
							|  |  |  | 	if (argc != 3) | 
					
						
							|  |  |  | 		return RESULT_SHOWUSAGE; | 
					
						
							|  |  |  | 	ast_cli(fd, FORMAT, "Name", "Extensions", "Description", "Format"); | 
					
						
							| 
									
										
										
										
											2006-01-03 08:40:55 +00:00
										 |  |  | 	AST_LIST_TRAVERSE(&imagers, i, list) | 
					
						
							| 
									
										
										
										
											2003-08-16 05:10:35 +00:00
										 |  |  | 		ast_cli(fd, FORMAT2, i->name, i->exts, i->desc, ast_getformatname(i->format)); | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | 	return RESULT_SUCCESS; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-18 19:54:18 +00:00
										 |  |  | static int show_image_formats(int fd, int argc, char *argv[]) | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2006-09-18 19:54:18 +00:00
										 |  |  | #define FORMAT "%10s %10s %50s %10s\n"
 | 
					
						
							|  |  |  | #define FORMAT2 "%10s %10s %50s %10s\n"
 | 
					
						
							|  |  |  | 	struct ast_imager *i; | 
					
						
							|  |  |  | 	if (argc != 4) | 
					
						
							|  |  |  | 		return RESULT_SHOWUSAGE; | 
					
						
							|  |  |  | 	ast_cli(fd, FORMAT, "Name", "Extensions", "Description", "Format"); | 
					
						
							|  |  |  | 	AST_LIST_TRAVERSE(&imagers, i, list) | 
					
						
							|  |  |  | 		ast_cli(fd, FORMAT2, i->name, i->exts, i->desc, ast_getformatname(i->format)); | 
					
						
							|  |  |  | 	return RESULT_SUCCESS; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct ast_cli_entry cli_show_image_formats_deprecated = { | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | 	{ "show", "image", "formats" }, | 
					
						
							| 
									
										
										
										
											2006-09-18 19:54:18 +00:00
										 |  |  | 	show_image_formats_deprecated, NULL, | 
					
						
							|  |  |  | 	NULL }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct ast_cli_entry cli_image[] = { | 
					
						
							| 
									
										
										
										
											2006-11-02 23:00:20 +00:00
										 |  |  | 	{ { "core", "show", "image", "formats" }, | 
					
						
							| 
									
										
										
										
											2006-09-18 19:54:18 +00:00
										 |  |  | 	show_image_formats, "Displays image formats", | 
					
						
							| 
									
										
										
										
											2006-11-02 23:00:20 +00:00
										 |  |  | 	"Usage: core show image formats\n" | 
					
						
							| 
									
										
										
										
											2006-09-18 19:54:18 +00:00
										 |  |  | 	"       displays currently registered image formats (if any)\n", NULL, &cli_show_image_formats_deprecated }, | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int ast_image_init(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2006-09-18 19:54:18 +00:00
										 |  |  | 	ast_cli_register_multiple(cli_image, sizeof(cli_image) / sizeof(struct ast_cli_entry)); | 
					
						
							|  |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2001-05-27 14:51:50 +00:00
										 |  |  | } |