Asterisk.org: Developer Documentation (28 Oct 2009)

Wed Oct 28 15:47:54 2009

## Asterisk developer's documentation

- Main Page
- Related Pages
- Modules
- Data Structures
- Files
- Directories

# image.c

Go to the documentation of this file.

    00001 /*
    00002  * Asterisk -- An open source telephony toolkit.
    00003  *
    00004  * Copyright (C) 1999 - 2005, Digium, Inc.
    00005  *
    00006  * Mark Spencer <markster@digium.com>
    00007  *
    00008  * See http://www.asterisk.org for more information about
    00009  * the Asterisk project. Please do not directly contact
    00010  * any of the maintainers of this project for assistance;
    00011  * the project provides a web site, mailing lists and IRC
    00012  * channels for your use.
    00013  *
    00014  * This program is free software, distributed under the terms of
    00015  * the GNU General Public License Version 2. See the LICENSE file
    00016  * at the top of the source tree.
    00017  */
    00018
    00019 /*! \file
    00020  *
    00021  * \brief Image Management
    00022  *
    00023  */
    00024
    00025 #include <stdio.h>
    00026 #include <stdlib.h>
    00027 #include <string.h>
    00028 #include <sys/time.h>
    00029 #include <sys/stat.h>
    00030 #include <signal.h>
    00031 #include <errno.h>
    00032 #include <unistd.h>
    00033
    00034 #include "asterisk.h"
    00035
    00036 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 14704 $")
    00037
    00038 #include "asterisk/sched.h"
    00039 #include "asterisk/options.h"
    00040 #include "asterisk/channel.h"
    00041 #include "asterisk/logger.h"
    00042 #include "asterisk/file.h"
    00043 #include "asterisk/image.h"
    00044 #include "asterisk/translate.h"
    00045 #include "asterisk/cli.h"
    00046 #include "asterisk/lock.h"
    00047
    00048 static struct ast_imager *list;
    00049 AST_MUTEX_DEFINE_STATIC(listlock);
    00050
    00051 int ast_image_register(struct ast_imager *img)
    00052 {
    00053    if (option_verbose > 1)
    00054       ast_verbose(VERBOSE_PREFIX_2 "Registered format '%s' (%s)\n", img->name, img->desc);
    00055    ast_mutex_lock(&listlock);
    00056    img->next = list;
    00057    list = img;
    00058    ast_mutex_unlock(&listlock);
    00059    return 0;
    00060 }
    00061
    00062 void ast_image_unregister(struct ast_imager *img)
    00063 {
    00064    struct ast_imager *i, *prev = NULL;
    00065    ast_mutex_lock(&listlock);
    00066    i = list;
    00067    while(i) {
    00068       if (i == img) {
    00069          if (prev)
    00070             prev->next = i->next;
    00071          else
    00072             list = i->next;
    00073          break;
    00074       }
    00075       prev = i;
    00076       i = i->next;
    00077    }
    00078    ast_mutex_unlock(&listlock);
    00079    if (i && (option_verbose > 1))
    00080       ast_verbose(VERBOSE_PREFIX_2 "Unregistered format '%s' (%s)\n", img->name, img->desc);
    00081 }
    00082
    00083 int ast_supports_images(struct ast_channel *chan)
    00084 {
    00085    if (!chan || !chan->tech)
    00086       return 0;
    00087    if (!chan->tech->send_image)
    00088       return 0;
    00089    return 1;
    00090 }
    00091
    00092 static int file_exists(char *filename)
    00093 {
    00094    int res;
    00095    struct stat st;
    00096    res = stat(filename, &st);
    00097    if (!res)
    00098       return st.st_size;
    00099    return 0;
    00100 }
    00101
    00102 static void make_filename(char *buf, int len, char *filename, char *preflang, char *ext)
    00103 {
    00104    if (filename[0] == '/') {
    00105       if (preflang && strlen(preflang))
    00106          snprintf(buf, len, "%s-%s.%s", filename, preflang, ext);
    00107       else
    00108          snprintf(buf, len, "%s.%s", filename, ext);
    00109    } else {
    00110       if (preflang && strlen(preflang))
    00111          snprintf(buf, len, "%s/%s/%s-%s.%s", ast_config_AST_VAR_DIR, "images", filename, preflang, ext);
    00112       else
    00113          snprintf(buf, len, "%s/%s/%s.%s", ast_config_AST_VAR_DIR, "images", filename, ext);
    00114    }
    00115 }
    00116
    00117 struct ast_frame *ast_read_image(char *filename, char *preflang, int format)
    00118 {
    00119    struct ast_imager *i;
    00120    char buf[256];
    00121    char tmp[80];
    00122    char *e;
    00123    struct ast_imager *found = NULL;
    00124    int fd;
    00125    int len=0;
    00126    struct ast_frame *f = NULL;
    00127 #if 0 /* We need to have some sort of read-only lock */
    00128    ast_mutex_lock(&listlock);
    00129 #endif
    00130    i = list;
    00131    while(!found && i) {
    00132       if (i->format & format) {
    00133          char *stringp=NULL;
    00134          strncpy(tmp, i->exts, sizeof(tmp)-1);
    00135          stringp=tmp;
    00136          e = strsep(&stringp, "|");
    00137          while(e) {
    00138             make_filename(buf, sizeof(buf), filename, preflang, e);
    00139             if ((len = file_exists(buf))) {
    00140                found = i;
    00141                break;
    00142             }
    00143             make_filename(buf, sizeof(buf), filename, NULL, e);
    00144             if ((len = file_exists(buf))) {
    00145                found = i;
    00146                break;
    00147             }
    00148             e = strsep(&stringp, "|");
    00149          }
    00150       }
    00151       i = i->next;
    00152    }
    00153    if (found) {
    00154       fd = open(buf, O_RDONLY);
    00155       if (fd > -1) {
    00156          if (!found->identify || found->identify(fd)) {
    00157             /* Reset file pointer */
    00158             lseek(fd, 0, SEEK_SET);
    00159             f = found->read_image(fd,len);
    00160          } else
    00161             ast_log(LOG_WARNING, "%s does not appear to be a %s file\n", buf, found->name);
    00162          close(fd);
    00163       } else
    00164          ast_log(LOG_WARNING, "Unable to open '%s': %s\n", buf, strerror(errno));
    00165    } else
    00166       ast_log(LOG_WARNING, "Image file '%s' not found\n", filename);
    00167 #if 0
    00168    ast_mutex_unlock(&listlock);
    00169 #endif
    00170    return f;
    00171 }
    00172
    00173
    00174 int ast_send_image(struct ast_channel *chan, char *filename)
    00175 {
    00176    struct ast_frame *f;
    00177    int res = -1;
    00178    if (chan->tech->send_image) {
    00179       f = ast_read_image(filename, chan->language, -1);
    00180       if (f) {
    00181          res = chan->tech->send_image(chan, f);
    00182          ast_frfree(f);
    00183       }
    00184    }
    00185    return res;
    00186 }
    00187
    00188 static int show_image_formats(int fd, int argc, char *argv[])
    00189 {
    00190 #define FORMAT "%10s %10s %50s %10s\n"
    00191 #define FORMAT2 "%10s %10s %50s %10s\n"
    00192    struct ast_imager *i;
    00193    if (argc != 3)
    00194       return RESULT_SHOWUSAGE;
    00195    ast_cli(fd, FORMAT, "Name", "Extensions", "Description", "Format");
    00196    i = list;
    00197    while(i) {
    00198       ast_cli(fd, FORMAT2, i->name, i->exts, i->desc, ast_getformatname(i->format));
    00199       i = i->next;
    00200    };
    00201    return RESULT_SUCCESS;
    00202 }
    00203
    00204 struct ast_cli_entry show_images =
    00205 {
    00206    { "show", "image", "formats" },
    00207    show_image_formats,
    00208    "Displays image formats",
    00209 "Usage: show image formats\n"
    00210 "       displays currently registered image formats (if any)\n"
    00211 };
    00212
    00213
    00214 int ast_image_init(void)
    00215 {
    00216    ast_cli_register(&show_images);
    00217    return 0;
    00218 }
    00219