1) Changed ZM static colours to RGB order instead of HTML(BGR) order
2) Allow ZM to compile without swscale - hopefully 3) Saved few cpu cycles during image blending 4) Fixed wrong zone colours showing up 5) Unrelated fix: Allow ZM to be compiled with the latest ffmpeg revisions
This commit is contained in:
parent
f2aaeb78e0
commit
37cc9199b2
148
src/zm_image.cpp
148
src/zm_image.cpp
|
@ -451,19 +451,22 @@ void Image::Assign( const Image &image ) {
|
|||
|
||||
Image *Image::HighlightEdges( Rgb colour, const Box *limits )
|
||||
{
|
||||
if ( colours != 1 )
|
||||
{
|
||||
Panic( "Attempt to highlight image edges when colours = %d", colours );
|
||||
}
|
||||
Image *high_image = new Image( width, height, 3, ZM_SUBPIX_ORDER_RGB);
|
||||
if ( colours != 1 )
|
||||
{
|
||||
Panic( "Attempt to highlight image edges when colours = %d", colours );
|
||||
}
|
||||
|
||||
Image *high_image = new Image( width, height, ZM_COLOUR_RGB24, ZM_SUBPIX_ORDER_RGB);
|
||||
uint8_t* high_buff = high_image->WriteBuffer(width, height, ZM_COLOUR_RGB24, ZM_SUBPIX_ORDER_RGB);
|
||||
|
||||
int lo_x = limits?limits->Lo().X():0;
|
||||
int lo_y = limits?limits->Lo().Y():0;
|
||||
int hi_x = limits?limits->Hi().X():width-1;
|
||||
int hi_y = limits?limits->Hi().Y():height-1;
|
||||
for ( int y = lo_y; y <= hi_y; y++ )
|
||||
{
|
||||
unsigned char *p = &buffer[(y*width)+lo_x];
|
||||
unsigned char *phigh = (uint8_t*)high_image->Buffer( lo_x, y );
|
||||
uint8_t *p = &buffer[(y*width)+lo_x];
|
||||
uint8_t *phigh = high_buff + ( lo_x * y );
|
||||
for ( int x = lo_x; x <= hi_x; x++, p++, phigh += 3 )
|
||||
{
|
||||
bool edge = false;
|
||||
|
@ -1209,10 +1212,6 @@ void Image::Blend( const Image &image, int transparency ) const
|
|||
Panic( "Attempt to blend different sized images, expected %dx%dx%d %d, got %dx%dx%d %d", width, height, colours, subpixelorder, image.width, image.height, image.colours, image.subpixelorder );
|
||||
}
|
||||
|
||||
if((size % 16) != 0) {
|
||||
Warning("Image size is not multiples of 16");
|
||||
}
|
||||
|
||||
/* Do the blending */
|
||||
(*fptr_blend)(buffer, image.buffer, buffer, size, transparency);
|
||||
}
|
||||
|
@ -1678,6 +1677,10 @@ void Image::Fill( Rgb colour, const Box *limits )
|
|||
{
|
||||
Panic( "Attempt to fill image with unexpected colours %d", colours );
|
||||
}
|
||||
|
||||
/* Convert the colour's RGBA subpixel order into the image's subpixel order */
|
||||
colour = rgb_convert(colour,subpixelorder);
|
||||
|
||||
int lo_x = limits?limits->Lo().X():0;
|
||||
int lo_y = limits?limits->Lo().Y():0;
|
||||
int hi_x = limits?limits->Hi().X():width-1;
|
||||
|
@ -1733,6 +1736,9 @@ void Image::Fill( Rgb colour, int density, const Box *limits )
|
|||
{
|
||||
Panic( "Attempt to fill image with unexpected colours %d", colours );
|
||||
}
|
||||
|
||||
/* Convert the colour's RGBA subpixel order into the image's subpixel order */
|
||||
colour = rgb_convert(colour,subpixelorder);
|
||||
|
||||
int lo_x = limits?limits->Lo().X():0;
|
||||
int lo_y = limits?limits->Lo().Y():0;
|
||||
|
@ -1786,9 +1792,13 @@ void Image::Fill( Rgb colour, int density, const Box *limits )
|
|||
void Image::Outline( Rgb colour, const Polygon &polygon )
|
||||
{
|
||||
if ( !(colours == 1 || colours == 3 || colours == 4 ) )
|
||||
{
|
||||
Panic( "Attempt to outline image with unexpected colours %d", colours );
|
||||
}
|
||||
{
|
||||
Panic( "Attempt to outline image with unexpected colours %d", colours );
|
||||
}
|
||||
|
||||
/* Convert the colour's RGBA subpixel order into the image's subpixel order */
|
||||
colour = rgb_convert(colour,subpixelorder);
|
||||
|
||||
int n_coords = polygon.getNumCoords();
|
||||
for ( int j = 0, i = n_coords-1; j < n_coords; i = j++ )
|
||||
{
|
||||
|
@ -1894,6 +1904,9 @@ void Image::Fill( Rgb colour, int density, const Polygon &polygon )
|
|||
{
|
||||
Panic( "Attempt to fill image with unexpected colours %d", colours );
|
||||
}
|
||||
|
||||
/* Convert the colour's RGBA subpixel order into the image's subpixel order */
|
||||
colour = rgb_convert(colour,subpixelorder);
|
||||
|
||||
int n_coords = polygon.getNumCoords();
|
||||
int n_global_edges = 0;
|
||||
|
@ -2336,35 +2349,39 @@ void Image::Scale( unsigned int factor )
|
|||
|
||||
__attribute__ ((noinline)) void sse2_fastblend(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count, double blendpercent) {
|
||||
#if (defined(__i386__) || defined(__x86_64__))
|
||||
int divider = 0;
|
||||
uint32_t clearmask = 0;
|
||||
static uint32_t divider = 0;
|
||||
static uint32_t clearmask = 0;
|
||||
static double current_blendpercent = 0.0;
|
||||
unsigned long i = 0;
|
||||
|
||||
/* Attempt to match the blending percent to one of the possible values */
|
||||
if(blendpercent < 2.34375) {
|
||||
// 1.5625% blending
|
||||
divider = 6;
|
||||
clearmask = 0x03030303;
|
||||
} else if(blendpercent >= 2.34375 && blendpercent < 4.6875) {
|
||||
// 3.125% blending
|
||||
divider = 5;
|
||||
clearmask = 0x07070707;
|
||||
} else if(blendpercent >= 4.6875 && blendpercent < 9.375) {
|
||||
// 6.25% blending
|
||||
divider = 4;
|
||||
clearmask = 0x0F0F0F0F;
|
||||
} else if(blendpercent >= 9.375 && blendpercent < 18.75) {
|
||||
// 12.5% blending
|
||||
divider = 3;
|
||||
clearmask = 0x1F1F1F1F;
|
||||
} else if(blendpercent >= 18.75 && blendpercent < 37.5) {
|
||||
// 25% blending
|
||||
divider = 2;
|
||||
clearmask = 0x3F3F3F3F;
|
||||
} else if(blendpercent >= 37.5) {
|
||||
// 50% blending
|
||||
divider = 1;
|
||||
clearmask = 0x7F7F7F7F;
|
||||
|
||||
if(current_blendpercent != blendpercent) {
|
||||
/* Attempt to match the blending percent to one of the possible values */
|
||||
if(blendpercent < 2.34375) {
|
||||
// 1.5625% blending
|
||||
divider = 6;
|
||||
clearmask = 0x03030303;
|
||||
} else if(blendpercent >= 2.34375 && blendpercent < 4.6875) {
|
||||
// 3.125% blending
|
||||
divider = 5;
|
||||
clearmask = 0x07070707;
|
||||
} else if(blendpercent >= 4.6875 && blendpercent < 9.375) {
|
||||
// 6.25% blending
|
||||
divider = 4;
|
||||
clearmask = 0x0F0F0F0F;
|
||||
} else if(blendpercent >= 9.375 && blendpercent < 18.75) {
|
||||
// 12.5% blending
|
||||
divider = 3;
|
||||
clearmask = 0x1F1F1F1F;
|
||||
} else if(blendpercent >= 18.75 && blendpercent < 37.5) {
|
||||
// 25% blending
|
||||
divider = 2;
|
||||
clearmask = 0x3F3F3F3F;
|
||||
} else if(blendpercent >= 37.5) {
|
||||
// 50% blending
|
||||
divider = 1;
|
||||
clearmask = 0x7F7F7F7F;
|
||||
}
|
||||
current_blendpercent = blendpercent;
|
||||
}
|
||||
|
||||
__asm__ __volatile__(
|
||||
|
@ -2395,28 +2412,33 @@ __attribute__ ((noinline)) void sse2_fastblend(const uint8_t* col1, const uint8_
|
|||
}
|
||||
|
||||
__attribute__ ((noinline)) void std_fastblend(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count, double blendpercent) {
|
||||
int divider = 0;
|
||||
|
||||
/* Attempt to match the blending percent to one of the possible values */
|
||||
if(blendpercent < 2.34375) {
|
||||
// 1.5625% blending
|
||||
divider = 6;
|
||||
} else if(blendpercent >= 2.34375 && blendpercent < 4.6875) {
|
||||
// 3.125% blending
|
||||
divider = 5;
|
||||
} else if(blendpercent >= 4.6875 && blendpercent < 9.375) {
|
||||
// 6.25% blending
|
||||
divider = 4;
|
||||
} else if(blendpercent >= 9.375 && blendpercent < 18.75) {
|
||||
// 12.5% blending
|
||||
divider = 3;
|
||||
} else if(blendpercent >= 18.75 && blendpercent < 37.5) {
|
||||
// 25% blending
|
||||
divider = 2;
|
||||
} else if(blendpercent >= 37.5) {
|
||||
// 50% blending
|
||||
divider = 1;
|
||||
static int divider = 0;
|
||||
static double current_blendpercent = 0.0;
|
||||
|
||||
if(current_blendpercent != blendpercent) {
|
||||
/* Attempt to match the blending percent to one of the possible values */
|
||||
if(blendpercent < 2.34375) {
|
||||
// 1.5625% blending
|
||||
divider = 6;
|
||||
} else if(blendpercent >= 2.34375 && blendpercent < 4.6875) {
|
||||
// 3.125% blending
|
||||
divider = 5;
|
||||
} else if(blendpercent >= 4.6875 && blendpercent < 9.375) {
|
||||
// 6.25% blending
|
||||
divider = 4;
|
||||
} else if(blendpercent >= 9.375 && blendpercent < 18.75) {
|
||||
// 12.5% blending
|
||||
divider = 3;
|
||||
} else if(blendpercent >= 18.75 && blendpercent < 37.5) {
|
||||
// 25% blending
|
||||
divider = 2;
|
||||
} else if(blendpercent >= 37.5) {
|
||||
// 50% blending
|
||||
divider = 1;
|
||||
}
|
||||
current_blendpercent = blendpercent;
|
||||
}
|
||||
|
||||
|
||||
for(register unsigned long i=0; i < count; i += 16, col1 += 16, col2 += 16, result += 16) {
|
||||
result[0] = ((col2[0] - col1[0])>>divider) + col1[0];
|
||||
|
|
|
@ -375,7 +375,8 @@ LocalCamera::LocalCamera( int p_id, const std::string &p_device, int p_channel,
|
|||
subpixelorder = ZM_SUBPIX_ORDER_NONE;
|
||||
/* Unable to find a solution for the selected palette and target colourspace. Conversion required. Notify the user of performance penalty */
|
||||
} else {
|
||||
Warning("Unable to find a match for the selected palette and target colourspace. Conversion required, performance penalty expected");
|
||||
if( capture )
|
||||
Warning("Unable to find a match for the selected palette and target colourspace. Conversion required, performance penalty expected");
|
||||
#if HAVE_LIBSWSCALE
|
||||
/* Try using swscale for the conversion */
|
||||
conversion_type = 1;
|
||||
|
@ -1011,6 +1012,7 @@ void LocalCamera::Terminate()
|
|||
|
||||
close( vid_fd );
|
||||
|
||||
#if HAVE_LIBSWSCALE
|
||||
/* Clean up swscale stuff */
|
||||
if(conversion_type == 1) {
|
||||
sws_freeContext(imgConversionContext);
|
||||
|
@ -1019,7 +1021,8 @@ void LocalCamera::Terminate()
|
|||
av_free(tmpPicture);
|
||||
tmpPicture = NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#define capString(test,prefix,yesString,noString,capability) \
|
||||
|
@ -1914,15 +1917,16 @@ int LocalCamera::Capture( Image &image )
|
|||
Error("Failed requesting writeable buffer for the captured image.");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
#if HAVE_LIBSWSCALE
|
||||
if(conversion_type == 1) {
|
||||
/* Use swscale to convert the image directly into the shared memory */
|
||||
|
||||
avpicture_fill( (AVPicture *)tmpPicture, directbuffer, imagePixFormat, width, height );
|
||||
|
||||
sws_scale( imgConversionContext, capturePictures[capture_frame]->data, capturePictures[capture_frame]->linesize, 0, height, tmpPicture->data, tmpPicture->linesize );
|
||||
|
||||
} else if(conversion_type == 2) {
|
||||
}
|
||||
#endif
|
||||
if(conversion_type == 2) {
|
||||
|
||||
/* Call the image conversion function and convert directly into the shared memory */
|
||||
(*conversion_fptr)(buffer, directbuffer, pixels);
|
||||
|
|
|
@ -337,7 +337,7 @@ double VideoStream::EncodeFrame( const uint8_t *buffer, int buffer_size, bool ad
|
|||
}
|
||||
sws_scale( img_convert_ctx, tmp_opicture->data, tmp_opicture->linesize, 0, c->height, opicture->data, opicture->linesize );
|
||||
#else // HAVE_LIBSWSCALE
|
||||
img_convert( (AVPicture *)opicture, c->pix_fmt, (AVPicture *)tmp_opicture, pf, c->width, c->height );
|
||||
Fatal("swscale is required for MPEG mode");
|
||||
#endif // HAVE_LIBSWSCALE
|
||||
}
|
||||
else
|
||||
|
|
16
src/zm_rgb.h
16
src/zm_rgb.h
|
@ -34,11 +34,11 @@ typedef uint32_t Rgb; // RGB colour type
|
|||
|
||||
#define RGB_WHITE (0x00ffffff)
|
||||
#define RGB_BLACK (0x00000000)
|
||||
#define RGB_RED (0x00ff0000)
|
||||
#define RGB_RED (0x000000ff)
|
||||
#define RGB_GREEN (0x0000ff00)
|
||||
#define RGB_BLUE (0x000000ff)
|
||||
#define RGB_ORANGE (0x00ffa500)
|
||||
#define RGB_PURPLE (0x00800080)
|
||||
#define RGB_BLUE (0x00ff0000)
|
||||
#define RGB_ORANGE (0x0000a5ff)
|
||||
#define RGB_PURPLE (0x00800080)
|
||||
#define RGB_TRANSPARENT (0x01000000)
|
||||
|
||||
#define RGB_VAL(v,c) (((v)>>(16-((c)*8)))&0xff)
|
||||
|
@ -46,7 +46,7 @@ typedef uint32_t Rgb; // RGB colour type
|
|||
/* RGB or RGBA macros */
|
||||
#define BLUE_VAL_RGBA(v) (((v)>>16)&0xff)
|
||||
#define GREEN_VAL_RGBA(v) (((v)>>8)&0xff)
|
||||
#define RED_VAL_RGBA(v) ((v)&0xff)
|
||||
#define RED_VAL_RGBA(v) ((v)&0xff)
|
||||
#define ALPHA_VAL_RGBA(v) ((v)>>24)&0xff)
|
||||
#define RED_PTR_RGBA(ptr) (*((uint8_t*)ptr))
|
||||
#define GREEN_PTR_RGBA(ptr) (*((uint8_t*)ptr+1))
|
||||
|
@ -54,7 +54,7 @@ typedef uint32_t Rgb; // RGB colour type
|
|||
#define ALPHA_PTR_RGBA(ptr) (*((uint8_t*)ptr+3))
|
||||
|
||||
/* BGR or BGRA */
|
||||
#define RED_VAL_BGRA(v) (((v)>>16)&0xff)
|
||||
#define RED_VAL_BGRA(v) (((v)>>16)&0xff)
|
||||
#define GREEN_VAL_BGRA(v) (((v)>>8)&0xff)
|
||||
#define BLUE_VAL_BGRA(v) ((v)&0xff)
|
||||
#define ALPHA_VAL_BGRA(v) ((v)>>24)&0xff)
|
||||
|
@ -66,7 +66,7 @@ typedef uint32_t Rgb; // RGB colour type
|
|||
/* ARGB */
|
||||
#define BLUE_VAL_ARGB(v) (((v)>>24)&0xff)
|
||||
#define GREEN_VAL_ARGB(v) (((v)>>16)&0xff)
|
||||
#define RED_VAL_ARGB(v) (((v)>>8)&0xff)
|
||||
#define RED_VAL_ARGB(v) (((v)>>8)&0xff)
|
||||
#define ALPHA_VAL_ARGB(v) ((v)&0xff)
|
||||
#define RED_PTR_ARGB(ptr) (*((uint8_t*)ptr+1))
|
||||
#define GREEN_PTR_ARGB(ptr) (*((uint8_t*)ptr+2))
|
||||
|
@ -76,7 +76,7 @@ typedef uint32_t Rgb; // RGB colour type
|
|||
/* ABGR */
|
||||
#define BLUE_VAL_ABGR(v) (((v)>>8)&0xff)
|
||||
#define GREEN_VAL_ABGR(v) (((v)>>16)&0xff)
|
||||
#define RED_VAL_ABGR(v) (((v)>>24)&0xff)
|
||||
#define RED_VAL_ABGR(v) (((v)>>24)&0xff)
|
||||
#define ALPHA_VAL_ABGR(v) ((v)&0xff)
|
||||
#define RED_PTR_ABGR(ptr) (*((uint8_t*)ptr+3))
|
||||
#define GREEN_PTR_ABGR(ptr) (*((uint8_t*)ptr+2))
|
||||
|
|
Loading…
Reference in New Issue