8c4c4e3371b8cc52228c76e8b987b73b0283729f
[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 #include "asterisk.h"
28
29 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
30
31 #include <netinet/in.h>
32 #include <arpa/inet.h>
33 #include <sys/time.h>
34 #include <errno.h>
35
36 #include "asterisk/channel.h"
37 #include "asterisk/file.h"
38 #include "asterisk/logger.h"
39 #include "asterisk/sched.h"
40 #include "asterisk/module.h"
41 #include "asterisk/image.h"
42 #include "asterisk/lock.h"
43 #include "asterisk/endian.h"
44
45 static struct ast_frame *jpeg_read_image(int fd, int len)
46 {
47         struct ast_frame fr;
48         int res;
49         char buf[65536];
50         if (len > sizeof(buf) || len < 0) {
51                 ast_log(LOG_WARNING, "JPEG image too large to read\n");
52                 return NULL;
53         }
54         res = read(fd, buf, len);
55         if (res < len) {
56                 ast_log(LOG_WARNING, "Only read %d of %d bytes: %s\n", res, len, strerror(errno));
57         }
58         memset(&fr, 0, sizeof(fr));
59         fr.frametype = AST_FRAME_IMAGE;
60         fr.subclass = AST_FORMAT_JPEG;
61         fr.data = buf;
62         fr.src = "JPEG Read";
63         fr.datalen = len;
64         return ast_frisolate(&fr);
65 }
66
67 static int jpeg_identify(int fd)
68 {
69         char buf[10];
70         int res;
71         res = read(fd, buf, sizeof(buf));
72         if (res < sizeof(buf))
73                 return 0;
74         if (memcmp(buf + 6, "JFIF", 4))
75                 return 0;
76         return 1;
77 }
78
79 static int jpeg_write_image(int fd, struct ast_frame *fr)
80 {
81         int res=0;
82         if (fr->frametype != AST_FRAME_IMAGE) {
83                 ast_log(LOG_WARNING, "Not an image\n");
84                 return -1;
85         }
86         if (fr->subclass != AST_FORMAT_JPEG) {
87                 ast_log(LOG_WARNING, "Not a jpeg image\n");
88                 return -1;
89         }
90         if (fr->datalen) {
91                 res = write(fd, fr->data, fr->datalen);
92                 if (res != fr->datalen) {
93                         ast_log(LOG_WARNING, "Only wrote %d of %d bytes: %s\n", res, fr->datalen, strerror(errno));
94                         return -1;
95                 }
96         }
97         return res;
98 }
99
100 static struct ast_imager jpeg_format = {
101         "jpg",
102         "JPEG (Joint Picture Experts Group)",
103         "jpg|jpeg",
104         AST_FORMAT_JPEG,
105         jpeg_read_image,
106         jpeg_identify,
107         jpeg_write_image,
108 };
109
110 static int load_module(void)
111 {
112         if (ast_image_register(&jpeg_format))
113                 return AST_MODULE_LOAD_FAILURE;
114         return AST_MODULE_LOAD_SUCCESS;
115 }
116
117 static int unload_module(void)
118 {
119         ast_image_unregister(&jpeg_format);
120
121         return 0;
122 }       
123
124 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "JPEG (Joint Picture Experts Group) Image Format");