1 /* fswebcam - FireStorm.cx's webcam generator */
2 /*===========================================================*/
3 /* Copyright (C)2005-2006 Philip Heron <phil@firestorm.cx> */
5 /* This program is distributed under the terms of the GNU */
6 /* General Public License, version 2. You may use, modify, */
7 /* and redistribute it under the terms of this license. A */
8 /* copy should be included with this source. */
31 int src_file_open_jpeg(src_t
*src
)
33 src_file_t
*s
= (src_file_t
*) src
->state
;
36 src
->palette
= SRC_PAL_JPEG
;
38 /* Scan the JPEG segments for the SOF, which contains
39 * the width and height of the image. */
43 while(p
- s
->start
< src
->length
- 3)
48 /* Check for the segment marker. */
51 ERROR("Segment marker not found,");
56 length
= (p
[0] << 8) + p
[1];
58 /* Verify the full segment is present. */
59 if((p
- s
->start
) + length
>= s
->length
)
61 ERROR("Incomplete segment.");
65 if(header
== 0xC0) /* SOF */
67 uint16_t width
= (p
[5] << 8) + p
[6];
68 uint16_t height
= (p
[3] << 8) + p
[4];
70 if(src
->width
!= width
||
71 src
->height
!= height
)
73 MSG("Adjusting resolution to %ix%i.",
83 if(header
== 0xD9 || /* EOI */
84 header
== 0xDA) /* SOS */
86 WARN("%s: Unable to read resolution.", src
->source
);
96 int src_file_open_png(src_t
*src
)
98 src_file_t
*s
= (src_file_t
*) src
->state
;
99 uint32_t width
, height
;
102 src
->palette
= SRC_PAL_PNG
;
106 ERROR("%s: Unexpected end of file.", src
->source
);
112 if(strncmp((char *) p
, "IHDR", 4))
114 ERROR("%s: IHDR chunk must be first.", src
->source
);
120 width
= (p
[0] << 24) + (p
[1] << 16) + (p
[2] << 8) + p
[3];
121 height
= (p
[4] << 24) + (p
[5] << 16) + (p
[6] << 8) + p
[7];
123 if(src
->width
!= width
||
124 src
->height
!= height
)
126 MSG("Adjusting resolution to %ix%i.",
130 src
->height
= height
;
136 int src_file_open(src_t
*src
)
142 s
= calloc(sizeof(src_file_t
), 1);
145 ERROR("Out of memory.");
149 src
->state
= (void *) s
;
151 /* Get the file's size in bytes. */
152 if(stat(src
->source
, &st
) == -1)
154 ERROR("Error accessing file %s", src
->source
);
155 ERROR("stat: %s", strerror(errno
));
160 s
->f
= fopen(src
->source
, "rb");
163 ERROR("Error opening file %s", src
->source
);
164 ERROR("fopen: %s", strerror(errno
));
169 /* Allocate memory for the file. */
170 s
->length
= st
.st_size
;
171 s
->start
= (uint8_t *) malloc(s
->length
);
174 ERROR("Out of memory.");
180 /* Read the entire file into memory. */
182 while(!feof(s
->f
) && size
< s
->length
)
183 size
+= fread(s
->start
, 1, s
->length
, s
->f
);
188 if(size
!= s
->length
)
190 ERROR("Error reading file. Read %i bytes of %i byte file.",
197 src
->length
= s
->length
;
200 /* Test for a JPEG file. */
201 if(s
->start
[0] == 0xFF && s
->start
[1] == 0xD8)
203 MSG("%s: Loading JPEG file.", src
->source
);
205 if(src_file_open_jpeg(src
))
214 /* Test for a PNG file. */
215 if(s
->start
[0] == 0x89 && s
->start
[1] == 0x50 &&
216 s
->start
[2] == 0x4e && s
->start
[3] == 0x47)
218 MSG("%s: Loading PNG file.", src
->source
);
220 if(src_file_open_png(src
))
229 ERROR("%s: Unknown file format.", src
->source
);
235 int src_file_close(src_t
*src
)
237 src_file_t
*s
= (src_file_t
*) src
->state
;
239 if(s
->f
) fclose(s
->f
);
246 int src_file_grab(src_t
*src
)
251 src_mod_t src_file
= {
252 "file", SRC_TYPE_FILE
,