mirror of
https://github.com/Motion-Project/motion.git
synced 2026-05-19 12:05:54 -04:00
More code standard
This commit is contained in:
1120
netcam_ftp.c
1120
netcam_ftp.c
File diff suppressed because it is too large
Load Diff
344
netcam_wget.c
344
netcam_wget.c
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Copyright (C) 1995, 1996, 1997, 1998, 2000, 2001, 2002
|
||||
Free Software Foundation, Inc.
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
Additional Copyright (C) 2004-2005 Christopher Price,
|
||||
Angel Carpintero, and other contributing authors.
|
||||
@@ -38,14 +38,14 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
definition is not HTTP-specific -- it is virtually
|
||||
indistinguishable from the one given in RFC822 or RFC1036.
|
||||
|
||||
message-header = field-name ":" [ field-value ] CRLF
|
||||
message-header = field-name ":" [ field-value ] CRLF
|
||||
|
||||
field-name = token
|
||||
field-value = *( field-content | LWS )
|
||||
field-name = token
|
||||
field-value = *( field-content | LWS )
|
||||
|
||||
field-content = <the OCTETs making up the field-value
|
||||
and consisting of either *TEXT or combinations
|
||||
of token, tspecials, and quoted-string>
|
||||
field-content = <the OCTETs making up the field-value
|
||||
and consisting of either *TEXT or combinations
|
||||
of token, tspecials, and quoted-string>
|
||||
|
||||
The public functions are header_get() and header_process(), which
|
||||
see. */
|
||||
@@ -67,84 +67,80 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
int header_get(netcam_context_ptr netcam, char **hdr, enum header_get_flags flags)
|
||||
{
|
||||
int i;
|
||||
int bufsize = 80;
|
||||
int i;
|
||||
int bufsize = 80;
|
||||
|
||||
*hdr = (char *)mymalloc(bufsize);
|
||||
for (i = 0; 1; i++) {
|
||||
int res;
|
||||
/* #### Use DO_REALLOC? */
|
||||
if (i > bufsize - 1)
|
||||
*hdr = (char *)myrealloc(*hdr, (bufsize <<= 1), "");
|
||||
*hdr = (char *)mymalloc(bufsize);
|
||||
for (i = 0; 1; i++) {
|
||||
int res;
|
||||
/* #### Use DO_REALLOC? */
|
||||
if (i > bufsize - 1)
|
||||
*hdr = (char *)myrealloc(*hdr, (bufsize <<= 1), "");
|
||||
|
||||
res = RBUF_READCHAR (netcam, *hdr + i);
|
||||
res = RBUF_READCHAR (netcam, *hdr + i);
|
||||
|
||||
if (res == 1) {
|
||||
if ((*hdr)[i] == '\n') {
|
||||
if (!((flags & HG_NO_CONTINUATIONS) || i == 0
|
||||
|| (i == 1 && (*hdr)[0] == '\r'))) {
|
||||
char next;
|
||||
/* If the header is non-empty, we need to check if
|
||||
it continues on to the other line. We do that by
|
||||
peeking at the next character. */
|
||||
res = rbuf_peek(netcam, &next);
|
||||
if (res == 1) {
|
||||
if ((*hdr)[i] == '\n') {
|
||||
if (!((flags & HG_NO_CONTINUATIONS) || i == 0
|
||||
|| (i == 1 && (*hdr)[0] == '\r'))) {
|
||||
char next;
|
||||
/* If the header is non-empty, we need to check if
|
||||
it continues on to the other line. We do that by
|
||||
peeking at the next character. */
|
||||
res = rbuf_peek(netcam, &next);
|
||||
|
||||
if (res == 0)
|
||||
{
|
||||
(*hdr)[i] = '\0';
|
||||
return HG_EOF;
|
||||
}
|
||||
else if (res == -1)
|
||||
{
|
||||
(*hdr)[i] = '\0';
|
||||
return HG_ERROR;
|
||||
}
|
||||
/* If the next character is HT or SP, just continue. */
|
||||
if (res == 0) {
|
||||
(*hdr)[i] = '\0';
|
||||
return HG_EOF;
|
||||
} else if (res == -1) {
|
||||
(*hdr)[i] = '\0';
|
||||
return HG_ERROR;
|
||||
}
|
||||
/* If the next character is HT or SP, just continue. */
|
||||
|
||||
if (next == '\t' || next == ' ')
|
||||
continue;
|
||||
}
|
||||
if (next == '\t' || next == ' ')
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Strip trailing whitespace. (*hdr)[i] is the newline;
|
||||
decrement I until it points to the last available
|
||||
whitespace. */
|
||||
while (i > 0 && isspace((*hdr)[i - 1]))
|
||||
--i;
|
||||
|
||||
(*hdr)[i] = '\0';
|
||||
break;
|
||||
}
|
||||
} else if (res == 0)
|
||||
{
|
||||
(*hdr)[i] = '\0';
|
||||
return HG_EOF;
|
||||
}
|
||||
else
|
||||
{
|
||||
(*hdr)[i] = '\0';
|
||||
return HG_ERROR;
|
||||
}
|
||||
}
|
||||
/* Strip trailing whitespace. (*hdr)[i] is the newline;
|
||||
decrement I until it points to the last available
|
||||
whitespace. */
|
||||
while (i > 0 && isspace((*hdr)[i - 1]))
|
||||
--i;
|
||||
|
||||
(*hdr)[i] = '\0';
|
||||
break;
|
||||
}
|
||||
|
||||
return HG_OK;
|
||||
} else if (res == 0) {
|
||||
|
||||
(*hdr)[i] = '\0';
|
||||
return HG_EOF;
|
||||
} else {
|
||||
(*hdr)[i] = '\0';
|
||||
return HG_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return HG_OK;
|
||||
}
|
||||
|
||||
/* Check whether HEADER begins with NAME and, if yes, skip the `:' and
|
||||
the whitespace, and call PROCFUN with the arguments of HEADER's
|
||||
contents (after the `:' and space) and ARG. Otherwise, return 0. */
|
||||
int header_process (const char *header, const char *name,
|
||||
int (*procfun)(const char *, void *),
|
||||
void *arg)
|
||||
int (*procfun)(const char *, void *),
|
||||
void *arg)
|
||||
{
|
||||
/* Check whether HEADER matches NAME. */
|
||||
while (*name && (tolower (*name) == tolower (*header)))
|
||||
++name, ++header;
|
||||
/* Check whether HEADER matches NAME. */
|
||||
while (*name && (tolower (*name) == tolower (*header)))
|
||||
++name, ++header;
|
||||
|
||||
if (*name || *header++ != ':')
|
||||
return 0;
|
||||
|
||||
header += skip_lws (header);
|
||||
return ((*procfun) (header, arg));
|
||||
if (*name || *header++ != ':')
|
||||
return 0;
|
||||
|
||||
header += skip_lws (header);
|
||||
return ((*procfun) (header, arg));
|
||||
}
|
||||
|
||||
/* Helper functions for use with header_process(). */
|
||||
@@ -153,34 +149,34 @@ int header_process (const char *header, const char *name,
|
||||
error is encountered, return 0, else 1. */
|
||||
int header_extract_number(const char *header, void *closure)
|
||||
{
|
||||
const char *p = header;
|
||||
long result;
|
||||
const char *p = header;
|
||||
long result;
|
||||
|
||||
for (result = 0; isdigit (*p); p++)
|
||||
result = 10 * result + (*p - '0');
|
||||
for (result = 0; isdigit (*p); p++)
|
||||
result = 10 * result + (*p - '0');
|
||||
|
||||
/* Failure if no number present. */
|
||||
if (p == header)
|
||||
return 0;
|
||||
/* Failure if no number present. */
|
||||
if (p == header)
|
||||
return 0;
|
||||
|
||||
/* Skip trailing whitespace. */
|
||||
p += skip_lws (p);
|
||||
/* Skip trailing whitespace. */
|
||||
p += skip_lws (p);
|
||||
|
||||
/* We return the value, even if a format error follows */
|
||||
*(long *)closure = result;
|
||||
/* We return the value, even if a format error follows */
|
||||
*(long *)closure = result;
|
||||
|
||||
/* Indicate failure if trailing garbage is present. */
|
||||
if (*p)
|
||||
return 0;
|
||||
/* Indicate failure if trailing garbage is present. */
|
||||
if (*p)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Strdup HEADER, and place the pointer to CLOSURE. */
|
||||
int header_strdup(const char *header, void *closure)
|
||||
{
|
||||
*(char **)closure = strdup(header);
|
||||
return 1;
|
||||
*(char **)closure = strdup(header);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -188,148 +184,148 @@ int header_strdup(const char *header, void *closure)
|
||||
characters to skip. */
|
||||
int skip_lws(const char *string)
|
||||
{
|
||||
const char *p = string;
|
||||
const char *p = string;
|
||||
|
||||
while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n')
|
||||
++p;
|
||||
while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n')
|
||||
++p;
|
||||
|
||||
return p - string;
|
||||
return p - string;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Encode the string S of length LENGTH to base64 format and place it
|
||||
to STORE. STORE will be 0-terminated, and must point to a writable
|
||||
buffer of at least 1+BASE64_LENGTH(length) bytes.
|
||||
Encode the string S of length LENGTH to base64 format and place it
|
||||
to STORE. STORE will be 0-terminated, and must point to a writable
|
||||
buffer of at least 1+BASE64_LENGTH(length) bytes.
|
||||
*/
|
||||
void base64_encode(const char *s, char *store, int length)
|
||||
{
|
||||
/* Conversion table. */
|
||||
static const char tbl[64] = {
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
|
||||
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
||||
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
|
||||
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
|
||||
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
|
||||
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
|
||||
'w', 'x', 'y', 'z', '0', '1', '2', '3',
|
||||
'4', '5', '6', '7', '8', '9', '+', '/'
|
||||
};
|
||||
|
||||
int i;
|
||||
unsigned char *p = (unsigned char *)store;
|
||||
/* Conversion table. */
|
||||
static const char tbl[64] = {
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
|
||||
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
||||
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
|
||||
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
|
||||
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
|
||||
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
|
||||
'w', 'x', 'y', 'z', '0', '1', '2', '3',
|
||||
'4', '5', '6', '7', '8', '9', '+', '/'
|
||||
};
|
||||
|
||||
int i;
|
||||
unsigned char *p = (unsigned char *)store;
|
||||
|
||||
/* Transform the 3x8 bits to 4x6 bits, as required by base64. */
|
||||
for (i = 0; i < length; i += 3) {
|
||||
*p++ = tbl[s[0] >> 2];
|
||||
*p++ = tbl[((s[0] & 3) << 4) + (s[1] >> 4)];
|
||||
*p++ = tbl[((s[1] & 0xf) << 2) + (s[2] >> 6)];
|
||||
*p++ = tbl[s[2] & 0x3f];
|
||||
s += 3;
|
||||
}
|
||||
|
||||
/* Pad the result if necessary... */
|
||||
if (i == length + 1)
|
||||
*(p - 1) = '=';
|
||||
else if (i == length + 2)
|
||||
*(p - 1) = *(p - 2) = '=';
|
||||
/* Transform the 3x8 bits to 4x6 bits, as required by base64. */
|
||||
for (i = 0; i < length; i += 3) {
|
||||
*p++ = tbl[s[0] >> 2];
|
||||
*p++ = tbl[((s[0] & 3) << 4) + (s[1] >> 4)];
|
||||
*p++ = tbl[((s[1] & 0xf) << 2) + (s[2] >> 6)];
|
||||
*p++ = tbl[s[2] & 0x3f];
|
||||
s += 3;
|
||||
}
|
||||
|
||||
/* Pad the result if necessary... */
|
||||
if (i == length + 1)
|
||||
*(p - 1) = '=';
|
||||
else if (i == length + 2)
|
||||
*(p - 1) = *(p - 2) = '=';
|
||||
|
||||
/* ...and zero-terminate it. */
|
||||
*p = '\0';
|
||||
/* ...and zero-terminate it. */
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
char *strdupdelim(const char *beg, const char *end)
|
||||
{
|
||||
char *res = (char *)mymalloc(end - beg + 1);
|
||||
memcpy (res, beg, end - beg);
|
||||
char *res = (char *)mymalloc(end - beg + 1);
|
||||
memcpy (res, beg, end - beg);
|
||||
|
||||
res[end - beg] = '\0';
|
||||
return res;
|
||||
res[end - beg] = '\0';
|
||||
return res;
|
||||
}
|
||||
|
||||
int http_process_type(const char *hdr, void *arg)
|
||||
{
|
||||
char **result = (char **)arg;
|
||||
/* Locate P on `;' or the terminating zero, whichever comes first. */
|
||||
const char *p = strchr (hdr, ';');
|
||||
char **result = (char **)arg;
|
||||
/* Locate P on `;' or the terminating zero, whichever comes first. */
|
||||
const char *p = strchr (hdr, ';');
|
||||
|
||||
if (!p)
|
||||
p = hdr + strlen (hdr);
|
||||
if (!p)
|
||||
p = hdr + strlen (hdr);
|
||||
|
||||
while (p > hdr && isspace (*(p - 1)))
|
||||
--p;
|
||||
while (p > hdr && isspace (*(p - 1)))
|
||||
--p;
|
||||
|
||||
*result = strdupdelim (hdr, p);
|
||||
return 1;
|
||||
*result = strdupdelim (hdr, p);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* This is a simple implementation of buffering IO-read functions. */
|
||||
|
||||
void rbuf_initialize(netcam_context_ptr netcam)
|
||||
{
|
||||
netcam->response->buffer_pos = netcam->response->buffer;
|
||||
netcam->response->buffer_left = 0;
|
||||
netcam->response->buffer_pos = netcam->response->buffer;
|
||||
netcam->response->buffer_left = 0;
|
||||
}
|
||||
|
||||
int rbuf_read_bufferful(netcam_context_ptr netcam)
|
||||
{
|
||||
return netcam_recv(netcam, netcam->response->buffer,
|
||||
sizeof (netcam->response->buffer));
|
||||
return netcam_recv(netcam, netcam->response->buffer,
|
||||
sizeof (netcam->response->buffer));
|
||||
}
|
||||
|
||||
/* Like rbuf_readchar(), only don't move the buffer position. */
|
||||
int rbuf_peek(netcam_context_ptr netcam, char *store)
|
||||
{
|
||||
if (!netcam->response->buffer_left) {
|
||||
int res;
|
||||
rbuf_initialize(netcam);
|
||||
res = netcam_recv (netcam, netcam->response->buffer,
|
||||
sizeof (netcam->response->buffer));
|
||||
if (!netcam->response->buffer_left) {
|
||||
int res;
|
||||
rbuf_initialize(netcam);
|
||||
res = netcam_recv (netcam, netcam->response->buffer,
|
||||
sizeof (netcam->response->buffer));
|
||||
|
||||
if (res <= 0)
|
||||
return res;
|
||||
if (res <= 0)
|
||||
return res;
|
||||
|
||||
netcam->response->buffer_left = res;
|
||||
}
|
||||
|
||||
*store = *netcam->response->buffer_pos;
|
||||
return 1;
|
||||
netcam->response->buffer_left = res;
|
||||
}
|
||||
|
||||
*store = *netcam->response->buffer_pos;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
Flush RBUF's buffer to WHERE. Flush MAXSIZE bytes at most.
|
||||
Returns the number of bytes actually copied. If the buffer is
|
||||
empty, 0 is returned.
|
||||
Flush RBUF's buffer to WHERE. Flush MAXSIZE bytes at most.
|
||||
Returns the number of bytes actually copied. If the buffer is
|
||||
empty, 0 is returned.
|
||||
*/
|
||||
int rbuf_flush(netcam_context_ptr netcam, char *where, int maxsize)
|
||||
{
|
||||
if (!netcam->response->buffer_left)
|
||||
return 0;
|
||||
else {
|
||||
int howmuch = MINVAL ((int)netcam->response->buffer_left, maxsize);
|
||||
if (!netcam->response->buffer_left) {
|
||||
return 0;
|
||||
} else {
|
||||
int howmuch = MINVAL ((int)netcam->response->buffer_left, maxsize);
|
||||
|
||||
if (where)
|
||||
memcpy(where, netcam->response->buffer_pos, howmuch);
|
||||
if (where)
|
||||
memcpy(where, netcam->response->buffer_pos, howmuch);
|
||||
|
||||
netcam->response->buffer_left -= howmuch;
|
||||
netcam->response->buffer_pos += howmuch;
|
||||
return howmuch;
|
||||
}
|
||||
netcam->response->buffer_left -= howmuch;
|
||||
netcam->response->buffer_pos += howmuch;
|
||||
return howmuch;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the HTTP result code */
|
||||
int http_result_code(const char *header)
|
||||
{
|
||||
char *cptr;
|
||||
char *cptr;
|
||||
|
||||
/* assure the header starts out right */
|
||||
if (strncmp(header, "HTTP", 4))
|
||||
return -1;
|
||||
/* assure the header starts out right */
|
||||
if (strncmp(header, "HTTP", 4))
|
||||
return -1;
|
||||
|
||||
/* find the space following the HTTP/1.x */
|
||||
if ((cptr = strchr(header+4, ' ')) == NULL)
|
||||
return -1;
|
||||
/* find the space following the HTTP/1.x */
|
||||
if ((cptr = strchr(header+4, ' ')) == NULL)
|
||||
return -1;
|
||||
|
||||
return atoi(cptr + 1);
|
||||
return atoi(cptr + 1);
|
||||
}
|
||||
|
||||
|
||||
475
rotate.c
475
rotate.c
@@ -1,33 +1,33 @@
|
||||
/*
|
||||
* rotate.c
|
||||
* rotate.c
|
||||
*
|
||||
* Module for handling image rotation.
|
||||
* Module for handling image rotation.
|
||||
*
|
||||
* Copyright 2004-2005, Per Jonsson (per@pjd.nu)
|
||||
*
|
||||
* This software is distributed under the GNU Public license
|
||||
* Version 2. See also the file 'COPYING'.
|
||||
* Copyright 2004-2005, Per Jonsson (per@pjd.nu)
|
||||
*
|
||||
* This software is distributed under the GNU Public license
|
||||
* Version 2. See also the file 'COPYING'.
|
||||
*
|
||||
* Image rotation is a feature of Motion that can be used when the
|
||||
* camera is mounted upside-down or on the side. The module only
|
||||
* supports rotation in multiples of 90 degrees. Using rotation
|
||||
* increases the Motion CPU usage slightly.
|
||||
* Image rotation is a feature of Motion that can be used when the
|
||||
* camera is mounted upside-down or on the side. The module only
|
||||
* supports rotation in multiples of 90 degrees. Using rotation
|
||||
* increases the Motion CPU usage slightly.
|
||||
*
|
||||
* Version history:
|
||||
* v6 (29-Aug-2005) - simplified the code as Motion now requires
|
||||
* that width and height are multiples of 16
|
||||
* v5 (3-Aug-2005) - cleanup in code comments
|
||||
* - better adherence to coding standard
|
||||
* - fix for __bswap_32 macro collision
|
||||
* - fixed bug where initialization would be
|
||||
* incomplete for invalid degrees of rotation
|
||||
* - now uses motion_log for error reporting
|
||||
* v4 (26-Oct-2004) - new fix for width/height from imgs/conf due to
|
||||
* earlier misinterpretation
|
||||
* v3 (11-Oct-2004) - cleanup of width/height from imgs/conf
|
||||
* v2 (26-Sep-2004) - separation of capture/internal dimensions
|
||||
* - speed optimization, including bswap
|
||||
* v1 (28-Aug-2004) - initial version
|
||||
* Version history:
|
||||
* v6 (29-Aug-2005) - simplified the code as Motion now requires
|
||||
* that width and height are multiples of 16
|
||||
* v5 (3-Aug-2005) - cleanup in code comments
|
||||
* - better adherence to coding standard
|
||||
* - fix for __bswap_32 macro collision
|
||||
* - fixed bug where initialization would be
|
||||
* incomplete for invalid degrees of rotation
|
||||
* - now uses motion_log for error reporting
|
||||
* v4 (26-Oct-2004) - new fix for width/height from imgs/conf due to
|
||||
* earlier misinterpretation
|
||||
* v3 (11-Oct-2004) - cleanup of width/height from imgs/conf
|
||||
* v2 (26-Sep-2004) - separation of capture/internal dimensions
|
||||
* - speed optimization, including bswap
|
||||
* v1 (28-Aug-2004) - initial version
|
||||
*/
|
||||
#include "rotate.h"
|
||||
|
||||
@@ -36,11 +36,11 @@
|
||||
* We don't have a 32-bit unsigned integer type, so define it, given
|
||||
* a 32-bit type was found by configure.
|
||||
*/
|
||||
# ifdef TYPE_32BIT
|
||||
# ifdef TYPE_32BIT
|
||||
typedef unsigned TYPE_32BIT __uint32;
|
||||
# else
|
||||
# error "Failed to find a 32-bit integer type."
|
||||
# endif
|
||||
# else
|
||||
# error "Failed to find a 32-bit integer type."
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*=============================================================================
|
||||
@@ -65,52 +65,52 @@ typedef unsigned TYPE_32BIT __uint32;
|
||||
*/
|
||||
|
||||
/* Swap bytes in 32 bit value. This is used as a fallback and for constants. */
|
||||
#define rot__bswap_constant_32(x) \
|
||||
((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
|
||||
(((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
|
||||
#define rot__bswap_constant_32(x) \
|
||||
((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
|
||||
(((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
|
||||
|
||||
#ifdef __GNUC__
|
||||
# if (__GNUC__ >= 2) && (i386 || __i386 || __i386__)
|
||||
# if (__GNUC__ >= 2) && (i386 || __i386 || __i386__)
|
||||
/* We're on an Intel-compatible platform, so we can use inline Intel assembler
|
||||
* for the swapping.
|
||||
*/
|
||||
# ifndef HAVE_BSWAP
|
||||
# ifndef HAVE_BSWAP
|
||||
/* Bswap is not available, we have to use three instructions instead. */
|
||||
# define rot__bswap_32(x) \
|
||||
(__extension__ \
|
||||
({ register __uint32 __v, __x = (x); \
|
||||
if (__builtin_constant_p (__x)) \
|
||||
__v = rot__bswap_constant_32 (__x); \
|
||||
else \
|
||||
__asm__ ("rorw $8, %w0;" \
|
||||
"rorl $16, %0;" \
|
||||
"rorw $8, %w0" \
|
||||
: "=r" (__v) \
|
||||
: "0" (__x) \
|
||||
: "cc"); \
|
||||
__v; }))
|
||||
# else
|
||||
# define rot__bswap_32(x) \
|
||||
(__extension__ \
|
||||
({ register __uint32 __v, __x = (x); \
|
||||
if (__builtin_constant_p (__x)) \
|
||||
__v = rot__bswap_constant_32 (__x); \
|
||||
else \
|
||||
__asm__ ("bswap %0" : "=r" (__v) : "0" (__x)); \
|
||||
__v; }))
|
||||
# endif
|
||||
# else
|
||||
# define rot__bswap_32(x) \
|
||||
(__extension__ \
|
||||
({ register __uint32 __v, __x = (x); \
|
||||
if (__builtin_constant_p (__x)) \
|
||||
__v = rot__bswap_constant_32 (__x); \
|
||||
else \
|
||||
__asm__ ("rorw $8, %w0;" \
|
||||
"rorl $16, %0;" \
|
||||
"rorw $8, %w0" \
|
||||
: "=r" (__v) \
|
||||
: "0" (__x) \
|
||||
: "cc"); \
|
||||
__v; }))
|
||||
# else
|
||||
# define rot__bswap_32(x) \
|
||||
(__extension__ \
|
||||
({ register __uint32 __v, __x = (x); \
|
||||
if (__builtin_constant_p (__x)) \
|
||||
__v = rot__bswap_constant_32 (__x); \
|
||||
else \
|
||||
__asm__ ("bswap %0" : "=r" (__v) : "0" (__x)); \
|
||||
__v; }))
|
||||
# endif
|
||||
# else
|
||||
/* Non-Intel platform or too old version of gcc. */
|
||||
# define rot__bswap_32(x) \
|
||||
(__extension__ \
|
||||
({ register __uint32 __x = (x); \
|
||||
rot__bswap_constant_32 (__x); }))
|
||||
# endif
|
||||
# define rot__bswap_32(x) \
|
||||
(__extension__ \
|
||||
({ register __uint32 __x = (x); \
|
||||
rot__bswap_constant_32 (__x); }))
|
||||
# endif
|
||||
#else
|
||||
/* Not a GNU compiler. */
|
||||
static inline __uint32 rot__bswap_32(__uint32 __bsx)
|
||||
{
|
||||
return __bswap_constant_32 (__bsx);
|
||||
return __bswap_constant_32 (__bsx);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -136,15 +136,15 @@ static inline __uint32 rot__bswap_32(__uint32 __bsx)
|
||||
*/
|
||||
static void reverse_inplace_quad(unsigned char *src, int size)
|
||||
{
|
||||
__uint32 *nsrc = (__uint32 *)src; /* first quad */
|
||||
__uint32 *ndst = (__uint32 *)(src + size - 4); /* last quad */
|
||||
register __uint32 tmp;
|
||||
__uint32 *nsrc = (__uint32 *)src; /* first quad */
|
||||
__uint32 *ndst = (__uint32 *)(src + size - 4); /* last quad */
|
||||
register __uint32 tmp;
|
||||
|
||||
while (nsrc < ndst) {
|
||||
tmp = swap_bytes(*ndst);
|
||||
*ndst-- = swap_bytes(*nsrc);
|
||||
*nsrc++ = tmp;
|
||||
}
|
||||
while (nsrc < ndst) {
|
||||
tmp = swap_bytes(*ndst);
|
||||
*ndst-- = swap_bytes(*nsrc);
|
||||
*nsrc++ = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -167,17 +167,17 @@ static void reverse_inplace_quad(unsigned char *src, int size)
|
||||
static void rot90cw(unsigned char *src, register unsigned char *dst, int size,
|
||||
int width, int height)
|
||||
{
|
||||
unsigned char *endp;
|
||||
register unsigned char *base;
|
||||
int j;
|
||||
unsigned char *endp;
|
||||
register unsigned char *base;
|
||||
int j;
|
||||
|
||||
endp = src + size;
|
||||
for (base = endp - width; base < endp; base++) {
|
||||
src = base;
|
||||
for (j = 0; j < height; j++, src -= width) {
|
||||
*dst++ = *src;
|
||||
}
|
||||
}
|
||||
endp = src + size;
|
||||
for (base = endp - width; base < endp; base++) {
|
||||
src = base;
|
||||
for (j = 0; j < height; j++, src -= width)
|
||||
*dst++ = *src;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -200,18 +200,18 @@ static void rot90cw(unsigned char *src, register unsigned char *dst, int size,
|
||||
static inline void rot90ccw(unsigned char *src, register unsigned char *dst,
|
||||
int size, int width, int height)
|
||||
{
|
||||
unsigned char *endp;
|
||||
register unsigned char *base;
|
||||
int j;
|
||||
unsigned char *endp;
|
||||
register unsigned char *base;
|
||||
int j;
|
||||
|
||||
endp = src + size;
|
||||
dst = dst + size - 1;
|
||||
for(base = endp - width; base < endp; base++) {
|
||||
src = base;
|
||||
for(j = 0; j < height; j++, src -= width) {
|
||||
*dst-- = *src;
|
||||
}
|
||||
}
|
||||
endp = src + size;
|
||||
dst = dst + size - 1;
|
||||
for(base = endp - width; base < endp; base++) {
|
||||
src = base;
|
||||
for(j = 0; j < height; j++, src -= width)
|
||||
*dst-- = *src;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -228,77 +228,77 @@ static inline void rot90ccw(unsigned char *src, register unsigned char *dst,
|
||||
*/
|
||||
void rotate_init(struct context *cnt)
|
||||
{
|
||||
int size;
|
||||
|
||||
/* Make sure temp_buf isn't freed if it hasn't been allocated. */
|
||||
cnt->rotate_data.temp_buf = NULL;
|
||||
int size;
|
||||
|
||||
/* Make sure temp_buf isn't freed if it hasn't been allocated. */
|
||||
cnt->rotate_data.temp_buf = NULL;
|
||||
|
||||
/* Assign the value in conf.rotate_deg to rotate_data.degrees. This way,
|
||||
* we have a value that is safe from changes caused by motion-control.
|
||||
*/
|
||||
if((cnt->conf.rotate_deg % 90) > 0) {
|
||||
motion_log(LOG_ERR, 0, "Config option \"rotate\" not a multiple of 90: %d",
|
||||
cnt->conf.rotate_deg);
|
||||
cnt->conf.rotate_deg = 0; /* disable rotation */
|
||||
cnt->rotate_data.degrees = 0; /* force return below */
|
||||
} else {
|
||||
cnt->rotate_data.degrees = cnt->conf.rotate_deg % 360; /* range: 0..359 */
|
||||
}
|
||||
/* Assign the value in conf.rotate_deg to rotate_data.degrees. This way,
|
||||
* we have a value that is safe from changes caused by motion-control.
|
||||
*/
|
||||
if ((cnt->conf.rotate_deg % 90) > 0) {
|
||||
motion_log(LOG_ERR, 0, "Config option \"rotate\" not a multiple of 90: %d",
|
||||
cnt->conf.rotate_deg);
|
||||
cnt->conf.rotate_deg = 0; /* disable rotation */
|
||||
cnt->rotate_data.degrees = 0; /* force return below */
|
||||
} else {
|
||||
cnt->rotate_data.degrees = cnt->conf.rotate_deg % 360; /* range: 0..359 */
|
||||
}
|
||||
|
||||
/* Upon entrance to this function, imgs.width and imgs.height contain the
|
||||
* capture dimensions (as set in the configuration file, or read from a
|
||||
* netcam source).
|
||||
*
|
||||
* If rotating 90 or 270 degrees, the capture dimensions and output dimensions
|
||||
* are not the same. Capture dimensions will be contained in cap_width and
|
||||
* cap_height in cnt->rotate_data, while output dimensions will be contained
|
||||
* in imgs.width and imgs.height.
|
||||
*/
|
||||
/* Upon entrance to this function, imgs.width and imgs.height contain the
|
||||
* capture dimensions (as set in the configuration file, or read from a
|
||||
* netcam source).
|
||||
*
|
||||
* If rotating 90 or 270 degrees, the capture dimensions and output dimensions
|
||||
* are not the same. Capture dimensions will be contained in cap_width and
|
||||
* cap_height in cnt->rotate_data, while output dimensions will be contained
|
||||
* in imgs.width and imgs.height.
|
||||
*/
|
||||
|
||||
/* 1. Transfer capture dimensions into cap_width and cap_height. */
|
||||
cnt->rotate_data.cap_width = cnt->imgs.width;
|
||||
cnt->rotate_data.cap_height = cnt->imgs.height;
|
||||
/* 1. Transfer capture dimensions into cap_width and cap_height. */
|
||||
cnt->rotate_data.cap_width = cnt->imgs.width;
|
||||
cnt->rotate_data.cap_height = cnt->imgs.height;
|
||||
|
||||
if((cnt->rotate_data.degrees == 90) || (cnt->rotate_data.degrees == 270)) {
|
||||
/* 2. "Swap" imgs.width and imgs.height. */
|
||||
cnt->imgs.width = cnt->rotate_data.cap_height;
|
||||
cnt->imgs.height = cnt->rotate_data.cap_width;
|
||||
}
|
||||
if ((cnt->rotate_data.degrees == 90) || (cnt->rotate_data.degrees == 270)) {
|
||||
/* 2. "Swap" imgs.width and imgs.height. */
|
||||
cnt->imgs.width = cnt->rotate_data.cap_height;
|
||||
cnt->imgs.height = cnt->rotate_data.cap_width;
|
||||
}
|
||||
|
||||
/* If we're not rotating, let's exit once we have setup the capture dimensions
|
||||
* and output dimensions properly.
|
||||
*/
|
||||
if(cnt->rotate_data.degrees == 0) {
|
||||
return;
|
||||
}
|
||||
/* If we're not rotating, let's exit once we have setup the capture dimensions
|
||||
* and output dimensions properly.
|
||||
*/
|
||||
if (cnt->rotate_data.degrees == 0)
|
||||
return;
|
||||
|
||||
|
||||
switch(cnt->imgs.type)
|
||||
{
|
||||
case VIDEO_PALETTE_YUV420P:
|
||||
/* For YUV 4:2:0 planar, the memory block used for 90/270 degrees
|
||||
* rotation needs to be width x height x 1.5 bytes large.
|
||||
*/
|
||||
size = cnt->imgs.width * cnt->imgs.height * 3 / 2;
|
||||
break;
|
||||
case VIDEO_PALETTE_GREY:
|
||||
/* For greyscale, the memory block used for 90/270 degrees rotation
|
||||
* needs to be width x height bytes large.
|
||||
*/
|
||||
size = cnt->imgs.width * cnt->imgs.height;
|
||||
break;
|
||||
default:
|
||||
cnt->rotate_data.degrees = 0;
|
||||
motion_log(LOG_ERR, 0, "Unsupported palette (%d), rotation is disabled",
|
||||
cnt->imgs.type);
|
||||
return;
|
||||
}
|
||||
switch(cnt->imgs.type)
|
||||
{
|
||||
case VIDEO_PALETTE_YUV420P:
|
||||
/* For YUV 4:2:0 planar, the memory block used for 90/270 degrees
|
||||
* rotation needs to be width x height x 1.5 bytes large.
|
||||
*/
|
||||
size = cnt->imgs.width * cnt->imgs.height * 3 / 2;
|
||||
break;
|
||||
case VIDEO_PALETTE_GREY:
|
||||
/* For greyscale, the memory block used for 90/270 degrees rotation
|
||||
* needs to be width x height bytes large.
|
||||
*/
|
||||
size = cnt->imgs.width * cnt->imgs.height;
|
||||
break;
|
||||
default:
|
||||
cnt->rotate_data.degrees = 0;
|
||||
motion_log(LOG_ERR, 0, "Unsupported palette (%d), rotation is disabled",
|
||||
cnt->imgs.type);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Allocate memory if rotating 90 or 270 degrees, because those rotations
|
||||
* cannot be performed in-place (they can, but it would be too slow).
|
||||
*/
|
||||
if((cnt->rotate_data.degrees == 90) || (cnt->rotate_data.degrees == 270)) {
|
||||
cnt->rotate_data.temp_buf = mymalloc(size);
|
||||
}
|
||||
/* Allocate memory if rotating 90 or 270 degrees, because those rotations
|
||||
* cannot be performed in-place (they can, but it would be too slow).
|
||||
*/
|
||||
if ((cnt->rotate_data.degrees == 90) || (cnt->rotate_data.degrees == 270))
|
||||
cnt->rotate_data.temp_buf = mymalloc(size);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -314,9 +314,9 @@ void rotate_init(struct context *cnt)
|
||||
*/
|
||||
void rotate_deinit(struct context *cnt)
|
||||
{
|
||||
if(cnt->rotate_data.temp_buf) {
|
||||
free(cnt->rotate_data.temp_buf);
|
||||
}
|
||||
if (cnt->rotate_data.temp_buf)
|
||||
free(cnt->rotate_data.temp_buf);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -337,87 +337,90 @@ void rotate_deinit(struct context *cnt)
|
||||
*/
|
||||
int rotate_map(struct context *cnt, unsigned char *map)
|
||||
{
|
||||
/* The image format is either YUV 4:2:0 planar, in which case the pixel
|
||||
* data is divided in three parts:
|
||||
* Y - width x height bytes
|
||||
* U - width x height / 4 bytes
|
||||
* V - as U
|
||||
* or, it is in greyscale, in which case the pixel data simply consists
|
||||
* of width x height bytes.
|
||||
*/
|
||||
int wh, wh4 = 0, w2 = 0, h2 = 0; /* width*height, width*height/4 etc. */
|
||||
int size, deg;
|
||||
int width, height;
|
||||
/* The image format is either YUV 4:2:0 planar, in which case the pixel
|
||||
* data is divided in three parts:
|
||||
* Y - width x height bytes
|
||||
* U - width x height / 4 bytes
|
||||
* V - as U
|
||||
* or, it is in greyscale, in which case the pixel data simply consists
|
||||
* of width x height bytes.
|
||||
*/
|
||||
int wh, wh4 = 0, w2 = 0, h2 = 0; /* width*height, width*height/4 etc. */
|
||||
int size, deg;
|
||||
int width, height;
|
||||
|
||||
deg = cnt->rotate_data.degrees;
|
||||
width = cnt->rotate_data.cap_width;
|
||||
height = cnt->rotate_data.cap_height;
|
||||
deg = cnt->rotate_data.degrees;
|
||||
width = cnt->rotate_data.cap_width;
|
||||
height = cnt->rotate_data.cap_height;
|
||||
|
||||
/* Pre-calculate some stuff:
|
||||
* wh - size of the Y plane, or the entire greyscale image
|
||||
* size - size of the entire memory block
|
||||
* wh4 - size of the U plane, and the V plane
|
||||
* w2 - width of the U plane, and the V plane
|
||||
* h2 - as w2, but height instead
|
||||
*/
|
||||
wh = width * height;
|
||||
if(cnt->imgs.type == VIDEO_PALETTE_YUV420P) {
|
||||
size = wh * 3 / 2;
|
||||
wh4 = wh / 4;
|
||||
w2 = width / 2;
|
||||
h2 = height / 2;
|
||||
}
|
||||
else { /* VIDEO_PALETTE_GREY */
|
||||
size = wh;
|
||||
}
|
||||
/* Pre-calculate some stuff:
|
||||
* wh - size of the Y plane, or the entire greyscale image
|
||||
* size - size of the entire memory block
|
||||
* wh4 - size of the U plane, and the V plane
|
||||
* w2 - width of the U plane, and the V plane
|
||||
* h2 - as w2, but height instead
|
||||
*/
|
||||
wh = width * height;
|
||||
|
||||
if (cnt->imgs.type == VIDEO_PALETTE_YUV420P) {
|
||||
size = wh * 3 / 2;
|
||||
wh4 = wh / 4;
|
||||
w2 = width / 2;
|
||||
h2 = height / 2;
|
||||
}
|
||||
else { /* VIDEO_PALETTE_GREY */
|
||||
size = wh;
|
||||
}
|
||||
|
||||
switch (deg) {
|
||||
case 90:
|
||||
/* first do the Y part */
|
||||
rot90cw(map, cnt->rotate_data.temp_buf, wh, width, height);
|
||||
if(cnt->imgs.type == VIDEO_PALETTE_YUV420P) {
|
||||
/* then do U and V */
|
||||
rot90cw(map + wh, cnt->rotate_data.temp_buf + wh, wh4, w2, h2);
|
||||
rot90cw(map + wh + wh4, cnt->rotate_data.temp_buf + wh + wh4,
|
||||
wh4, w2, h2);
|
||||
}
|
||||
|
||||
/* then copy back from the temp buffer to map */
|
||||
memcpy(map, cnt->rotate_data.temp_buf, size);
|
||||
switch (deg) {
|
||||
case 90:
|
||||
/* first do the Y part */
|
||||
rot90cw(map, cnt->rotate_data.temp_buf, wh, width, height);
|
||||
|
||||
break;
|
||||
|
||||
case 180:
|
||||
/* 180 degrees is easy - just reverse the data within
|
||||
* Y, U and V.
|
||||
*/
|
||||
reverse_inplace_quad(map, wh);
|
||||
if(cnt->imgs.type == VIDEO_PALETTE_YUV420P) {
|
||||
reverse_inplace_quad(map + wh, wh4);
|
||||
reverse_inplace_quad(map + wh + wh4, wh4);
|
||||
}
|
||||
break;
|
||||
if (cnt->imgs.type == VIDEO_PALETTE_YUV420P) {
|
||||
/* then do U and V */
|
||||
rot90cw(map + wh, cnt->rotate_data.temp_buf + wh, wh4, w2, h2);
|
||||
rot90cw(map + wh + wh4, cnt->rotate_data.temp_buf + wh + wh4,
|
||||
wh4, w2, h2);
|
||||
}
|
||||
|
||||
/* then copy back from the temp buffer to map */
|
||||
memcpy(map, cnt->rotate_data.temp_buf, size);
|
||||
|
||||
case 270:
|
||||
break;
|
||||
|
||||
case 180:
|
||||
/* 180 degrees is easy - just reverse the data within
|
||||
* Y, U and V.
|
||||
*/
|
||||
reverse_inplace_quad(map, wh);
|
||||
|
||||
/* first do the Y part */
|
||||
rot90ccw(map, cnt->rotate_data.temp_buf, wh, width, height);
|
||||
if(cnt->imgs.type == VIDEO_PALETTE_YUV420P) {
|
||||
/* then do U and V */
|
||||
rot90ccw(map + wh, cnt->rotate_data.temp_buf + wh, wh4, w2, h2);
|
||||
rot90ccw(map + wh + wh4, cnt->rotate_data.temp_buf + wh + wh4,
|
||||
wh4, w2, h2);
|
||||
}
|
||||
|
||||
/* then copy back from the temp buffer to map */
|
||||
memcpy(map, cnt->rotate_data.temp_buf, size);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* invalid */
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
if (cnt->imgs.type == VIDEO_PALETTE_YUV420P) {
|
||||
reverse_inplace_quad(map + wh, wh4);
|
||||
reverse_inplace_quad(map + wh + wh4, wh4);
|
||||
}
|
||||
break;
|
||||
|
||||
case 270:
|
||||
/* first do the Y part */
|
||||
rot90ccw(map, cnt->rotate_data.temp_buf, wh, width, height);
|
||||
|
||||
if (cnt->imgs.type == VIDEO_PALETTE_YUV420P) {
|
||||
/* then do U and V */
|
||||
rot90ccw(map + wh, cnt->rotate_data.temp_buf + wh, wh4, w2, h2);
|
||||
rot90ccw(map + wh + wh4, cnt->rotate_data.temp_buf + wh + wh4,
|
||||
wh4, w2, h2);
|
||||
}
|
||||
|
||||
/* then copy back from the temp buffer to map */
|
||||
memcpy(map, cnt->rotate_data.temp_buf, size);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* invalid */
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
1205
video_common.c
1205
video_common.c
File diff suppressed because it is too large
Load Diff
4050
webhttpd.c
4050
webhttpd.c
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user