2003-03-26 19:57:29 +08:00
|
|
|
//
|
|
|
|
// ZoneMinder Image Class Interface, $Date$, $Revision$
|
2008-07-25 17:33:23 +08:00
|
|
|
// Copyright (C) 2001-2008 Philip Coombes
|
2003-03-26 19:57:29 +08:00
|
|
|
//
|
|
|
|
// This program is free software; you can redistribute it and/or
|
|
|
|
// modify it under the terms of the GNU General Public License
|
|
|
|
// as published by the Free Software Foundation; either version 2
|
|
|
|
// of the License, or (at your option) any later version.
|
|
|
|
//
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
|
|
// along with this program; if not, write to the Free Software
|
2016-12-26 23:23:16 +08:00
|
|
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
2003-03-26 19:57:29 +08:00
|
|
|
//
|
|
|
|
|
|
|
|
#ifndef ZM_IMAGE_H
|
|
|
|
#define ZM_IMAGE_H
|
|
|
|
|
2008-07-16 16:35:59 +08:00
|
|
|
#include "zm.h"
|
2017-08-24 03:05:44 +08:00
|
|
|
extern "C" {
|
2004-01-15 05:26:47 +08:00
|
|
|
#include "zm_jpeg.h"
|
2003-03-26 19:57:29 +08:00
|
|
|
}
|
|
|
|
#include "zm_rgb.h"
|
|
|
|
#include "zm_coord.h"
|
|
|
|
#include "zm_box.h"
|
2005-11-30 01:51:06 +08:00
|
|
|
#include "zm_poly.h"
|
2011-05-01 02:39:34 +08:00
|
|
|
#include "zm_mem_utils.h"
|
|
|
|
#include "zm_utils.h"
|
|
|
|
|
2017-08-24 03:05:44 +08:00
|
|
|
class Image;
|
|
|
|
#include "zm_ffmpeg.h"
|
|
|
|
|
2011-05-01 02:39:34 +08:00
|
|
|
#include <errno.h>
|
2003-03-26 19:57:29 +08:00
|
|
|
|
2009-03-20 20:39:29 +08:00
|
|
|
#if HAVE_ZLIB_H
|
|
|
|
#include <zlib.h>
|
|
|
|
#endif // HAVE_ZLIB_H
|
|
|
|
|
2011-04-29 22:26:50 +08:00
|
|
|
#define ZM_BUFTYPE_DONTFREE 0
|
|
|
|
#define ZM_BUFTYPE_MALLOC 1
|
|
|
|
#define ZM_BUFTYPE_NEW 2
|
|
|
|
#define ZM_BUFTYPE_AVMALLOC 3
|
|
|
|
#define ZM_BUFTYPE_ZM 4
|
|
|
|
|
2011-06-15 01:38:18 +08:00
|
|
|
typedef void (*blend_fptr_t)(const uint8_t*, const uint8_t*, uint8_t*, unsigned long, double);
|
|
|
|
typedef void (*delta_fptr_t)(const uint8_t*, const uint8_t*, uint8_t*, unsigned long);
|
|
|
|
typedef void (*convert_fptr_t)(const uint8_t*, uint8_t*, unsigned long);
|
2012-07-15 22:30:37 +08:00
|
|
|
typedef void (*deinterlace_4field_fptr_t)(uint8_t*, uint8_t*, unsigned int, unsigned int, unsigned int);
|
2011-06-15 01:38:18 +08:00
|
|
|
typedef void* (*imgbufcpy_fptr_t)(void*, const void*, size_t);
|
|
|
|
|
|
|
|
extern imgbufcpy_fptr_t fptr_imgbufcpy;
|
2011-05-06 20:01:16 +08:00
|
|
|
|
|
|
|
/* Should be called from Image class functions */
|
|
|
|
inline static uint8_t* AllocBuffer(size_t p_bufsize) {
|
2019-08-11 02:46:05 +08:00
|
|
|
uint8_t* buffer = (uint8_t*)zm_mallocaligned(64, p_bufsize);
|
2020-08-26 07:45:48 +08:00
|
|
|
if ( buffer == nullptr )
|
2019-08-11 02:46:05 +08:00
|
|
|
Fatal("Memory allocation failed: %s", strerror(errno));
|
2011-05-06 20:01:16 +08:00
|
|
|
|
|
|
|
return buffer;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline static void DumpBuffer(uint8_t* buffer, int buffertype) {
|
2020-11-20 05:38:49 +08:00
|
|
|
if ( buffer && (buffertype != ZM_BUFTYPE_DONTFREE) ) {
|
2017-08-11 03:44:20 +08:00
|
|
|
if ( buffertype == ZM_BUFTYPE_ZM ) {
|
|
|
|
zm_freealigned(buffer);
|
|
|
|
} else if ( buffertype == ZM_BUFTYPE_MALLOC ) {
|
|
|
|
free(buffer);
|
|
|
|
} else if ( buffertype == ZM_BUFTYPE_NEW ) {
|
|
|
|
delete buffer;
|
2011-05-06 20:01:16 +08:00
|
|
|
/*else if(buffertype == ZM_BUFTYPE_AVMALLOC)
|
|
|
|
av_free(buffer);
|
|
|
|
*/
|
2017-08-11 03:44:20 +08:00
|
|
|
} else {
|
2019-08-11 02:46:05 +08:00
|
|
|
Error("Unknown buffer type in DumpBuffer(%d)", buffertype);
|
2017-08-11 03:44:20 +08:00
|
|
|
}
|
2011-05-06 20:01:16 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-06-15 01:38:18 +08:00
|
|
|
|
2003-03-26 19:57:29 +08:00
|
|
|
//
|
|
|
|
// This is image class, and represents a frame captured from a
|
|
|
|
// camera in raw form.
|
|
|
|
//
|
2017-08-11 03:44:20 +08:00
|
|
|
class Image {
|
2019-02-22 22:44:57 +08:00
|
|
|
private:
|
|
|
|
delta_fptr_t delta8_rgb;
|
|
|
|
delta_fptr_t delta8_bgr;
|
|
|
|
delta_fptr_t delta8_rgba;
|
|
|
|
delta_fptr_t delta8_bgra;
|
|
|
|
delta_fptr_t delta8_argb;
|
|
|
|
delta_fptr_t delta8_abgr;
|
|
|
|
delta_fptr_t delta8_gray8;
|
|
|
|
|
|
|
|
// Per object function pointer that we can set once we know the image dimensions
|
|
|
|
blend_fptr_t blend;
|
|
|
|
|
|
|
|
void update_function_pointers();
|
2003-03-26 19:57:29 +08:00
|
|
|
protected:
|
2004-02-16 03:53:10 +08:00
|
|
|
|
2017-08-11 03:44:20 +08:00
|
|
|
struct Edge {
|
2005-11-30 01:51:06 +08:00
|
|
|
int min_y;
|
|
|
|
int max_y;
|
|
|
|
double min_x;
|
|
|
|
double _1_m;
|
|
|
|
|
2017-08-11 03:44:20 +08:00
|
|
|
static int CompareYX( const void *p1, const void *p2 ) {
|
2017-10-23 21:51:41 +08:00
|
|
|
// This is because these functions are passed to qsort
|
|
|
|
const Edge *e1 = reinterpret_cast<const Edge *>(p1), *e2 = reinterpret_cast<const Edge *>(p2);
|
2005-11-30 01:51:06 +08:00
|
|
|
if ( e1->min_y == e2->min_y )
|
|
|
|
return( int(e1->min_x - e2->min_x) );
|
|
|
|
else
|
|
|
|
return( int(e1->min_y - e2->min_y) );
|
|
|
|
}
|
2017-08-11 03:44:20 +08:00
|
|
|
static int CompareX( const void *p1, const void *p2 ) {
|
2017-10-23 21:51:41 +08:00
|
|
|
const Edge *e1 = reinterpret_cast<const Edge *>(p1), *e2 = reinterpret_cast<const Edge *>(p2);
|
2005-11-30 01:51:06 +08:00
|
|
|
return( int(e1->min_x - e2->min_x) );
|
|
|
|
}
|
|
|
|
};
|
2011-04-29 22:26:50 +08:00
|
|
|
|
2011-05-05 17:52:00 +08:00
|
|
|
inline void DumpImgBuffer() {
|
2020-04-27 06:19:30 +08:00
|
|
|
DumpBuffer(buffer, buffertype);
|
2020-11-20 05:38:49 +08:00
|
|
|
buffertype = ZM_BUFTYPE_DONTFREE;
|
2020-08-26 07:45:48 +08:00
|
|
|
buffer = nullptr;
|
2011-04-29 22:26:50 +08:00
|
|
|
allocation = 0;
|
|
|
|
}
|
|
|
|
|
2011-05-05 17:52:00 +08:00
|
|
|
inline void AllocImgBuffer(size_t p_bufsize) {
|
2017-08-11 03:44:20 +08:00
|
|
|
if ( buffer )
|
2011-05-05 17:52:00 +08:00
|
|
|
DumpImgBuffer();
|
2011-04-29 22:26:50 +08:00
|
|
|
|
2011-05-05 17:52:00 +08:00
|
|
|
buffer = AllocBuffer(p_bufsize);
|
2011-04-29 22:26:50 +08:00
|
|
|
buffertype = ZM_BUFTYPE_ZM;
|
|
|
|
allocation = p_bufsize;
|
|
|
|
}
|
2005-11-30 01:51:06 +08:00
|
|
|
|
2009-10-14 18:01:46 +08:00
|
|
|
public:
|
2017-03-12 22:00:46 +08:00
|
|
|
enum { ZM_CHAR_HEIGHT=11, ZM_CHAR_WIDTH=6 };
|
|
|
|
enum { LINE_HEIGHT=ZM_CHAR_HEIGHT+0 };
|
2009-10-14 18:01:46 +08:00
|
|
|
|
2004-02-16 03:53:10 +08:00
|
|
|
protected:
|
|
|
|
static bool initialised;
|
|
|
|
static unsigned char *abs_table;
|
|
|
|
static unsigned char *y_r_table;
|
|
|
|
static unsigned char *y_g_table;
|
|
|
|
static unsigned char *y_b_table;
|
2016-07-04 03:59:05 +08:00
|
|
|
static jpeg_compress_struct *writejpg_ccinfo[101];
|
|
|
|
static jpeg_compress_struct *encodejpg_ccinfo[101];
|
|
|
|
static jpeg_decompress_struct *readjpg_dcinfo;
|
|
|
|
static jpeg_decompress_struct *decodejpg_dcinfo;
|
2005-11-22 18:41:50 +08:00
|
|
|
static struct zm_error_mgr jpg_err;
|
2003-03-26 19:57:29 +08:00
|
|
|
|
2013-09-17 15:28:59 +08:00
|
|
|
unsigned int width;
|
2020-07-08 04:13:41 +08:00
|
|
|
unsigned int linesize;
|
2013-09-17 15:28:59 +08:00
|
|
|
unsigned int height;
|
|
|
|
unsigned int pixels;
|
|
|
|
unsigned int colours;
|
2020-07-08 04:13:41 +08:00
|
|
|
unsigned int padding;
|
2013-09-17 15:28:59 +08:00
|
|
|
unsigned int size;
|
|
|
|
unsigned int subpixelorder;
|
2011-04-29 22:26:50 +08:00
|
|
|
unsigned long allocation;
|
2017-10-23 21:51:41 +08:00
|
|
|
_AVPIXELFORMAT imagePixFormat;
|
2011-02-15 19:18:41 +08:00
|
|
|
uint8_t *buffer;
|
2011-04-29 22:26:50 +08:00
|
|
|
int buffertype; /* 0=not ours, no need to call free(), 1=malloc() buffer, 2=new buffer */
|
|
|
|
int holdbuffer; /* Hold the buffer instead of replacing it with new one */
|
2006-11-16 19:34:53 +08:00
|
|
|
char text[1024];
|
2003-03-26 19:57:29 +08:00
|
|
|
|
|
|
|
public:
|
2007-08-30 02:11:09 +08:00
|
|
|
Image();
|
2020-07-24 05:14:56 +08:00
|
|
|
explicit Image(const char *filename);
|
2020-07-08 04:13:41 +08:00
|
|
|
Image(int p_width, int p_height, int p_colours, int p_subpixelorder, uint8_t *p_buffer=0, unsigned int padding=0);
|
|
|
|
Image(int p_width, int p_linesize, int p_height, int p_colours, int p_subpixelorder, uint8_t *p_buffer=0, unsigned int padding=0);
|
2017-11-19 05:00:10 +08:00
|
|
|
explicit Image( const Image &p_image );
|
|
|
|
explicit Image( const AVFrame *frame );
|
2020-07-08 04:13:41 +08:00
|
|
|
|
2007-08-30 02:11:09 +08:00
|
|
|
~Image();
|
2016-10-07 23:35:14 +08:00
|
|
|
static void Initialise();
|
|
|
|
static void Deinitialise();
|
2003-03-26 19:57:29 +08:00
|
|
|
|
2018-08-12 01:35:37 +08:00
|
|
|
inline unsigned int Width() const { return width; }
|
2020-07-08 04:13:41 +08:00
|
|
|
inline unsigned int LineSize() const { return linesize; }
|
2018-08-12 01:35:37 +08:00
|
|
|
inline unsigned int Height() const { return height; }
|
|
|
|
inline unsigned int Pixels() const { return pixels; }
|
|
|
|
inline unsigned int Colours() const { return colours; }
|
|
|
|
inline unsigned int SubpixelOrder() const { return subpixelorder; }
|
|
|
|
inline unsigned int Size() const { return size; }
|
2017-10-23 21:51:41 +08:00
|
|
|
|
2020-12-30 01:18:26 +08:00
|
|
|
inline AVPixelFormat AVPixFormat() {
|
2017-11-13 00:42:34 +08:00
|
|
|
if ( colours == ZM_COLOUR_RGB32 ) {
|
|
|
|
return AV_PIX_FMT_RGBA;
|
|
|
|
} else if ( colours == ZM_COLOUR_RGB24 ) {
|
2017-11-14 06:24:28 +08:00
|
|
|
if ( subpixelorder == ZM_SUBPIX_ORDER_BGR){
|
|
|
|
return AV_PIX_FMT_BGR24;
|
|
|
|
} else {
|
|
|
|
return AV_PIX_FMT_RGB24;
|
|
|
|
}
|
2017-11-13 00:42:34 +08:00
|
|
|
} else if ( colours == ZM_COLOUR_GRAY8 ) {
|
|
|
|
return AV_PIX_FMT_GRAY8;
|
|
|
|
} else {
|
|
|
|
Error("Unknown colours (%d)",colours);
|
|
|
|
return AV_PIX_FMT_RGBA;
|
2017-10-23 21:51:41 +08:00
|
|
|
}
|
|
|
|
}
|
2003-03-26 19:57:29 +08:00
|
|
|
|
2011-04-29 22:26:50 +08:00
|
|
|
/* Internal buffer should not be modified from functions outside of this class */
|
2018-08-12 01:35:37 +08:00
|
|
|
inline const uint8_t* Buffer() const { return buffer; }
|
2020-07-08 04:13:41 +08:00
|
|
|
inline const uint8_t* Buffer( unsigned int x, unsigned int y= 0 ) const { return &buffer[(y*linesize)+x]; }
|
2011-04-29 22:26:50 +08:00
|
|
|
/* Request writeable buffer */
|
2013-09-17 15:28:59 +08:00
|
|
|
uint8_t* WriteBuffer(const unsigned int p_width, const unsigned int p_height, const unsigned int p_colours, const unsigned int p_subpixelorder);
|
2017-10-23 21:51:41 +08:00
|
|
|
// Is only acceptable on a pre-allocated buffer
|
|
|
|
uint8_t* WriteBuffer() { if ( holdbuffer ) return buffer; return NULL; };
|
2011-04-29 22:26:50 +08:00
|
|
|
|
2011-05-05 17:52:00 +08:00
|
|
|
inline int IsBufferHeld() const { return holdbuffer; }
|
|
|
|
inline void HoldBuffer(int tohold) { holdbuffer = tohold; }
|
2011-04-29 22:26:50 +08:00
|
|
|
|
|
|
|
inline void Empty() {
|
2017-08-11 03:44:20 +08:00
|
|
|
if ( !holdbuffer )
|
|
|
|
DumpImgBuffer();
|
|
|
|
|
2020-07-08 04:13:41 +08:00
|
|
|
width = linesize = height = colours = size = pixels = subpixelorder = 0;
|
2011-04-29 22:26:50 +08:00
|
|
|
}
|
|
|
|
|
2020-07-24 05:14:56 +08:00
|
|
|
void Assign(
|
|
|
|
unsigned int p_width,
|
|
|
|
unsigned int p_height,
|
|
|
|
unsigned int p_colours,
|
|
|
|
unsigned int p_subpixelorder,
|
|
|
|
const uint8_t* new_buffer,
|
|
|
|
const size_t buffer_size);
|
|
|
|
void Assign(const Image &image);
|
2020-08-08 05:52:43 +08:00
|
|
|
void Assign(const AVFrame *frame);
|
2020-07-24 05:14:56 +08:00
|
|
|
void AssignDirect(
|
|
|
|
const unsigned int p_width,
|
|
|
|
const unsigned int p_height,
|
|
|
|
const unsigned int p_colours,
|
|
|
|
const unsigned int p_subpixelorder,
|
|
|
|
uint8_t *new_buffer,
|
|
|
|
const size_t buffer_size,
|
|
|
|
const int p_buffertype);
|
2003-03-26 19:57:29 +08:00
|
|
|
|
2021-01-12 00:57:34 +08:00
|
|
|
int PopulateFrame(AVFrame *frame);
|
|
|
|
|
2020-07-24 05:14:56 +08:00
|
|
|
inline void CopyBuffer(const Image &image) {
|
2013-11-01 19:31:37 +08:00
|
|
|
Assign(image);
|
|
|
|
}
|
2020-07-24 05:14:56 +08:00
|
|
|
inline Image &operator=(const Image &image) {
|
2013-11-01 19:31:37 +08:00
|
|
|
Assign(image);
|
|
|
|
return *this;
|
2003-03-26 19:57:29 +08:00
|
|
|
}
|
2020-07-24 05:14:56 +08:00
|
|
|
inline Image &operator=(const unsigned char *new_buffer) {
|
2011-06-15 01:38:18 +08:00
|
|
|
(*fptr_imgbufcpy)(buffer, new_buffer, size);
|
2018-08-12 01:35:37 +08:00
|
|
|
return *this;
|
2003-03-26 19:57:29 +08:00
|
|
|
}
|
|
|
|
|
2005-11-30 01:51:06 +08:00
|
|
|
bool ReadRaw( const char *filename );
|
|
|
|
bool WriteRaw( const char *filename ) const;
|
|
|
|
|
2013-09-17 15:28:59 +08:00
|
|
|
bool ReadJpeg( const char *filename, unsigned int p_colours, unsigned int p_subpixelorder);
|
2015-07-24 07:34:39 +08:00
|
|
|
|
|
|
|
bool WriteJpeg ( const char *filename) const;
|
2019-05-17 03:37:03 +08:00
|
|
|
bool WriteJpeg ( const char *filename, bool on_blocking_abort) const;
|
2017-08-11 03:44:20 +08:00
|
|
|
bool WriteJpeg ( const char *filename, int quality_override ) const;
|
|
|
|
bool WriteJpeg ( const char *filename, struct timeval timestamp ) const;
|
|
|
|
bool WriteJpeg ( const char *filename, int quality_override, struct timeval timestamp ) const;
|
2019-05-17 03:37:03 +08:00
|
|
|
bool WriteJpeg ( const char *filename, int quality_override, struct timeval timestamp, bool on_blocking_abort ) const;
|
|
|
|
|
2015-07-24 07:34:39 +08:00
|
|
|
|
2013-09-17 15:28:59 +08:00
|
|
|
bool DecodeJpeg( const JOCTET *inbuffer, int inbuffer_size, unsigned int p_colours, unsigned int p_subpixelorder);
|
2005-11-19 01:26:12 +08:00
|
|
|
bool EncodeJpeg( JOCTET *outbuffer, int *outbuffer_size, int quality_override=0 ) const;
|
2003-03-26 19:57:29 +08:00
|
|
|
|
2009-03-20 20:39:29 +08:00
|
|
|
#if HAVE_ZLIB_H
|
2006-01-20 23:27:48 +08:00
|
|
|
bool Unzip( const Bytef *inbuffer, unsigned long inbuffer_size );
|
|
|
|
bool Zip( Bytef *outbuffer, unsigned long *outbuffer_size, int compression_level=Z_BEST_SPEED ) const;
|
2009-03-20 20:39:29 +08:00
|
|
|
#endif // HAVE_ZLIB_H
|
2006-01-20 23:27:48 +08:00
|
|
|
|
2013-09-17 15:28:59 +08:00
|
|
|
bool Crop( unsigned int lo_x, unsigned int lo_y, unsigned int hi_x, unsigned int hi_y );
|
2007-08-30 02:11:09 +08:00
|
|
|
bool Crop( const Box &limits );
|
2005-12-02 00:24:25 +08:00
|
|
|
|
2003-03-26 19:57:29 +08:00
|
|
|
void Overlay( const Image &image );
|
2013-09-17 15:28:59 +08:00
|
|
|
void Overlay( const Image &image, unsigned int x, unsigned int y );
|
2011-06-16 00:04:29 +08:00
|
|
|
void Blend( const Image &image, int transparency=12 );
|
2013-09-17 15:28:59 +08:00
|
|
|
static Image *Merge( unsigned int n_images, Image *images[] );
|
|
|
|
static Image *Merge( unsigned int n_images, Image *images[], double weight );
|
|
|
|
static Image *Highlight( unsigned int n_images, Image *images[], const Rgb threshold=RGB_BLACK, const Rgb ref_colour=RGB_RED );
|
2011-04-29 22:26:50 +08:00
|
|
|
//Image *Delta( const Image &image ) const;
|
2011-05-01 02:39:34 +08:00
|
|
|
void Delta( const Image &image, Image* targetimage) const;
|
2003-03-26 19:57:29 +08:00
|
|
|
|
2020-10-21 04:20:29 +08:00
|
|
|
const Coord centreCoord(const char *text, const int size) const;
|
2017-08-11 03:44:20 +08:00
|
|
|
void MaskPrivacy( const unsigned char *p_bitmask, const Rgb pixel_colour=0x00222222 );
|
2015-10-02 21:49:09 +08:00
|
|
|
void Annotate( const char *p_text, const Coord &coord, const unsigned int size=1, const Rgb fg_colour=RGB_WHITE, const Rgb bg_colour=RGB_BLACK );
|
2013-09-17 15:28:59 +08:00
|
|
|
Image *HighlightEdges( Rgb colour, unsigned int p_colours, unsigned int p_subpixelorder, const Box *limits=0 );
|
2005-12-21 08:13:23 +08:00
|
|
|
//Image *HighlightEdges( Rgb colour, const Polygon &polygon );
|
2015-08-10 17:11:54 +08:00
|
|
|
void Timestamp( const char *label, const time_t when, const Coord &coord, const int size );
|
2013-09-17 15:28:59 +08:00
|
|
|
void Colourise(const unsigned int p_reqcolours, const unsigned int p_reqsubpixelorder);
|
2003-03-26 19:57:29 +08:00
|
|
|
void DeColourise();
|
|
|
|
|
|
|
|
void Clear() { memset( buffer, 0, size ); }
|
|
|
|
void Fill( Rgb colour, const Box *limits=0 );
|
2005-11-30 01:51:06 +08:00
|
|
|
void Fill( Rgb colour, int density, const Box *limits=0 );
|
|
|
|
void Outline( Rgb colour, const Polygon &polygon );
|
|
|
|
void Fill( Rgb colour, const Polygon &polygon );
|
|
|
|
void Fill( Rgb colour, int density, const Polygon &polygon );
|
2003-03-26 19:57:29 +08:00
|
|
|
|
2003-05-02 23:03:16 +08:00
|
|
|
void Rotate( int angle );
|
2005-05-06 00:42:37 +08:00
|
|
|
void Flip( bool leftright );
|
2004-02-16 03:47:23 +08:00
|
|
|
void Scale( unsigned int factor );
|
2012-07-15 22:30:37 +08:00
|
|
|
|
2012-01-25 22:59:56 +08:00
|
|
|
void Deinterlace_Discard();
|
|
|
|
void Deinterlace_Linear();
|
2012-01-30 14:00:22 +08:00
|
|
|
void Deinterlace_Blend();
|
|
|
|
void Deinterlace_Blend_CustomRatio(int divider);
|
|
|
|
void Deinterlace_4Field(const Image* next_image, unsigned int threshold);
|
2012-01-25 22:59:56 +08:00
|
|
|
|
2003-03-26 19:57:29 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif // ZM_IMAGE_H
|
2011-04-29 22:26:50 +08:00
|
|
|
|
2011-05-01 02:39:34 +08:00
|
|
|
/* Blend functions */
|
2011-05-05 17:52:00 +08:00
|
|
|
void sse2_fastblend(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count, double blendpercent);
|
|
|
|
void std_fastblend(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count, double blendpercent);
|
2017-03-19 19:31:44 +08:00
|
|
|
void neon32_armv7_fastblend(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count, double blendpercent);
|
2017-05-13 03:59:08 +08:00
|
|
|
void neon64_armv8_fastblend(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count, double blendpercent);
|
2011-05-05 17:52:00 +08:00
|
|
|
void std_blend(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count, double blendpercent);
|
2011-05-01 02:39:34 +08:00
|
|
|
|
|
|
|
/* Delta functions */
|
2011-05-05 17:52:00 +08:00
|
|
|
void std_delta8_gray8(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count);
|
|
|
|
void std_delta8_rgb(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count);
|
|
|
|
void std_delta8_bgr(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count);
|
|
|
|
void std_delta8_rgba(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count);
|
|
|
|
void std_delta8_bgra(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count);
|
|
|
|
void std_delta8_argb(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count);
|
|
|
|
void std_delta8_abgr(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count);
|
2018-10-22 22:41:27 +08:00
|
|
|
|
2019-02-22 22:44:57 +08:00
|
|
|
void fast_delta8_gray8(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count);
|
|
|
|
void fast_delta8_rgb(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count);
|
|
|
|
void fast_delta8_bgr(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count);
|
|
|
|
void fast_delta8_rgba(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count);
|
|
|
|
void fast_delta8_bgra(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count);
|
|
|
|
void fast_delta8_argb(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count);
|
|
|
|
void fast_delta8_abgr(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count);
|
|
|
|
|
2017-03-19 19:39:24 +08:00
|
|
|
void neon32_armv7_delta8_gray8(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count);
|
|
|
|
void neon32_armv7_delta8_rgba(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count);
|
|
|
|
void neon32_armv7_delta8_bgra(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count);
|
|
|
|
void neon32_armv7_delta8_argb(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count);
|
|
|
|
void neon32_armv7_delta8_abgr(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count);
|
2017-05-13 14:19:13 +08:00
|
|
|
void neon64_armv8_delta8_gray8(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count);
|
|
|
|
void neon64_armv8_delta8_rgba(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count);
|
|
|
|
void neon64_armv8_delta8_bgra(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count);
|
|
|
|
void neon64_armv8_delta8_argb(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count);
|
|
|
|
void neon64_armv8_delta8_abgr(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count);
|
2011-05-05 17:52:00 +08:00
|
|
|
void sse2_delta8_gray8(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count);
|
2011-05-23 20:52:33 +08:00
|
|
|
void sse2_delta8_rgba(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count);
|
|
|
|
void sse2_delta8_bgra(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count);
|
|
|
|
void sse2_delta8_argb(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count);
|
|
|
|
void sse2_delta8_abgr(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count);
|
2011-05-05 17:52:00 +08:00
|
|
|
void ssse3_delta8_rgba(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count);
|
|
|
|
void ssse3_delta8_bgra(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count);
|
|
|
|
void ssse3_delta8_argb(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count);
|
|
|
|
void ssse3_delta8_abgr(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count);
|
|
|
|
|
|
|
|
/* Convert functions */
|
2011-06-08 04:14:01 +08:00
|
|
|
void std_convert_rgb_gray8(const uint8_t* col1, uint8_t* result, unsigned long count);
|
|
|
|
void std_convert_bgr_gray8(const uint8_t* col1, uint8_t* result, unsigned long count);
|
2011-05-05 17:52:00 +08:00
|
|
|
void std_convert_rgba_gray8(const uint8_t* col1, uint8_t* result, unsigned long count);
|
|
|
|
void std_convert_bgra_gray8(const uint8_t* col1, uint8_t* result, unsigned long count);
|
|
|
|
void std_convert_argb_gray8(const uint8_t* col1, uint8_t* result, unsigned long count);
|
|
|
|
void std_convert_abgr_gray8(const uint8_t* col1, uint8_t* result, unsigned long count);
|
|
|
|
void std_convert_yuyv_gray8(const uint8_t* col1, uint8_t* result, unsigned long count);
|
2019-02-22 22:44:57 +08:00
|
|
|
|
|
|
|
void fast_convert_rgb_gray8(const uint8_t* col1, uint8_t* result, unsigned long count);
|
|
|
|
void fast_convert_bgr_gray8(const uint8_t* col1, uint8_t* result, unsigned long count);
|
|
|
|
void fast_convert_rgba_gray8(const uint8_t* col1, uint8_t* result, unsigned long count);
|
|
|
|
void fast_convert_bgra_gray8(const uint8_t* col1, uint8_t* result, unsigned long count);
|
|
|
|
void fast_convert_argb_gray8(const uint8_t* col1, uint8_t* result, unsigned long count);
|
|
|
|
void fast_convert_abgr_gray8(const uint8_t* col1, uint8_t* result, unsigned long count);
|
|
|
|
void fast_convert_yuyv_gray8(const uint8_t* col1, uint8_t* result, unsigned long count);
|
|
|
|
|
2011-05-05 17:52:00 +08:00
|
|
|
void ssse3_convert_rgba_gray8(const uint8_t* col1, uint8_t* result, unsigned long count);
|
2017-03-15 04:29:55 +08:00
|
|
|
void ssse3_convert_bgra_gray8(const uint8_t* col1, uint8_t* result, unsigned long count);
|
|
|
|
void ssse3_convert_argb_gray8(const uint8_t* col1, uint8_t* result, unsigned long count);
|
|
|
|
void ssse3_convert_abgr_gray8(const uint8_t* col1, uint8_t* result, unsigned long count);
|
2011-05-05 17:52:00 +08:00
|
|
|
void ssse3_convert_yuyv_gray8(const uint8_t* col1, uint8_t* result, unsigned long count);
|
|
|
|
void zm_convert_yuyv_rgb(const uint8_t* col1, uint8_t* result, unsigned long count);
|
|
|
|
void zm_convert_yuyv_rgba(const uint8_t* col1, uint8_t* result, unsigned long count);
|
|
|
|
void zm_convert_rgb555_rgb(const uint8_t* col1, uint8_t* result, unsigned long count);
|
|
|
|
void zm_convert_rgb555_rgba(const uint8_t* col1, uint8_t* result, unsigned long count);
|
|
|
|
void zm_convert_rgb565_rgb(const uint8_t* col1, uint8_t* result, unsigned long count);
|
|
|
|
void zm_convert_rgb565_rgba(const uint8_t* col1, uint8_t* result, unsigned long count);
|
|
|
|
|
2012-07-15 22:30:37 +08:00
|
|
|
/* Deinterlace_4Field functions */
|
|
|
|
void std_deinterlace_4field_gray8(uint8_t* col1, uint8_t* col2, unsigned int threshold, unsigned int width, unsigned int height);
|
|
|
|
void std_deinterlace_4field_rgb(uint8_t* col1, uint8_t* col2, unsigned int threshold, unsigned int width, unsigned int height);
|
|
|
|
void std_deinterlace_4field_bgr(uint8_t* col1, uint8_t* col2, unsigned int threshold, unsigned int width, unsigned int height);
|
|
|
|
void std_deinterlace_4field_rgba(uint8_t* col1, uint8_t* col2, unsigned int threshold, unsigned int width, unsigned int height);
|
|
|
|
void std_deinterlace_4field_bgra(uint8_t* col1, uint8_t* col2, unsigned int threshold, unsigned int width, unsigned int height);
|
|
|
|
void std_deinterlace_4field_argb(uint8_t* col1, uint8_t* col2, unsigned int threshold, unsigned int width, unsigned int height);
|
|
|
|
void std_deinterlace_4field_abgr(uint8_t* col1, uint8_t* col2, unsigned int threshold, unsigned int width, unsigned int height);
|