Add load priority order, such that preload becomes unnecessary in most cases
[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 "asterisk/mod_format.h"
32 #include "asterisk/module.h"
33 #include "asterisk/image.h"
34 #include "asterisk/endian.h"
35
36 static struct ast_frame *jpeg_read_image(int fd, int len)
37 {
38         struct ast_frame fr;
39         int res;
40         char buf[65536];
41         if (len > sizeof(buf) || len < 0) {
42                 ast_log(LOG_WARNING, "JPEG image too large to read\n");
43                 return NULL;
44         }
45         res = read(fd, buf, len);
46         if (res < len) {
47                 ast_log(LOG_WARNING, "Only read %d of %d bytes: %s\n", res, len, strerror(errno));
48         }
49         memset(&fr, 0, sizeof(fr));
50         fr.frametype = AST_FRAME_IMAGE;
51         fr.subclass.codec = AST_FORMAT_JPEG;
52         fr.data.ptr = buf;
53         fr.src = "JPEG Read";
54         fr.datalen = len;
55         return ast_frisolate(&fr);
56 }
57
58 static int jpeg_identify(int fd)
59 {
60         char buf[10];
61         int res;
62         res = read(fd, buf, sizeof(buf));
63         if (res < sizeof(buf))
64                 return 0;
65         if (memcmp(buf + 6, "JFIF", 4))
66                 return 0;
67         return 1;
68 }
69
70 static int jpeg_write_image(int fd, struct ast_frame *fr)
71 {
72         int res=0;
73         if (fr->frametype != AST_FRAME_IMAGE) {
74                 ast_log(LOG_WARNING, "Not an image\n");
75                 return -1;
76         }
77         if (fr->subclass.codec != AST_FORMAT_JPEG) {
78                 ast_log(LOG_WARNING, "Not a jpeg image\n");
79                 return -1;
80         }
81         if (fr->datalen) {
82                 res = write(fd, fr->data.ptr, fr->datalen);
83                 if (res != fr->datalen) {
84                         ast_log(LOG_WARNING, "Only wrote %d of %d bytes: %s\n", res, fr->datalen, strerror(errno));
85                         return -1;
86                 }
87         }
88         return res;
89 }
90
91 static struct ast_imager jpeg_format = {
92         .name = "jpg",
93         .desc = "JPEG (Joint Picture Experts Group)",
94         .exts = "jpg|jpeg",
95         .format = AST_FORMAT_JPEG,
96         .read_image = jpeg_read_image,
97         .identify = jpeg_identify,
98         .write_image = jpeg_write_image,
99 };
100
101 static int load_module(void)
102 {
103         if (ast_image_register(&jpeg_format))
104                 return AST_MODULE_LOAD_FAILURE;
105         return AST_MODULE_LOAD_SUCCESS;
106 }
107
108 static int unload_module(void)
109 {
110         ast_image_unregister(&jpeg_format);
111
112         return 0;
113 }
114
115 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "jpeg (joint picture experts group) image format");