modules: change module LOAD_FAILUREs to LOAD_DECLINES
[asterisk/asterisk.git] / formats / format_jpeg.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2005, Digium, Inc.
5  *
6  * Mark Spencer <markster@digium.com>
7  *
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.
13  *
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.
17  */
18
19 /*! \file
20  *
21  * \brief JPEG File format support.
22  * 
23  * \arg File name extension: jpeg, jpg
24  * \ingroup formats
25  */
26
27 /*** MODULEINFO
28         <support_level>extended</support_level>
29  ***/
30  
31 #include "asterisk.h"
32
33 #include "asterisk/mod_format.h"
34 #include "asterisk/module.h"
35 #include "asterisk/image.h"
36 #include "asterisk/endian.h"
37 #include "asterisk/format_cache.h"
38
39 static struct ast_frame *jpeg_read_image(int fd, int len)
40 {
41         struct ast_frame fr;
42         int res;
43         char buf[65536];
44         if (len > sizeof(buf) || len < 0) {
45                 ast_log(LOG_WARNING, "JPEG image too large to read\n");
46                 return NULL;
47         }
48         res = read(fd, buf, len);
49         if (res < len) {
50                 ast_log(LOG_WARNING, "Only read %d of %d bytes: %s\n", res, len, strerror(errno));
51         }
52         memset(&fr, 0, sizeof(fr));
53         fr.frametype = AST_FRAME_IMAGE;
54         fr.subclass.format = ast_format_jpeg;
55         fr.data.ptr = buf;
56         fr.src = "JPEG Read";
57         fr.datalen = len;
58         return ast_frisolate(&fr);
59 }
60
61 static int jpeg_identify(int fd)
62 {
63         char buf[10];
64         int res;
65         res = read(fd, buf, sizeof(buf));
66         if (res < sizeof(buf))
67                 return 0;
68         if (memcmp(buf + 6, "JFIF", 4))
69                 return 0;
70         return 1;
71 }
72
73 static int jpeg_write_image(int fd, struct ast_frame *fr)
74 {
75         int res=0;
76         if (fr->datalen) {
77                 res = write(fd, fr->data.ptr, fr->datalen);
78                 if (res != fr->datalen) {
79                         ast_log(LOG_WARNING, "Only wrote %d of %d bytes: %s\n", res, fr->datalen, strerror(errno));
80                         return -1;
81                 }
82         }
83         return res;
84 }
85
86 static struct ast_imager jpeg_format = {
87         .name = "jpg",
88         .desc = "JPEG (Joint Picture Experts Group)",
89         .exts = "jpg|jpeg",
90         .read_image = jpeg_read_image,
91         .identify = jpeg_identify,
92         .write_image = jpeg_write_image,
93 };
94
95 static int load_module(void)
96 {
97         jpeg_format.format = ast_format_jpeg;
98         if (ast_image_register(&jpeg_format))
99                 return AST_MODULE_LOAD_DECLINE;
100         return AST_MODULE_LOAD_SUCCESS;
101 }
102
103 static int unload_module(void)
104 {
105         ast_image_unregister(&jpeg_format);
106
107         return 0;
108 }
109
110 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "jpeg (joint picture experts group) image format",
111         .support_level = AST_MODULE_SUPPORT_EXTENDED,
112         .load = load_module,
113         .unload = unload_module,
114         .load_pri = AST_MODPRI_APP_DEPEND
115 );