Bug 263 - Support raw image input.
git-svn-id: http://svn.zoneminder.com/svn/zm/trunk@1846 e3e1d417-86f3-4887-817a-d78f3d33393f
This commit is contained in:
parent
b6f9ed3427
commit
a6fca601a2
|
@ -129,7 +129,8 @@ void RemoteCamera::Initialise()
|
||||||
|
|
||||||
buffer.Size( max_size );
|
buffer.Size( max_size );
|
||||||
|
|
||||||
mode = SINGLE_JPEG;
|
mode = SINGLE_IMAGE;
|
||||||
|
format = UNDEF;
|
||||||
state = HEADER;
|
state = HEADER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,6 +171,7 @@ int RemoteCamera::SendRequest()
|
||||||
Disconnect();
|
Disconnect();
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
format = UNDEF;
|
||||||
state = HEADER;
|
state = HEADER;
|
||||||
Debug( 3, ( "Request sent" ));
|
Debug( 3, ( "Request sent" ));
|
||||||
return( 0 );
|
return( 0 );
|
||||||
|
@ -345,7 +347,15 @@ int RemoteCamera::GetResponse()
|
||||||
if ( !strcasecmp( content_type, "image/jpeg" ) || !strcasecmp( content_type, "image/jpg" ) )
|
if ( !strcasecmp( content_type, "image/jpeg" ) || !strcasecmp( content_type, "image/jpg" ) )
|
||||||
{
|
{
|
||||||
// Single image
|
// Single image
|
||||||
mode = SINGLE_JPEG;
|
mode = SINGLE_IMAGE;
|
||||||
|
format = JPEG;
|
||||||
|
state = CONTENT;
|
||||||
|
}
|
||||||
|
else if ( !strcasecmp( content_type, "image/x-rgb" ) )
|
||||||
|
{
|
||||||
|
// Single image
|
||||||
|
mode = SINGLE_IMAGE;
|
||||||
|
format = X_RGB;
|
||||||
state = CONTENT;
|
state = CONTENT;
|
||||||
}
|
}
|
||||||
else if ( !strcasecmp( content_type, "multipart/x-mixed-replace" ) )
|
else if ( !strcasecmp( content_type, "multipart/x-mixed-replace" ) )
|
||||||
|
@ -356,7 +366,7 @@ int RemoteCamera::GetResponse()
|
||||||
Error(( "No content boundary found in header '%s'", header ));
|
Error(( "No content boundary found in header '%s'", header ));
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
mode = MULTI_JPEG;
|
mode = MULTI_IMAGE;
|
||||||
state = SUBHEADER;
|
state = SUBHEADER;
|
||||||
}
|
}
|
||||||
//else if ( !strcasecmp( content_type, "video/mpeg" ) || !strcasecmp( content_type, "video/mpg" ) )
|
//else if ( !strcasecmp( content_type, "video/mpeg" ) || !strcasecmp( content_type, "video/mpg" ) )
|
||||||
|
@ -427,7 +437,15 @@ int RemoteCamera::GetResponse()
|
||||||
}
|
}
|
||||||
case CONTENT :
|
case CONTENT :
|
||||||
{
|
{
|
||||||
if ( strcasecmp( content_type, "image/jpeg" ) && strcasecmp( content_type, "image/jpg" ) )
|
if ( !strcasecmp( content_type, "image/jpeg" ) || !strcasecmp( content_type, "image/jpg" ) )
|
||||||
|
{
|
||||||
|
format = JPEG;
|
||||||
|
}
|
||||||
|
else if ( !strcasecmp( content_type, "image/x-rgb" ) )
|
||||||
|
{
|
||||||
|
format = X_RGB;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
Error(( "Found unsupported content type '%s'", content_type ));
|
Error(( "Found unsupported content type '%s'", content_type ));
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
@ -457,7 +475,7 @@ int RemoteCamera::GetResponse()
|
||||||
static RegExpr *content_expr = 0;
|
static RegExpr *content_expr = 0;
|
||||||
if ( buffer_len )
|
if ( buffer_len )
|
||||||
{
|
{
|
||||||
if ( mode == MULTI_JPEG )
|
if ( mode == MULTI_IMAGE )
|
||||||
{
|
{
|
||||||
if ( !content_expr )
|
if ( !content_expr )
|
||||||
{
|
{
|
||||||
|
@ -476,7 +494,7 @@ int RemoteCamera::GetResponse()
|
||||||
{
|
{
|
||||||
content_length = buffer.Size();
|
content_length = buffer.Size();
|
||||||
Debug( 3, ( "Got end of image by closure, content-length = %d", content_length ));
|
Debug( 3, ( "Got end of image by closure, content-length = %d", content_length ));
|
||||||
if ( mode == SINGLE_JPEG )
|
if ( mode == SINGLE_IMAGE )
|
||||||
{
|
{
|
||||||
if ( !content_expr )
|
if ( !content_expr )
|
||||||
{
|
{
|
||||||
|
@ -491,7 +509,7 @@ int RemoteCamera::GetResponse()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( mode == SINGLE_JPEG )
|
if ( mode == SINGLE_IMAGE )
|
||||||
{
|
{
|
||||||
state = HEADER;
|
state = HEADER;
|
||||||
Disconnect();
|
Disconnect();
|
||||||
|
@ -742,7 +760,15 @@ int RemoteCamera::GetResponse()
|
||||||
if ( !strcasecmp( content_type, "image/jpeg" ) || !strcasecmp( content_type, "image/jpg" ) )
|
if ( !strcasecmp( content_type, "image/jpeg" ) || !strcasecmp( content_type, "image/jpg" ) )
|
||||||
{
|
{
|
||||||
// Single image
|
// Single image
|
||||||
mode = SINGLE_JPEG;
|
mode = SINGLE_IMAGE;
|
||||||
|
format = JPEG;
|
||||||
|
state = CONTENT;
|
||||||
|
}
|
||||||
|
else if ( !strcasecmp( content_type, "image/x-rgb" ) )
|
||||||
|
{
|
||||||
|
// Single image
|
||||||
|
mode = SINGLE_IMAGE;
|
||||||
|
format = X_RGB;
|
||||||
state = CONTENT;
|
state = CONTENT;
|
||||||
}
|
}
|
||||||
else if ( !strcasecmp( content_type, "multipart/x-mixed-replace" ) )
|
else if ( !strcasecmp( content_type, "multipart/x-mixed-replace" ) )
|
||||||
|
@ -753,7 +779,7 @@ int RemoteCamera::GetResponse()
|
||||||
Error(( "No content boundary found in header '%s'", content_type_header ));
|
Error(( "No content boundary found in header '%s'", content_type_header ));
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
mode = MULTI_JPEG;
|
mode = MULTI_IMAGE;
|
||||||
state = SUBHEADER;
|
state = SUBHEADER;
|
||||||
}
|
}
|
||||||
//else if ( !strcasecmp( content_type, "video/mpeg" ) || !strcasecmp( content_type, "video/mpg" ) )
|
//else if ( !strcasecmp( content_type, "video/mpeg" ) || !strcasecmp( content_type, "video/mpg" ) )
|
||||||
|
@ -890,13 +916,21 @@ int RemoteCamera::GetResponse()
|
||||||
}
|
}
|
||||||
case CONTENT :
|
case CONTENT :
|
||||||
{
|
{
|
||||||
if ( strcasecmp( content_type, "image/jpeg" ) && strcasecmp( content_type, "image/jpg" ) )
|
if ( !strcasecmp( content_type, "image/jpeg" ) || !strcasecmp( content_type, "image/jpg" ) )
|
||||||
|
{
|
||||||
|
format = JPEG;
|
||||||
|
}
|
||||||
|
else if ( !strcasecmp( content_type, "image/x-rgb" ) )
|
||||||
|
{
|
||||||
|
format = X_RGB;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
Error(( "Found unsupported content type '%s'", content_type ));
|
Error(( "Found unsupported content type '%s'", content_type ));
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( buffer.Size() >= 2 )
|
if ( format == JPEG && buffer.Size() >= 2 )
|
||||||
{
|
{
|
||||||
if ( buffer[0] != 0xff || buffer[1] != 0xd8 )
|
if ( buffer[0] != 0xff || buffer[1] != 0xd8 )
|
||||||
{
|
{
|
||||||
|
@ -931,7 +965,7 @@ int RemoteCamera::GetResponse()
|
||||||
}
|
}
|
||||||
if ( buffer_len )
|
if ( buffer_len )
|
||||||
{
|
{
|
||||||
if ( mode == MULTI_JPEG )
|
if ( mode == MULTI_IMAGE )
|
||||||
{
|
{
|
||||||
while ( char *start_ptr = (char *)memstr( (char *)buffer+content_pos, "\r\n--", buffer_size-content_pos ) )
|
while ( char *start_ptr = (char *)memstr( (char *)buffer+content_pos, "\r\n--", buffer_size-content_pos ) )
|
||||||
{
|
{
|
||||||
|
@ -945,7 +979,7 @@ int RemoteCamera::GetResponse()
|
||||||
{
|
{
|
||||||
content_length = buffer_size;
|
content_length = buffer_size;
|
||||||
Debug( 3, ( "Got end of image by closure, content-length = %d", content_length ));
|
Debug( 3, ( "Got end of image by closure, content-length = %d", content_length ));
|
||||||
if ( mode == SINGLE_JPEG )
|
if ( mode == SINGLE_IMAGE )
|
||||||
{
|
{
|
||||||
char *end_ptr = (char *)buffer+buffer_size;
|
char *end_ptr = (char *)buffer+buffer_size;
|
||||||
|
|
||||||
|
@ -963,7 +997,7 @@ int RemoteCamera::GetResponse()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( mode == SINGLE_JPEG )
|
if ( mode == SINGLE_IMAGE )
|
||||||
{
|
{
|
||||||
state = HEADER;
|
state = HEADER;
|
||||||
Disconnect();
|
Disconnect();
|
||||||
|
@ -972,7 +1006,8 @@ int RemoteCamera::GetResponse()
|
||||||
{
|
{
|
||||||
state = SUBHEADER;
|
state = SUBHEADER;
|
||||||
}
|
}
|
||||||
if ( buffer.Size() >= 2 )
|
|
||||||
|
if ( format == JPEG && buffer.Size() >= 2 )
|
||||||
{
|
{
|
||||||
if ( buffer[0] != 0xff || buffer[1] != 0xd8 )
|
if ( buffer[0] != 0xff || buffer[1] != 0xd8 )
|
||||||
{
|
{
|
||||||
|
@ -999,10 +1034,10 @@ int RemoteCamera::PreCapture()
|
||||||
{
|
{
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
mode = SINGLE_JPEG;
|
mode = SINGLE_IMAGE;
|
||||||
buffer.Empty();
|
buffer.Empty();
|
||||||
}
|
}
|
||||||
if ( mode == SINGLE_JPEG )
|
if ( mode == SINGLE_IMAGE )
|
||||||
{
|
{
|
||||||
if ( SendRequest() < 0 )
|
if ( SendRequest() < 0 )
|
||||||
{
|
{
|
||||||
|
@ -1021,9 +1056,33 @@ int RemoteCamera::PostCapture( Image &image )
|
||||||
Disconnect();
|
Disconnect();
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
if ( !image.DecodeJpeg( buffer.Extract( content_length ), content_length ) )
|
switch( format )
|
||||||
{
|
{
|
||||||
return( -1 );
|
case JPEG :
|
||||||
|
{
|
||||||
|
if ( !image.DecodeJpeg( buffer.Extract( content_length ), content_length ) )
|
||||||
|
{
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case X_RGB :
|
||||||
|
{
|
||||||
|
if ( content_length != image.Size() )
|
||||||
|
{
|
||||||
|
Error(( "Image length mismatch, expected %d bytes, content length was %d", image.Size(), content_length ));
|
||||||
|
Disconnect();
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
image.Assign( width, height, colours, buffer );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default :
|
||||||
|
{
|
||||||
|
Error(( "Unexpected image format encountered" ));
|
||||||
|
Disconnect();
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,8 @@ protected:
|
||||||
struct sockaddr_in sa;
|
struct sockaddr_in sa;
|
||||||
int sd;
|
int sd;
|
||||||
Buffer buffer;
|
Buffer buffer;
|
||||||
enum { SINGLE_JPEG, MULTI_JPEG, MULTI_MPEG } mode;
|
enum { SINGLE_IMAGE, MULTI_IMAGE } mode;
|
||||||
|
enum { UNDEF, JPEG, X_RGB } format;
|
||||||
enum { HEADER, HEADERCONT, SUBHEADER, SUBHEADERCONT, CONTENT } state;
|
enum { HEADER, HEADERCONT, SUBHEADER, SUBHEADERCONT, CONTENT } state;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
Loading…
Reference in New Issue