You've already forked M5Stack_Linux_Libs
mirror of
https://github.com/m5stack/M5Stack_Linux_Libs.git
synced 2026-05-20 11:01:38 -07:00
1614 lines
61 KiB
C
1614 lines
61 KiB
C
/*
|
||
* This file is part of the OpenMV project.
|
||
*
|
||
* Copyright (c) 2013-2021 Ibrahim Abdelkader <iabdalkader@openmv.io>
|
||
* Copyright (c) 2013-2021 Kwabena W. Agyeman <kwagyeman@openmv.io>
|
||
*
|
||
* This work is licensed under the MIT license, see the file LICENSE for details.
|
||
*
|
||
* Image processing library.
|
||
*/
|
||
#ifndef __IMLIB_H__
|
||
#define __IMLIB_H__
|
||
#include <stdbool.h>
|
||
#include <stddef.h>
|
||
#include <stdlib.h>
|
||
#include <stdint.h>
|
||
#include <string.h>
|
||
#include <limits.h>
|
||
#include <float.h>
|
||
#include <math.h>
|
||
// #include <arm_math.h>
|
||
// #include <ff.h>
|
||
#include "fb_alloc.h"
|
||
#include "umm_malloc.h"
|
||
#include "xalloc.h"
|
||
#include "array.h"
|
||
#include "fmath.h"
|
||
#include "collections.h"
|
||
#include "imlib_config.h"
|
||
#include "omv_boardconfig.h"
|
||
#include "ff_wrapper.h"
|
||
#include "imlib_io.h"
|
||
|
||
#ifdef __cplusplus
|
||
extern "C"
|
||
{
|
||
#endif
|
||
|
||
#ifndef M_PI
|
||
#define M_PI 3.14159265f
|
||
#define M_PI_2 1.57079632f
|
||
#define M_PI_4 0.78539816f
|
||
#endif
|
||
|
||
#define IM_LOG2_2(x) (((x) & 0x2ULL) ? ( 2 ) : 1) // NO ({ ... }) !
|
||
#define IM_LOG2_4(x) (((x) & 0xCULL) ? ( 2 + IM_LOG2_2((x) >> 2)) : IM_LOG2_2(x)) // NO ({ ... }) !
|
||
#define IM_LOG2_8(x) (((x) & 0xF0ULL) ? ( 4 + IM_LOG2_4((x) >> 4)) : IM_LOG2_4(x)) // NO ({ ... }) !
|
||
#define IM_LOG2_16(x) (((x) & 0xFF00ULL) ? ( 8 + IM_LOG2_8((x) >> 8)) : IM_LOG2_8(x)) // NO ({ ... }) !
|
||
#define IM_LOG2_32(x) (((x) & 0xFFFF0000ULL) ? (16 + IM_LOG2_16((x) >> 16)) : IM_LOG2_16(x)) // NO ({ ... }) !
|
||
#define IM_LOG2(x) (((x) & 0xFFFFFFFF00000000ULL) ? (32 + IM_LOG2_32((x) >> 32)) : IM_LOG2_32(x)) // NO ({ ... }) !
|
||
|
||
#define IM_MAX(a,b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _a > _b ? _a : _b; })
|
||
#define IM_MIN(a,b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _a < _b ? _a : _b; })
|
||
#define IM_DIV(a,b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _b ? (_a / _b) : 0; })
|
||
#define IM_MOD(a,b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _b ? (_a % _b) : 0; })
|
||
#define IM_LIMIT(a, min_b, max_c) ({__typeof__ (a) _a = (a);__typeof__ (min_b) _min_b = (min_b);__typeof__ (max_c) _max_c = (max_c); _a = _a > max_c ? max_c : _a;_a < min_b ? min_b : _a;})
|
||
|
||
#define INT8_T_BITS (sizeof(int8_t) * 8)
|
||
#define INT8_T_MASK (INT8_T_BITS - 1)
|
||
#define INT8_T_SHIFT IM_LOG2(INT8_T_MASK)
|
||
|
||
#define INT16_T_BITS (sizeof(int16_t) * 8)
|
||
#define INT16_T_MASK (INT16_T_BITS - 1)
|
||
#define INT16_T_SHIFT IM_LOG2(INT16_T_MASK)
|
||
|
||
#define INT32_T_BITS (sizeof(int32_t) * 8)
|
||
#define INT32_T_MASK (INT32_T_BITS - 1)
|
||
#define INT32_T_SHIFT IM_LOG2(INT32_T_MASK)
|
||
|
||
#define INT64_T_BITS (sizeof(int64_t) * 8)
|
||
#define INT64_T_MASK (INT64_T_BITS - 1)
|
||
#define INT64_T_SHIFT IM_LOG2(INT64_T_MASK)
|
||
|
||
#define UINT8_T_BITS (sizeof(uint8_t) * 8)
|
||
#define UINT8_T_MASK (UINT8_T_BITS - 1)
|
||
#define UINT8_T_SHIFT IM_LOG2(UINT8_T_MASK)
|
||
|
||
#define UINT16_T_BITS (sizeof(uint16_t) * 8)
|
||
#define UINT16_T_MASK (UINT16_T_BITS - 1)
|
||
#define UINT16_T_SHIFT IM_LOG2(UINT16_T_MASK)
|
||
|
||
#define UINT32_T_BITS (sizeof(uint32_t) * 8)
|
||
#define UINT32_T_MASK (UINT32_T_BITS - 1)
|
||
#define UINT32_T_SHIFT IM_LOG2(UINT32_T_MASK)
|
||
|
||
#define UINT64_T_BITS (sizeof(uint64_t) * 8)
|
||
#define UINT64_T_MASK (UINT64_T_BITS - 1)
|
||
#define UINT64_T_SHIFT IM_LOG2(UINT64_T_MASK)
|
||
|
||
#define IM_DEG2RAD(x) (((x)*M_PI)/180)
|
||
#define IM_RAD2DEG(x) (((x)*180)/M_PI)
|
||
|
||
|
||
/////////////////
|
||
// pixel Stuff //
|
||
/////////////////
|
||
|
||
|
||
|
||
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||
// ARGB
|
||
|
||
typedef struct pixel_s {
|
||
char blue;
|
||
char green;
|
||
char red;
|
||
} pixel24_t;
|
||
|
||
#define pixel24232(_u24_t) \
|
||
({\
|
||
__typeof__ (_u24_t) ___u24_t = _u24_t;\
|
||
((*((uint32_t*)((void*)&___u24_t))) & 0xffffff00);\
|
||
})
|
||
//input_ uint32_t,output pixel24_t
|
||
#define pixel32224(_u32_t) \
|
||
({\
|
||
__typeof__ (_u32_t) __u32_t = _u32_t;\
|
||
__u32_t = __u32_t >> 8;\
|
||
(*((pixel24_t*)((void*)&__u32_t)));\
|
||
})
|
||
void nihao()
|
||
{
|
||
printf("t am __ORDER_BIG_ENDIAN__ \n");
|
||
}
|
||
#else
|
||
//cpu is little
|
||
//input pixel24_t,output uint32_t
|
||
// BGRA
|
||
|
||
typedef struct pixel_s {
|
||
uint8_t red;
|
||
uint8_t green;
|
||
uint8_t blue;
|
||
} pixel24_t;
|
||
|
||
#define pixel24232(_u24_t) \
|
||
({\
|
||
__typeof__ (_u24_t) ___u24_t = _u24_t;\
|
||
((*((uint32_t*)&___u24_t)) & 0x00ffffff);\
|
||
})
|
||
//input_ uint32_t,output pixel24_t
|
||
#define pixel32224(_u32_t) \
|
||
({\
|
||
__typeof__ (_u32_t) __u32_t = _u32_t;\
|
||
(*((pixel24_t*)&__u32_t));\
|
||
})
|
||
#endif //__BYTE_ORDER__
|
||
|
||
|
||
|
||
/////////////////
|
||
// Point Stuff //
|
||
/////////////////
|
||
|
||
typedef struct point {
|
||
int16_t x;
|
||
int16_t y;
|
||
} point_t;
|
||
|
||
void point_init(point_t *ptr, int x, int y);
|
||
void point_copy(point_t *dst, point_t *src);
|
||
bool point_equal_fast(point_t *ptr0, point_t *ptr1);
|
||
int point_quadrance(point_t *ptr0, point_t *ptr1);
|
||
int point_quadrance_i(point_t *ptr0, point_t *ptr1);
|
||
void point_rotate(int x, int y, float r, int center_x, int center_y, int16_t *new_x, int16_t *new_y);
|
||
void point_min_area_rectangle(point_t *corners, point_t *new_corners, int corners_len);
|
||
|
||
////////////////
|
||
// Line Stuff //
|
||
////////////////
|
||
|
||
typedef struct line {
|
||
int16_t x1;
|
||
int16_t y1;
|
||
int16_t x2;
|
||
int16_t y2;
|
||
} line_t;
|
||
|
||
bool lb_clip_line(line_t *l, int x, int y, int w, int h);
|
||
|
||
/////////////////////
|
||
// Rectangle Stuff //
|
||
/////////////////////
|
||
|
||
typedef struct rectangle {
|
||
int16_t x;
|
||
int16_t y;
|
||
int16_t w;
|
||
int16_t h;
|
||
} rectangle_t;
|
||
|
||
void rectangle_init(rectangle_t *ptr, int x, int y, int w, int h);
|
||
void rectangle_copy(rectangle_t *dst, rectangle_t *src);
|
||
bool rectangle_equal_fast(rectangle_t *ptr0, rectangle_t *ptr1);
|
||
bool rectangle_overlap(rectangle_t *ptr0, rectangle_t *ptr1);
|
||
void rectangle_intersected(rectangle_t *dst, rectangle_t *src);
|
||
void rectangle_united(rectangle_t *dst, rectangle_t *src);
|
||
|
||
/////////////////
|
||
// Color Stuff //
|
||
/////////////////
|
||
|
||
typedef struct color_thresholds_list_lnk_data
|
||
{
|
||
uint8_t LMin, LMax; // or grayscale
|
||
int8_t AMin, AMax;
|
||
int8_t BMin, BMax;
|
||
}
|
||
color_thresholds_list_lnk_data_t;
|
||
|
||
#define COLOR_THRESHOLD_BINARY(pixel, threshold, invert) \
|
||
({ \
|
||
__typeof__ (pixel) _pixel = (pixel); \
|
||
__typeof__ (threshold) _threshold = (threshold); \
|
||
__typeof__ (invert) _invert = (invert); \
|
||
((_threshold->LMin <= _pixel) && (_pixel <= _threshold->LMax)) ^ _invert; \
|
||
})
|
||
|
||
#define COLOR_THRESHOLD_GRAYSCALE(pixel, threshold, invert) \
|
||
({ \
|
||
__typeof__ (pixel) _pixel = (pixel); \
|
||
__typeof__ (threshold) _threshold = (threshold); \
|
||
__typeof__ (invert) _invert = (invert); \
|
||
((_threshold->LMin <= _pixel) && (_pixel <= _threshold->LMax)) ^ _invert; \
|
||
})
|
||
|
||
#define COLOR_THRESHOLD_RGB565(pixel, threshold, invert) \
|
||
({ \
|
||
__typeof__ (pixel) _pixel = (pixel); \
|
||
__typeof__ (threshold) _threshold = (threshold); \
|
||
__typeof__ (invert) _invert = (invert); \
|
||
uint8_t _l = COLOR_RGB565_TO_L(_pixel); \
|
||
int8_t _a = COLOR_RGB565_TO_A(_pixel); \
|
||
int8_t _b = COLOR_RGB565_TO_B(_pixel); \
|
||
((_threshold->LMin <= _l) && (_l <= _threshold->LMax) && \
|
||
(_threshold->AMin <= _a) && (_a <= _threshold->AMax) && \
|
||
(_threshold->BMin <= _b) && (_b <= _threshold->BMax)) ^ _invert; \
|
||
})
|
||
#define COLOR_THRESHOLD_RGB888(pixel, threshold, invert) \
|
||
({\
|
||
__typeof__(pixel) _pixel = (pixel); \
|
||
__typeof__(threshold) _threshold = (threshold); \
|
||
__typeof__(invert) _invert = (invert); \
|
||
uint8_t _l = COLOR_RGB888_TO_L(_pixel); \
|
||
int8_t _a = COLOR_RGB888_TO_A(_pixel); \
|
||
int8_t _b = COLOR_RGB888_TO_B(_pixel); \
|
||
((_threshold->LMin <= _l) && (_l <= _threshold->LMax) && \
|
||
(_threshold->AMin <= _a) && (_a <= _threshold->AMax) && \
|
||
(_threshold->BMin <= _b) && (_b <= _threshold->BMax)) ^ _invert; \
|
||
})
|
||
#define COLOR_THRESHOLD_LAB(pixel, threshold, invert) \
|
||
({\
|
||
__typeof__(pixel) _pixel = (pixel); \
|
||
__typeof__(threshold) _threshold = (threshold); \
|
||
__typeof__(invert) _invert = (invert); \
|
||
((_threshold->LMin <= _pixel->L) && (_pixel->L <= _threshold->LMax) && \
|
||
(_threshold->AMin <= _pixel->A) && (_pixel->A <= _threshold->AMax) && \
|
||
(_threshold->BMin <= _pixel->B) && (_pixel->B <= _threshold->BMax)) ^ _invert; \
|
||
})
|
||
#define COLOR_BOUND_BINARY(pixel0, pixel1, threshold) \
|
||
({ \
|
||
__typeof__ (pixel0) _pixel0 = (pixel0); \
|
||
__typeof__ (pixel1) _pixel1 = (pixel1); \
|
||
__typeof__ (threshold) _threshold = (threshold); \
|
||
(abs(_pixel0 - _pixel1) <= _threshold); \
|
||
})
|
||
|
||
#define COLOR_BOUND_GRAYSCALE(pixel0, pixel1, threshold) \
|
||
({ \
|
||
__typeof__ (pixel0) _pixel0 = (pixel0); \
|
||
__typeof__ (pixel1) _pixel1 = (pixel1); \
|
||
__typeof__ (threshold) _threshold = (threshold); \
|
||
(abs(_pixel0 - _pixel1) <= _threshold); \
|
||
})
|
||
|
||
#define COLOR_BOUND_RGB565(pixel0, pixel1, threshold) \
|
||
({ \
|
||
__typeof__ (pixel0) _pixel0 = (pixel0); \
|
||
__typeof__ (pixel1) _pixel1 = (pixel1); \
|
||
__typeof__ (threshold) _threshold = (threshold); \
|
||
(abs(COLOR_RGB565_TO_R5(_pixel0) - COLOR_RGB565_TO_R5(_pixel1)) <= COLOR_RGB565_TO_R5(_threshold)) && \
|
||
(abs(COLOR_RGB565_TO_G6(_pixel0) - COLOR_RGB565_TO_G6(_pixel1)) <= COLOR_RGB565_TO_G6(_threshold)) && \
|
||
(abs(COLOR_RGB565_TO_B5(_pixel0) - COLOR_RGB565_TO_B5(_pixel1)) <= COLOR_RGB565_TO_B5(_threshold)); \
|
||
})
|
||
#define COLOR_BOUND_RGB888(pixel0, pixel1, threshold) \
|
||
({ \
|
||
__typeof__(pixel0) _pixel0 = (pixel0); \
|
||
__typeof__(pixel1) _pixel1 = (pixel1); \
|
||
__typeof__(threshold) _threshold = (threshold); \
|
||
(abs(COLOR_RGB888_TO_R8(_pixel0) - COLOR_RGB888_TO_R8(_pixel1)) <= COLOR_RGB888_TO_R8(_threshold)) && \
|
||
(abs(COLOR_RGB888_TO_G8(_pixel0) - COLOR_RGB888_TO_G8(_pixel1)) <= COLOR_RGB888_TO_G8(_threshold)) && \
|
||
(abs(COLOR_RGB888_TO_B8(_pixel0) - COLOR_RGB888_TO_B8(_pixel1)) <= COLOR_RGB888_TO_B8(_threshold)); \
|
||
})
|
||
#define COLOR_BINARY_MIN 0
|
||
#define COLOR_BINARY_MAX 1
|
||
#define COLOR_GRAYSCALE_BINARY_MIN 0x00
|
||
#define COLOR_GRAYSCALE_BINARY_MAX 0xFF
|
||
#define COLOR_RGB565_BINARY_MIN 0x0000
|
||
#define COLOR_RGB565_BINARY_MAX 0xFFFF
|
||
#define COLOR_RGB888_BINARY_MIN 0x000000
|
||
#define COLOR_RGB888_BINARY_MAX 0xFFFFFF
|
||
|
||
#define COLOR_GRAYSCALE_MIN 0
|
||
#define COLOR_GRAYSCALE_MAX 255
|
||
|
||
#define COLOR_R5_MIN 0
|
||
#define COLOR_R5_MAX 31
|
||
#define COLOR_G6_MIN 0
|
||
#define COLOR_G6_MAX 63
|
||
#define COLOR_B5_MIN 0
|
||
#define COLOR_B5_MAX 31
|
||
|
||
#define COLOR_R8_MIN 0
|
||
#define COLOR_R8_MAX 255
|
||
#define COLOR_G8_MIN 0
|
||
#define COLOR_G8_MAX 255
|
||
#define COLOR_B8_MIN 0
|
||
#define COLOR_B8_MAX 255
|
||
|
||
#define COLOR_L_MIN 0
|
||
#define COLOR_L_MAX 100
|
||
#define COLOR_A_MIN -128
|
||
#define COLOR_A_MAX 127
|
||
#define COLOR_B_MIN -128
|
||
#define COLOR_B_MAX 127
|
||
|
||
#define COLOR_Y_MIN 0
|
||
#define COLOR_Y_MAX 255
|
||
#define COLOR_U_MIN -128
|
||
#define COLOR_U_MAX 127
|
||
#define COLOR_V_MIN -128
|
||
#define COLOR_V_MAX 127
|
||
|
||
// RGB565 Stuff //
|
||
|
||
#define COLOR_RGB565_TO_R5(pixel) (((pixel) >> 11) & 0x1F)
|
||
#define COLOR_RGB565_TO_R8(pixel) \
|
||
({ \
|
||
__typeof__ (pixel) __pixel = (pixel); \
|
||
__pixel = (__pixel >> 8) & 0xF8; \
|
||
__pixel | (__pixel >> 5); \
|
||
})
|
||
|
||
#define COLOR_RGB565_TO_G6(pixel) (((pixel) >> 5) & 0x3F)
|
||
#define COLOR_RGB565_TO_G8(pixel) \
|
||
({ \
|
||
__typeof__ (pixel) __pixel = (pixel); \
|
||
__pixel = (__pixel >> 3) & 0xFC; \
|
||
__pixel | (__pixel >> 6); \
|
||
})
|
||
|
||
#define COLOR_RGB565_TO_B5(pixel) ((pixel) & 0x1F)
|
||
#define COLOR_RGB565_TO_B8(pixel) \
|
||
({ \
|
||
__typeof__ (pixel) __pixel = (pixel); \
|
||
__pixel = (__pixel << 3) & 0xF8; \
|
||
__pixel | (__pixel >> 5); \
|
||
})
|
||
|
||
#define COLOR_RGB888_TO_R8(pixel) pixel32224(pixel).red
|
||
#define COLOR_RGB888_TO_G8(pixel) pixel32224(pixel).green
|
||
#define COLOR_RGB888_TO_B8(pixel) pixel32224(pixel).blue
|
||
|
||
#define COLOR_R5_G6_B5_TO_RGB565(r5, g6, b5) (((r5) << 11) | ((g6) << 5) | (b5))
|
||
#define COLOR_R8_G8_B8_TO_RGB565(r8, g8, b8) ((((r8) & 0xF8) << 8) | (((g8) & 0xFC) << 3) | ((b8) >> 3))
|
||
|
||
#define COLOR_R8_G8_B8_TO_RGB888(r8, g8, b8) pixel24232(((pixel24_t){.red = r8,.green = g8, .blue = b8}))
|
||
|
||
#define COLOR_RGB888_TO_Y_(r8, g8, b8) ((((r8) * 38) + ((g8) * 75) + ((b8) * 15)) >> 7) // 0.299R + 0.587G + 0.114B
|
||
|
||
#define COLOR_RGB888_TO_Y(rgb888) COLOR_RGB888_TO_Y_(COLOR_RGB888_TO_R8(rgb888), COLOR_RGB888_TO_G8(rgb888), COLOR_RGB888_TO_B8(rgb888)) // 0.299R + 0.587G + 0.114B
|
||
|
||
#define COLOR_RGB565_TO_Y(rgb565) \
|
||
({ \
|
||
__typeof__ (rgb565) __rgb565 = (rgb565); \
|
||
int r = COLOR_RGB565_TO_R8(__rgb565); \
|
||
int g = COLOR_RGB565_TO_G8(__rgb565); \
|
||
int b = COLOR_RGB565_TO_B8(__rgb565); \
|
||
COLOR_RGB888_TO_Y_(r, g, b); \
|
||
})
|
||
|
||
#define COLOR_Y_TO_RGB888(pixel) ((pixel) * 0x010101)
|
||
#define COLOR_Y_TO_RGB565(pixel) \
|
||
({ \
|
||
__typeof__ (pixel) __pixel = (pixel); \
|
||
int __rb_pixel = (__pixel >> 3) & 0x1F; \
|
||
(__rb_pixel * 0x0801) + ((__pixel << 3) & 0x7E0); \
|
||
})
|
||
#define COLOR_RGB888_TO_U_(r8, g8, b8) ((((r8) * -21) - ((g8) * 43) + ((b8) * 64)) >> 7) // -0.168736R - 0.331264G + 0.5B
|
||
#define COLOR_RGB888_TO_U(rgb888) COLOR_RGB888_TO_U_(COLOR_RGB888_TO_R8(rgb888), COLOR_RGB888_TO_G8(rgb888), COLOR_RGB888_TO_B8(rgb888)) // -0.168736R - 0.331264G + 0.5B
|
||
#define COLOR_RGB565_TO_U(rgb565) \
|
||
({ \
|
||
__typeof__ (rgb565) __rgb565 = (rgb565); \
|
||
int r = COLOR_RGB565_TO_R8(__rgb565); \
|
||
int g = COLOR_RGB565_TO_G8(__rgb565); \
|
||
int b = COLOR_RGB565_TO_B8(__rgb565); \
|
||
COLOR_RGB888_TO_U_(r, g, b); \
|
||
})
|
||
#define COLOR_RGB888_TO_V_(r8, g8, b8) ((((r8) * 64) - ((g8) * 54) - ((b8) * 10)) >> 7) // 0.5R - 0.418688G - 0.081312B
|
||
#define COLOR_RGB888_TO_V(rgb888) COLOR_RGB888_TO_V_(COLOR_RGB888_TO_R8(rgb888), COLOR_RGB888_TO_G8(rgb888), COLOR_RGB888_TO_B8(rgb888)) // 0.5R - 0.418688G - 0.081312B
|
||
#define COLOR_RGB565_TO_V(rgb565) \
|
||
({ \
|
||
__typeof__ (rgb565) __rgb565 = (rgb565); \
|
||
int r = COLOR_RGB565_TO_R8(__rgb565); \
|
||
int g = COLOR_RGB565_TO_G8(__rgb565); \
|
||
int b = COLOR_RGB565_TO_B8(__rgb565); \
|
||
COLOR_RGB888_TO_V_(r, g, b); \
|
||
})
|
||
|
||
|
||
|
||
#ifdef IMLIB_ENABLE_LAB_LUT
|
||
extern const int8_t lab_table[196608/2];
|
||
#define COLOR_RGB565_TO_L(pixel) lab_table[((pixel>>1) * 3) + 0]
|
||
#define COLOR_RGB565_TO_A(pixel) lab_table[((pixel>>1) * 3) + 1]
|
||
#define COLOR_RGB565_TO_B(pixel) lab_table[((pixel>>1) * 3) + 2]
|
||
#else
|
||
#define COLOR_RGB565_TO_L(pixel) imlib_rgb565_to_l(pixel)
|
||
#define COLOR_RGB565_TO_A(pixel) imlib_rgb565_to_a(pixel)
|
||
#define COLOR_RGB565_TO_B(pixel) imlib_rgb565_to_b(pixel)
|
||
#define COLOR_RGB888_TO_L(pixel) imlib_rgb888_to_l(pixel)
|
||
#define COLOR_RGB888_TO_A(pixel) imlib_rgb888_to_a(pixel)
|
||
#define COLOR_RGB888_TO_B(pixel) imlib_rgb888_to_b(pixel)
|
||
#endif
|
||
|
||
#define COLOR_LAB_TO_RGB565(l, a, b) imlib_lab_to_rgb(l, a, b)
|
||
#define COLOR_YUV_TO_RGB565(y, u, v) imlib_yuv_to_rgb((y) + 128, u, v)
|
||
|
||
#define COLOR_LAB_TO_RGB888(l, a, b) imlib_lab_to_rgb888(l, a, b)
|
||
#define COLOR_YUV_TO_RGB888(y, u, v) imlib_yuv_to_rgb888((y) + 128, u, v)
|
||
|
||
#define COLOR_BINARY_TO_GRAYSCALE(pixel) ((pixel) * COLOR_GRAYSCALE_MAX)
|
||
#define COLOR_BINARY_TO_RGB565(pixel) COLOR_YUV_TO_RGB565(((pixel) ? 127 : -128), 0, 0)
|
||
#define COLOR_BINARY_TO_RGB888(pixel) COLOR_YUV_TO_RGB888(((pixel) ? 127 : -128), 0, 0)
|
||
#define COLOR_RGB565_TO_BINARY(pixel) (COLOR_RGB565_TO_Y(pixel) > (((COLOR_Y_MAX - COLOR_Y_MIN) / 2) + COLOR_Y_MIN))
|
||
#define COLOR_RGB565_TO_GRAYSCALE(pixel) COLOR_RGB565_TO_Y(pixel)
|
||
#define COLOR_RGB565_TO_RGB888(pixel) COLOR_R8_G8_B8_TO_RGB888(COLOR_RGB565_TO_R8(pixel), COLOR_RGB565_TO_G8(pixel), COLOR_RGB565_TO_B8(pixel))
|
||
#define COLOR_RGB888_TO_GRAYSCALE(pixel) COLOR_RGB888_TO_Y(pixel)
|
||
#define COLOR_RGB888_TO_BINARY(pixel) (COLOR_RGB888_TO_Y(pixel) > (((COLOR_Y_MAX - COLOR_Y_MIN) / 2) + COLOR_Y_MIN))
|
||
#define COLOR_RGB888_TO_RGB565(pixel) COLOR_R8_G8_B8_TO_RGB565(COLOR_RGB888_TO_R8(pixel), COLOR_RGB888_TO_G8(pixel), COLOR_RGB888_TO_B8(pixel))
|
||
|
||
#define COLOR_GRAYSCALE_TO_BINARY(pixel) ((pixel) > (((COLOR_GRAYSCALE_MAX - COLOR_GRAYSCALE_MIN) / 2) + COLOR_GRAYSCALE_MIN))
|
||
#define COLOR_GRAYSCALE_TO_RGB565(pixel) COLOR_YUV_TO_RGB565(((pixel) - 128), 0, 0)
|
||
#define COLOR_GRAYSCALE_TO_RGB888(pixel) COLOR_YUV_TO_RGB888(((pixel) - 128), 0, 0)
|
||
|
||
typedef enum {
|
||
COLOR_PALETTE_RAINBOW,
|
||
COLOR_PALETTE_IRONBOW
|
||
} color_palette_t;
|
||
|
||
// Color palette LUTs
|
||
extern const uint16_t rainbow_table[256];
|
||
extern const uint16_t ironbow_table[256];
|
||
|
||
/////////////////
|
||
// Image Stuff //
|
||
/////////////////
|
||
|
||
// Pixel format IDs.
|
||
typedef enum {
|
||
PIXFORMAT_ID_BINARY = 1,
|
||
PIXFORMAT_ID_GRAY = 2,
|
||
PIXFORMAT_ID_RGB565 = 3,
|
||
PIXFORMAT_ID_BAYER = 4,
|
||
PIXFORMAT_ID_YUV422 = 5,
|
||
PIXFORMAT_ID_JPEG = 6,
|
||
PIXFORMAT_ID_RGB888 = 7,
|
||
PIXFORMAT_ID_PNG = 9,
|
||
PIXFORMAT_ID_ARGB8 = 8,
|
||
|
||
/* Note: Update PIXFORMAT_IS_VALID when adding new formats */
|
||
} pixformat_id_t;
|
||
|
||
// Pixel sub-format IDs.
|
||
typedef enum {
|
||
SUBFORMAT_ID_GRAY8 = 0,
|
||
SUBFORMAT_ID_GRAY16 = 1,
|
||
SUBFORMAT_ID_BGGR = 0, // !!! Note: Make sure bayer sub-formats don't !!!
|
||
SUBFORMAT_ID_GBRG = 1, // !!! overflow the sensor.hw_flags.bayer field !!!
|
||
SUBFORMAT_ID_GRBG = 2,
|
||
SUBFORMAT_ID_RGGB = 3,
|
||
SUBFORMAT_ID_YUV422 = 0,
|
||
SUBFORMAT_ID_YVU422 = 1,
|
||
/* Note: Update PIXFORMAT_IS_VALID when adding new formats */
|
||
} subformat_id_t;
|
||
|
||
// Pixel format Byte Per Pixel.
|
||
typedef enum {
|
||
PIXFORMAT_BPP_BINARY = 0,
|
||
PIXFORMAT_BPP_GRAY8 = 1,
|
||
PIXFORMAT_BPP_GRAY16 = 2,
|
||
PIXFORMAT_BPP_RGB565 = 2,
|
||
PIXFORMAT_BPP_BAYER = 1,
|
||
PIXFORMAT_BPP_YUV422 = 2,
|
||
PIXFORMAT_BPP_RGB888 = 3,
|
||
PIXFORMAT_BPP_ARGB8 = 4,
|
||
/* Note: Update PIXFORMAT_IS_VALID when adding new formats */
|
||
} pixformat_bpp_t;
|
||
|
||
// Pixel format flags.
|
||
#define PIXFORMAT_FLAGS_Y (1 << 28) // YUV format.
|
||
#define PIXFORMAT_FLAGS_M (1 << 27) // Mutable format.
|
||
#define PIXFORMAT_FLAGS_C (1 << 26) // Colored format.
|
||
#define PIXFORMAT_FLAGS_J (1 << 25) // Compressed format (JPEG/PNG).
|
||
#define PIXFORMAT_FLAGS_R (1 << 24) // RAW/Bayer format.
|
||
#define PIXFORMAT_FLAGS_CY (PIXFORMAT_FLAGS_C | PIXFORMAT_FLAGS_Y)
|
||
#define PIXFORMAT_FLAGS_CM (PIXFORMAT_FLAGS_C | PIXFORMAT_FLAGS_M)
|
||
#define PIXFORMAT_FLAGS_CR (PIXFORMAT_FLAGS_C | PIXFORMAT_FLAGS_R)
|
||
#define PIXFORMAT_FLAGS_CJ (PIXFORMAT_FLAGS_C | PIXFORMAT_FLAGS_J)
|
||
#define IMLIB_IMAGE_MAX_SIZE(x) ((x) & 0xFFFFFFFF)
|
||
|
||
// Each pixel format encodes flags, pixel format id and bpp as follows:
|
||
// 31......29 28 27 26 25 24 23..........16 15...........8 7.............0
|
||
// <RESERVED> YF MF CF JF RF <PIXFORMAT_ID> <SUBFORMAT_ID> <BYTES_PER_PIX>
|
||
// NOTE: Bit 31-30 must Not be used for pixformat_t to be used as mp_int_t.
|
||
typedef enum {
|
||
PIXFORMAT_INVALID = (0x00000000U),
|
||
PIXFORMAT_BINARY = (PIXFORMAT_FLAGS_M | (PIXFORMAT_ID_BINARY << 16) | (0 << 8) | PIXFORMAT_BPP_BINARY ),
|
||
PIXFORMAT_GRAYSCALE = (PIXFORMAT_FLAGS_M | (PIXFORMAT_ID_GRAY << 16) | (SUBFORMAT_ID_GRAY8 << 8) | PIXFORMAT_BPP_GRAY8 ),
|
||
PIXFORMAT_RGB565 = (PIXFORMAT_FLAGS_CM | (PIXFORMAT_ID_RGB565 << 16) | (0 << 8) | PIXFORMAT_BPP_RGB565 ),
|
||
PIXFORMAT_ARGB8 = (PIXFORMAT_FLAGS_CM | (PIXFORMAT_ID_ARGB8 << 16) | (0 << 8) | PIXFORMAT_BPP_ARGB8 ),
|
||
PIXFORMAT_BAYER = (PIXFORMAT_FLAGS_CR | (PIXFORMAT_ID_BAYER << 16) | (SUBFORMAT_ID_BGGR << 8) | PIXFORMAT_BPP_BAYER ),
|
||
PIXFORMAT_BAYER_BGGR = (PIXFORMAT_FLAGS_CR | (PIXFORMAT_ID_BAYER << 16) | (SUBFORMAT_ID_BGGR << 8) | PIXFORMAT_BPP_BAYER ),
|
||
PIXFORMAT_BAYER_GBRG = (PIXFORMAT_FLAGS_CR | (PIXFORMAT_ID_BAYER << 16) | (SUBFORMAT_ID_GBRG << 8) | PIXFORMAT_BPP_BAYER ),
|
||
PIXFORMAT_BAYER_GRBG = (PIXFORMAT_FLAGS_CR | (PIXFORMAT_ID_BAYER << 16) | (SUBFORMAT_ID_GRBG << 8) | PIXFORMAT_BPP_BAYER ),
|
||
PIXFORMAT_BAYER_RGGB = (PIXFORMAT_FLAGS_CR | (PIXFORMAT_ID_BAYER << 16) | (SUBFORMAT_ID_RGGB << 8) | PIXFORMAT_BPP_BAYER ),
|
||
PIXFORMAT_YUV = (PIXFORMAT_FLAGS_CY | (PIXFORMAT_ID_YUV422 << 16) | (SUBFORMAT_ID_YUV422 << 8) | PIXFORMAT_BPP_YUV422 ),
|
||
PIXFORMAT_YUV422 = (PIXFORMAT_FLAGS_CY | (PIXFORMAT_ID_YUV422 << 16) | (SUBFORMAT_ID_YUV422 << 8) | PIXFORMAT_BPP_YUV422 ),
|
||
PIXFORMAT_YVU422 = (PIXFORMAT_FLAGS_CY | (PIXFORMAT_ID_YUV422 << 16) | (SUBFORMAT_ID_YVU422 << 8) | PIXFORMAT_BPP_YUV422 ),
|
||
PIXFORMAT_JPEG = (PIXFORMAT_FLAGS_CJ | (PIXFORMAT_ID_JPEG << 16) | (0 << 8) | 0 ),
|
||
PIXFORMAT_PNG = (PIXFORMAT_FLAGS_CJ | (PIXFORMAT_ID_PNG << 16) | (0 << 8) | 0 ),
|
||
PIXFORMAT_RGB888 = (PIXFORMAT_FLAGS_CM | (PIXFORMAT_ID_RGB888 << 16) | (0 << 8) | PIXFORMAT_BPP_RGB888 ),
|
||
PIXFORMAT_LAST = (0xFFFFFFFFU),
|
||
} pixformat_t;
|
||
|
||
#define PIXFORMAT_MUTABLE_ANY \
|
||
PIXFORMAT_BINARY: \
|
||
case PIXFORMAT_GRAYSCALE: \
|
||
case PIXFORMAT_RGB565: \
|
||
case PIXFORMAT_ARGB8: \
|
||
case PIXFORMAT_RGB888 \
|
||
|
||
#define PIXFORMAT_BAYER_ANY \
|
||
PIXFORMAT_BAYER_BGGR: \
|
||
case PIXFORMAT_BAYER_GBRG: \
|
||
case PIXFORMAT_BAYER_GRBG: \
|
||
case PIXFORMAT_BAYER_RGGB \
|
||
|
||
#define PIXFORMAT_YUV_ANY \
|
||
PIXFORMAT_YUV422: \
|
||
case PIXFORMAT_YVU422 \
|
||
|
||
#define PIXFORMAT_COMPRESSED_ANY \
|
||
PIXFORMAT_JPEG: \
|
||
case PIXFORMAT_PNG \
|
||
|
||
#define IMLIB_PIXFORMAT_IS_VALID(x) \
|
||
((x == PIXFORMAT_BINARY) \
|
||
|| (x == PIXFORMAT_GRAYSCALE) \
|
||
|| (x == PIXFORMAT_RGB565) \
|
||
|| (x == PIXFORMAT_ARGB8) \
|
||
|| (x == PIXFORMAT_BAYER_BGGR) \
|
||
|| (x == PIXFORMAT_BAYER_GBRG) \
|
||
|| (x == PIXFORMAT_BAYER_GRBG) \
|
||
|| (x == PIXFORMAT_BAYER_RGGB) \
|
||
|| (x == PIXFORMAT_YUV422) \
|
||
|| (x == PIXFORMAT_YVU422) \
|
||
|| (x == PIXFORMAT_JPEG) \
|
||
|| (x == PIXFORMAT_PNG) \
|
||
|| (x == PIXFORMAT_RGB888)) \
|
||
|
||
#if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
|
||
#define PIXFORMAT_STRUCT \
|
||
struct { \
|
||
union { \
|
||
struct { \
|
||
uint32_t bpp :8; \
|
||
uint32_t subfmt_id :8; \
|
||
uint32_t pixfmt_id :8; \
|
||
uint32_t is_bayer :1; \
|
||
uint32_t is_compressed :1; \
|
||
uint32_t is_color :1; \
|
||
uint32_t is_mutable :1; \
|
||
uint32_t is_yuv :1; \
|
||
uint32_t /*reserved*/ :3; \
|
||
}; \
|
||
uint32_t pixfmt; \
|
||
}; \
|
||
uint32_t size; /* for compressed images */ \
|
||
bool is_data_alloc; /*data need to free when call destory*/\
|
||
}
|
||
#elif defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
|
||
#define PIXFORMAT_STRUCT \
|
||
struct { \
|
||
union { \
|
||
struct { \
|
||
uint32_t /*reserved*/ :3; \
|
||
uint32_t is_yuv :1; \
|
||
uint32_t is_mutable :1; \
|
||
uint32_t is_color :1; \
|
||
uint32_t is_compressed :1; \
|
||
uint32_t is_bayer :1; \
|
||
uint32_t pixfmt_id :8; \
|
||
uint32_t subfmt_id :8; \
|
||
uint32_t bpp :8; \
|
||
}; \
|
||
uint32_t pixfmt; \
|
||
}; \
|
||
uint32_t size; /* for compressed images */ \
|
||
bool is_data_alloc; /*data need to free when call destory*/\
|
||
}
|
||
#else
|
||
#error "Byte order is not defined."
|
||
#endif
|
||
|
||
typedef struct image {
|
||
uint32_t w;
|
||
uint32_t h;
|
||
PIXFORMAT_STRUCT;
|
||
union {
|
||
uint8_t *pixels;
|
||
uint8_t *data;
|
||
};
|
||
} image_t;
|
||
|
||
image_t* imlib_image_create(int w, int h, pixformat_t pixfmt, uint32_t size, void *pixels, bool is_data_alloc);
|
||
image_t* imlib_image_create_fb_buff(int w, int h, pixformat_t pixfmt, uint32_t size, void *pixels, bool is_data_alloc);
|
||
void imlib_image_destroy_fb_buff(image_t **obj);
|
||
void imlib_image_destroy(image_t **obj);
|
||
void imlib_image_init(image_t *ptr, int w, int h, pixformat_t pixfmt, uint32_t size, void *pixels);
|
||
void image_copy(image_t *dst, image_t *src);
|
||
size_t image_size(image_t *ptr);
|
||
bool image_get_mask_pixel(image_t *ptr, int x, int y);
|
||
|
||
#define IMAGE_BINARY_LINE_LEN(image) (((image)->w + UINT32_T_MASK) >> UINT32_T_SHIFT)
|
||
#define IMAGE_BINARY_LINE_LEN_BYTES(image) (IMAGE_BINARY_LINE_LEN(image) * sizeof(uint32_t))
|
||
|
||
#define IMAGE_GRAYSCALE_LINE_LEN(image) ((image)->w)
|
||
#define IMAGE_GRAYSCALE_LINE_LEN_BYTES(image) (IMAGE_GRAYSCALE_LINE_LEN(image) * sizeof(uint8_t))
|
||
|
||
#define IMAGE_RGB565_LINE_LEN(image) ((image)->w)
|
||
#define IMAGE_RGB565_LINE_LEN_BYTES(image) (IMAGE_RGB565_LINE_LEN(image) * sizeof(uint16_t))
|
||
|
||
#define IMAGE_RGB888_LINE_LEN(image) ((image)->w)
|
||
#define IMAGE_RGB888_LINE_LEN_BYTES(image) (IMAGE_RGB888_LINE_LEN(image) * sizeof(pixel24_t))
|
||
|
||
#define IMAGE_GET_BINARY_PIXEL(image, x, y) \
|
||
({ \
|
||
__typeof__ (image) _image = (image); \
|
||
__typeof__ (x) _x = (x); \
|
||
__typeof__ (y) _y = (y); \
|
||
(((uint32_t *) _image->data)[(((_image->w + UINT32_T_MASK) >> UINT32_T_SHIFT) * _y) + (_x >> UINT32_T_SHIFT)] >> (_x & UINT32_T_MASK)) & 1; \
|
||
})
|
||
|
||
#define IMAGE_PUT_BINARY_PIXEL(image, x, y, v) \
|
||
({ \
|
||
__typeof__ (image) _image = (image); \
|
||
__typeof__ (x) _x = (x); \
|
||
__typeof__ (y) _y = (y); \
|
||
__typeof__ (v) _v = (v); \
|
||
size_t _i = (((_image->w + UINT32_T_MASK) >> UINT32_T_SHIFT) * _y) + (_x >> UINT32_T_SHIFT); \
|
||
size_t _j = _x & UINT32_T_MASK; \
|
||
((uint32_t *) _image->data)[_i] = (((uint32_t *) _image->data)[_i] & (~(1 << _j))) | ((_v & 1) << _j); \
|
||
})
|
||
|
||
#define IMAGE_CLEAR_BINARY_PIXEL(image, x, y) \
|
||
({ \
|
||
__typeof__ (image) _image = (image); \
|
||
__typeof__ (x) _x = (x); \
|
||
__typeof__ (y) _y = (y); \
|
||
((uint32_t *) _image->data)[(((_image->w + UINT32_T_MASK) >> UINT32_T_SHIFT) * _y) + (_x >> UINT32_T_SHIFT)] &= ~(1 << (_x & UINT32_T_MASK)); \
|
||
})
|
||
|
||
#define IMAGE_SET_BINARY_PIXEL(image, x, y) \
|
||
({ \
|
||
__typeof__ (image) _image = (image); \
|
||
__typeof__ (x) _x = (x); \
|
||
__typeof__ (y) _y = (y); \
|
||
((uint32_t *) _image->data)[(((_image->w + UINT32_T_MASK) >> UINT32_T_SHIFT) * _y) + (_x >> UINT32_T_SHIFT)] |= 1 << (_x & UINT32_T_MASK); \
|
||
})
|
||
|
||
#define IMAGE_GET_GRAYSCALE_PIXEL(image, x, y) \
|
||
({ \
|
||
__typeof__ (image) _image = (image); \
|
||
__typeof__ (x) _x = (x); \
|
||
__typeof__ (y) _y = (y); \
|
||
((uint8_t *) _image->data)[(_image->w * _y) + _x]; \
|
||
})
|
||
|
||
#define IMAGE_PUT_GRAYSCALE_PIXEL(image, x, y, v) \
|
||
({ \
|
||
__typeof__ (image) _image = (image); \
|
||
__typeof__ (x) _x = (x); \
|
||
__typeof__ (y) _y = (y); \
|
||
__typeof__ (v) _v = (v); \
|
||
((uint8_t *) _image->data)[(_image->w * _y) + _x] = _v; \
|
||
})
|
||
|
||
#define IMAGE_GET_RGB565_PIXEL(image, x, y) \
|
||
({ \
|
||
__typeof__ (image) _image = (image); \
|
||
__typeof__ (x) _x = (x); \
|
||
__typeof__ (y) _y = (y); \
|
||
((uint16_t *) _image->data)[(_image->w * _y) + _x]; \
|
||
})
|
||
|
||
#define IMAGE_PUT_RGB565_PIXEL(image, x, y, v) \
|
||
({ \
|
||
__typeof__ (image) _image = (image); \
|
||
__typeof__ (x) _x = (x); \
|
||
__typeof__ (y) _y = (y); \
|
||
__typeof__ (v) _v = (v); \
|
||
((uint16_t *) _image->data)[(_image->w * _y) + _x] = _v; \
|
||
})
|
||
|
||
#define IMAGE_GET_RGB888_PIXEL_(image, x, y) \
|
||
({ \
|
||
__typeof__ (image) _image = (image); \
|
||
__typeof__ (x) _x = (x); \
|
||
__typeof__ (y) _y = (y); \
|
||
((pixel24_t *) _image->data)[(_image->w * _y) + _x]; \
|
||
})
|
||
|
||
#define IMAGE_GET_RGB888_PIXEL(image, x, y) \
|
||
({ \
|
||
__typeof__ (image) _image = (image); \
|
||
__typeof__ (x) _x = (x); \
|
||
__typeof__ (y) _y = (y); \
|
||
pixel24232(((pixel24_t *) _image->data)[(_image->w * _y) + _x]); \
|
||
})
|
||
|
||
#define IMAGE_PUT_RGB888_PIXEL_(image, x, y, v) \
|
||
({ \
|
||
__typeof__ (image) _image = (image); \
|
||
__typeof__ (x) _x = (x); \
|
||
__typeof__ (y) _y = (y); \
|
||
__typeof__ (v) _v = (v); \
|
||
((pixel24_t *) _image->data)[(_image->w * _y) + _x] = _v; \
|
||
})
|
||
|
||
#define IMAGE_PUT_RGB888_PIXEL(image, x, y, v) \
|
||
({ \
|
||
__typeof__ (image) _image = (image); \
|
||
__typeof__ (x) _x = (x); \
|
||
__typeof__ (y) _y = (y); \
|
||
__typeof__ (v) _v = (v); \
|
||
((pixel24_t *) _image->data)[(_image->w * _y) + _x] = pixel32224(_v); \
|
||
})
|
||
|
||
#define IMAGE_GET_YUV_PIXEL(image, x, y) \
|
||
({ \
|
||
__typeof__ (image) _image = (image); \
|
||
__typeof__ (x) _x = (x); \
|
||
__typeof__ (y) _y = (y); \
|
||
((uint16_t *) _image->data)[(_image->w * _y) + _x]; \
|
||
})
|
||
|
||
#define IMAGE_PUT_YUV_PIXEL(image, x, y, v) \
|
||
({ \
|
||
__typeof__ (image) _image = (image); \
|
||
__typeof__ (x) _x = (x); \
|
||
__typeof__ (y) _y = (y); \
|
||
__typeof__ (v) _v = (v); \
|
||
((uint16_t *) _image->data)[(_image->w * _y) + _x] = _v; \
|
||
})
|
||
|
||
#define IMAGE_GET_BAYER_PIXEL(image, x, y) \
|
||
({ \
|
||
__typeof__ (image) _image = (image); \
|
||
__typeof__ (x) _x = (x); \
|
||
__typeof__ (y) _y = (y); \
|
||
((uint8_t *) _image->data)[(_image->w * _y) + _x]; \
|
||
})
|
||
|
||
#define IMAGE_PUT_BAYER_PIXEL(image, x, y, v) \
|
||
({ \
|
||
__typeof__ (image) _image = (image); \
|
||
__typeof__ (x) _x = (x); \
|
||
__typeof__ (y) _y = (y); \
|
||
__typeof__ (v) _v = (v); \
|
||
((uint8_t *) _image->data)[(_image->w * _y) + _x] = _v; \
|
||
})
|
||
|
||
// Fast Stuff //
|
||
|
||
#define IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(image, y) \
|
||
({ \
|
||
__typeof__ (image) _image = (image); \
|
||
__typeof__ (y) _y = (y); \
|
||
((uint32_t *) _image->data) + (((_image->w + UINT32_T_MASK) >> UINT32_T_SHIFT) * _y); \
|
||
})
|
||
|
||
#define IMAGE_GET_BINARY_PIXEL_FAST(row_ptr, x) \
|
||
({ \
|
||
__typeof__ (row_ptr) _row_ptr = (row_ptr); \
|
||
__typeof__ (x) _x = (x); \
|
||
(_row_ptr[_x >> UINT32_T_SHIFT] >> (_x & UINT32_T_MASK)) & 1; \
|
||
})
|
||
|
||
#define IMAGE_PUT_BINARY_PIXEL_FAST(row_ptr, x, v) \
|
||
({ \
|
||
__typeof__ (row_ptr) _row_ptr = (row_ptr); \
|
||
__typeof__ (x) _x = (x); \
|
||
__typeof__ (v) _v = (v); \
|
||
size_t _i = _x >> UINT32_T_SHIFT; \
|
||
size_t _j = _x & UINT32_T_MASK; \
|
||
_row_ptr[_i] = (_row_ptr[_i] & (~(1 << _j))) | ((_v & 1) << _j); \
|
||
})
|
||
|
||
#define IMAGE_CLEAR_BINARY_PIXEL_FAST(row_ptr, x) \
|
||
({ \
|
||
__typeof__ (row_ptr) _row_ptr = (row_ptr); \
|
||
__typeof__ (x) _x = (x); \
|
||
_row_ptr[_x >> UINT32_T_SHIFT] &= ~(1 << (_x & UINT32_T_MASK)); \
|
||
})
|
||
|
||
#define IMAGE_SET_BINARY_PIXEL_FAST(row_ptr, x) \
|
||
({ \
|
||
__typeof__ (row_ptr) _row_ptr = (row_ptr); \
|
||
__typeof__ (x) _x = (x); \
|
||
_row_ptr[_x >> UINT32_T_SHIFT] |= 1 << (_x & UINT32_T_MASK); \
|
||
})
|
||
|
||
#define IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(image, y) \
|
||
({ \
|
||
__typeof__ (image) _image = (image); \
|
||
__typeof__ (y) _y = (y); \
|
||
((uint8_t *) _image->data) + (_image->w * _y); \
|
||
})
|
||
|
||
#define IMAGE_GET_GRAYSCALE_PIXEL_FAST(row_ptr, x) \
|
||
({ \
|
||
__typeof__ (row_ptr) _row_ptr = (row_ptr); \
|
||
__typeof__ (x) _x = (x); \
|
||
_row_ptr[_x]; \
|
||
})
|
||
|
||
#define IMAGE_PUT_GRAYSCALE_PIXEL_FAST(row_ptr, x, v) \
|
||
({ \
|
||
__typeof__ (row_ptr) _row_ptr = (row_ptr); \
|
||
__typeof__ (x) _x = (x); \
|
||
__typeof__ (v) _v = (v); \
|
||
_row_ptr[_x] = _v; \
|
||
})
|
||
|
||
#define IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(image, y) \
|
||
({ \
|
||
__typeof__ (image) _image = (image); \
|
||
__typeof__ (y) _y = (y); \
|
||
((uint16_t *) _image->data) + (_image->w * _y); \
|
||
})
|
||
|
||
#define IMAGE_GET_RGB565_PIXEL_FAST(row_ptr, x) \
|
||
({ \
|
||
__typeof__ (row_ptr) _row_ptr = (row_ptr); \
|
||
__typeof__ (x) _x = (x); \
|
||
_row_ptr[_x]; \
|
||
})
|
||
|
||
#define IMAGE_PUT_RGB565_PIXEL_FAST(row_ptr, x, v) \
|
||
({ \
|
||
__typeof__ (row_ptr) _row_ptr = (row_ptr); \
|
||
__typeof__ (x) _x = (x); \
|
||
__typeof__ (v) _v = (v); \
|
||
_row_ptr[_x] = _v; \
|
||
})
|
||
|
||
#define IMAGE_COMPUTE_RGB888_PIXEL_ROW_PTR(image, y) \
|
||
({ \
|
||
__typeof__ (image) _image = (image); \
|
||
__typeof__ (y) _y = (y); \
|
||
((pixel24_t *) _image->data) + (_image->w * _y); \
|
||
})
|
||
|
||
#define IMAGE_GET_RGB888_PIXEL_FAST_(row_ptr, x) \
|
||
({ \
|
||
__typeof__ (row_ptr) _row_ptr = (row_ptr); \
|
||
__typeof__ (x) _x = (x); \
|
||
_row_ptr[_x]; \
|
||
})
|
||
|
||
#define IMAGE_GET_RGB888_PIXEL_FAST(row_ptr, x) \
|
||
({ \
|
||
__typeof__ (row_ptr) _row_ptr = (row_ptr); \
|
||
__typeof__ (x) _x = (x); \
|
||
pixel24232(_row_ptr[_x]); \
|
||
})
|
||
|
||
#define IMAGE_PUT_RGB888_PIXEL_FAST_(row_ptr, x, v) \
|
||
({ \
|
||
__typeof__ (row_ptr) _row_ptr = (row_ptr); \
|
||
__typeof__ (x) _x = (x); \
|
||
__typeof__ (v) _v = (v); \
|
||
_row_ptr[_x] = _v; \
|
||
})
|
||
|
||
#define IMAGE_PUT_RGB888_PIXEL_FAST(row_ptr, x, v) \
|
||
({ \
|
||
__typeof__ (row_ptr) _row_ptr = (row_ptr); \
|
||
__typeof__ (x) _x = (x); \
|
||
__typeof__ (v) _v = (v); \
|
||
_row_ptr[_x] = pixel32224(_v); \
|
||
})
|
||
|
||
#define IMAGE_COMPUTE_BAYER_PIXEL_ROW_PTR(image, y) \
|
||
({ \
|
||
__typeof__ (image) _image = (image); \
|
||
__typeof__ (y) _y = (y); \
|
||
((uint8_t *) _image->data) + (_image->w * _y); \
|
||
})
|
||
|
||
#define IMAGE_COMPUTE_YUV_PIXEL_ROW_PTR(image, y) \
|
||
({ \
|
||
__typeof__ (image) _image = (image); \
|
||
__typeof__ (y) _y = (y); \
|
||
((uint16_t *) _image->data) + (_image->w * _y); \
|
||
})
|
||
|
||
// Old Image Macros - Will be refactor and removed. But, only after making sure through testing new macros work.
|
||
|
||
// Image kernels
|
||
extern const int8_t kernel_gauss_3[9];
|
||
extern const int8_t kernel_gauss_5[25];
|
||
extern const int kernel_laplacian_3[9];
|
||
extern const int kernel_high_pass_3[9];
|
||
|
||
// Grayscale maxes
|
||
#define IM_MAX_GS (255)
|
||
|
||
#define IM_IS_BINARY(img) ((img)->pixfmt == PIXFORMAT_BINARY)
|
||
#define IM_IS_GS(img) ((img)->pixfmt == PIXFORMAT_GRAYSCALE)
|
||
#define IM_IS_RGB565(img) ((img)->pixfmt == PIXFORMAT_RGB565)
|
||
#define IM_IS_BAYER(img) ((img)->is_bayer)
|
||
#define IM_IS_JPEG(img) ((img)->pixfmt == PIXFORMAT_JPEG)
|
||
#define IM_IS_RGB888(img) ((img)->pixfmt == PIXFORMAT_RGB888)
|
||
|
||
#define IM_X_INSIDE(img, x) \
|
||
({ __typeof__ (img) _img = (img); \
|
||
__typeof__ (x) _x = (x); \
|
||
(0<=_x)&&(_x<_img->w); })
|
||
|
||
#define IM_Y_INSIDE(img, y) \
|
||
({ __typeof__ (img) _img = (img); \
|
||
__typeof__ (y) _y = (y); \
|
||
(0<=_y)&&(_y<_img->h); })
|
||
|
||
#define IM_GET_GS_PIXEL(img, x, y) \
|
||
({ __typeof__ (img) _img = (img); \
|
||
__typeof__ (x) _x = (x); \
|
||
__typeof__ (y) _y = (y); \
|
||
((uint8_t*)_img->pixels)[(_y*_img->w)+_x]; })
|
||
|
||
#define IM_GET_RGB565_PIXEL(img, x, y) \
|
||
({ __typeof__ (img) _img = (img); \
|
||
__typeof__ (x) _x = (x); \
|
||
__typeof__ (y) _y = (y); \
|
||
((uint16_t*)_img->pixels)[(_y*_img->w)+_x]; })
|
||
|
||
#define IM_GET_RGB888_PIXEL(img, x, y) \
|
||
({ __typeof__ (img) _img = (img); \
|
||
__typeof__ (x) _x = (x); \
|
||
__typeof__ (y) _y = (y); \
|
||
pixel24232(((pixel24_t*)_img->pixels)[(_y*_img->w)+_x]); })
|
||
#define IM_GET_RGB888_PIXEL_(img, x, y) \
|
||
({ __typeof__ (img) _img = (img); \
|
||
__typeof__ (x) _x = (x); \
|
||
__typeof__ (y) _y = (y); \
|
||
((pixel24_t*)_img->pixels)[(_y*_img->w)+_x]; })
|
||
|
||
#define IM_SET_GS_PIXEL(img, x, y, p) \
|
||
({ __typeof__ (img) _img = (img); \
|
||
__typeof__ (x) _x = (x); \
|
||
__typeof__ (y) _y = (y); \
|
||
__typeof__ (p) _p = (p); \
|
||
((uint8_t*)_img->pixels)[(_y*_img->w)+_x]=_p; })
|
||
|
||
#define IM_SET_RGB565_PIXEL(img, x, y, p) \
|
||
({ __typeof__ (img) _img = (img); \
|
||
__typeof__ (x) _x = (x); \
|
||
__typeof__ (y) _y = (y); \
|
||
__typeof__ (p) _p = (p); \
|
||
((uint16_t*)_img->pixels)[(_y*_img->w)+_x]=_p; })
|
||
|
||
#define IM_SET_RGB888_PIXEL(img, x, y, p) \
|
||
({ __typeof__ (img) _img = (img); \
|
||
__typeof__ (x) _x = (x); \
|
||
__typeof__ (y) _y = (y); \
|
||
__typeof__ (p) _p = (p); \
|
||
((pixel24_t*)_img->pixels)[(_y*_img->w)+_x]=pixel32224(_p); })
|
||
|
||
#define IM_EQUAL(img0, img1) \
|
||
({ __typeof__ (img0) _img0 = (img0); \
|
||
__typeof__ (img1) _img1 = (img1); \
|
||
(_img0->w==_img1->w)&&(_img0->h==_img1->h)&&(_img0->pixfmt=_img1->pixfmt); })
|
||
|
||
#define IM_TO_GS_PIXEL(img, x, y) \
|
||
(img->bpp == 1 ? img->pixels[((y)*img->w)+(x)] : COLOR_RGB565_TO_Y(((uint16_t*)img->pixels)[((y)*img->w)+(x)]) )
|
||
|
||
typedef struct simple_color {
|
||
uint8_t G; // Gray
|
||
union {
|
||
int8_t L; // LAB L
|
||
uint8_t red; // RGB888 Red
|
||
};
|
||
union {
|
||
int8_t A; // LAB A
|
||
uint8_t green; // RGB888 Green
|
||
};
|
||
union {
|
||
int8_t B; // LAB B
|
||
uint8_t blue; // RGB888 Blue
|
||
};
|
||
} simple_color_t;
|
||
|
||
typedef struct integral_image {
|
||
int w;
|
||
int h;
|
||
uint32_t *data;
|
||
} i_image_t;
|
||
|
||
typedef struct {
|
||
int w;
|
||
int h;
|
||
int y_offs;
|
||
int x_ratio;
|
||
int y_ratio;
|
||
uint32_t **data;
|
||
uint32_t **swap;
|
||
} mw_image_t;
|
||
|
||
typedef struct _vector {
|
||
float x;
|
||
float y;
|
||
float m;
|
||
uint16_t cx,cy;
|
||
} vec_t;
|
||
|
||
typedef struct cluster {
|
||
int x, y, w, h;
|
||
array_t *points;
|
||
} cluster_t;
|
||
|
||
// Return the distance between a cluster centroid and some object.
|
||
typedef float (*cluster_dist_t)(int cx, int cy, void *obj);
|
||
|
||
/* Keypoint */
|
||
typedef struct kp {
|
||
uint16_t x;
|
||
uint16_t y;
|
||
uint16_t score;
|
||
uint16_t octave;
|
||
uint16_t angle;
|
||
uint16_t matched;
|
||
uint8_t desc[32];
|
||
} kp_t;
|
||
|
||
typedef struct size {
|
||
int w;
|
||
int h;
|
||
} wsize_t;
|
||
|
||
/* Haar cascade struct */
|
||
typedef struct cascade {
|
||
int std; // Image standard deviation.
|
||
int step; // Image scanning factor.
|
||
float threshold; // Detection threshold.
|
||
float scale_factor; // Image scaling factor.
|
||
int n_stages; // Number of stages in the cascade.
|
||
int n_features; // Number of features in the cascade.
|
||
int n_rectangles; // Number of rectangles in the cascade.
|
||
struct size window; // Detection window size.
|
||
struct image *img; // Grayscale image.
|
||
mw_image_t *sum; // Integral image.
|
||
mw_image_t *ssq; // Squared integral image.
|
||
uint8_t *stages_array; // Number of features per stage.
|
||
int16_t *stages_thresh_array; // Stages thresholds.
|
||
int16_t *tree_thresh_array; // Features threshold (1 per feature).
|
||
int16_t *alpha1_array; // Alpha1 array (1 per feature).
|
||
int16_t *alpha2_array; // Alpha2 array (1 per feature).
|
||
int8_t *num_rectangles_array; // Number of rectangles per features (1 per feature).
|
||
int8_t *weights_array; // Rectangles weights (1 per rectangle).
|
||
int8_t *rectangles_array; // Rectangles array.
|
||
} cascade_t;
|
||
|
||
typedef struct bmp_read_settings {
|
||
int32_t bmp_w;
|
||
int32_t bmp_h;
|
||
uint16_t bmp_bpp;
|
||
uint32_t bmp_fmt;
|
||
uint32_t bmp_row_bytes;
|
||
} bmp_read_settings_t;
|
||
|
||
typedef struct ppm_read_settings {
|
||
uint8_t read_int_c;
|
||
bool read_int_c_valid;
|
||
uint8_t ppm_fmt;
|
||
} ppm_read_settings_t;
|
||
|
||
typedef struct jpg_read_settings {
|
||
int32_t jpg_w;
|
||
int32_t jpg_h;
|
||
int32_t jpg_size;
|
||
} jpg_read_settings_t;
|
||
|
||
typedef struct png_read_settings {
|
||
int32_t png_w;
|
||
int32_t png_h;
|
||
int32_t png_size;
|
||
} png_read_settings_t;
|
||
|
||
typedef enum save_image_format {
|
||
FORMAT_DONT_CARE,
|
||
FORMAT_BMP,
|
||
FORMAT_PNM,
|
||
FORMAT_JPG,
|
||
FORMAT_PNG,
|
||
FORMAT_RAW,
|
||
} save_image_format_t;
|
||
|
||
typedef struct img_read_settings {
|
||
union {
|
||
bmp_read_settings_t bmp_rs;
|
||
ppm_read_settings_t ppm_rs;
|
||
jpg_read_settings_t jpg_rs;
|
||
png_read_settings_t png_rs;
|
||
};
|
||
save_image_format_t format;
|
||
} img_read_settings_t;
|
||
|
||
typedef void (*line_op_t)(image_t*, int, void*, void*, bool);
|
||
typedef void (*flood_fill_call_back_t)(image_t *, int, int, int, void *);
|
||
|
||
typedef enum descriptor_type {
|
||
DESC_LBP,
|
||
DESC_ORB,
|
||
} descriptor_t;
|
||
|
||
typedef enum edge_detector_type {
|
||
EDGE_CANNY,
|
||
EDGE_SIMPLE,
|
||
} edge_detector_t;
|
||
|
||
typedef enum template_match {
|
||
SEARCH_EX, // Exhaustive search
|
||
SEARCH_DS, // Diamond search
|
||
} template_match_t;
|
||
|
||
typedef enum jpeg_subsample {
|
||
JPEG_SUBSAMPLE_1x1 = 0x11, // 1x1 chroma subsampling (No subsampling)
|
||
JPEG_SUBSAMPLE_2x1 = 0x21, // 2x2 chroma subsampling
|
||
JPEG_SUBSAMPLE_2x2 = 0x22, // 2x2 chroma subsampling
|
||
} jpeg_subsample_t;
|
||
|
||
typedef enum corner_detector_type {
|
||
CORNER_FAST,
|
||
CORNER_AGAST
|
||
} corner_detector_t;
|
||
|
||
typedef struct histogram {
|
||
int LBinCount;
|
||
float *LBins;
|
||
int ABinCount;
|
||
float *ABins;
|
||
int BBinCount;
|
||
float *BBins;
|
||
} histogram_t;
|
||
|
||
typedef struct percentile {
|
||
uint8_t LValue;
|
||
int8_t AValue;
|
||
int8_t BValue;
|
||
} percentile_t;
|
||
|
||
typedef struct threshold {
|
||
uint8_t LValue;
|
||
int8_t AValue;
|
||
int8_t BValue;
|
||
} threshold_t;
|
||
//平均数, 中位数, 众数, stdev, 最小值, 最大值,
|
||
typedef struct statistics {
|
||
uint8_t LMean, LMedian, LMode, LSTDev, LMin, LMax, LLQ, LUQ;
|
||
int8_t AMean, AMedian, AMode, ASTDev, AMin, AMax, ALQ, AUQ;
|
||
int8_t BMean, BMedian, BMode, BSTDev, BMin, BMax, BLQ, BUQ;
|
||
} statistics_t;
|
||
|
||
#define FIND_BLOBS_CORNERS_RESOLUTION 20 // multiple of 4
|
||
#define FIND_BLOBS_ANGLE_RESOLUTION (360 / FIND_BLOBS_CORNERS_RESOLUTION)
|
||
|
||
typedef struct find_blobs_list_lnk_data {
|
||
point_t corners[FIND_BLOBS_CORNERS_RESOLUTION];
|
||
rectangle_t rect;
|
||
uint32_t pixels, perimeter, code, count;
|
||
float centroid_x, centroid_y, rotation, roundness;
|
||
uint16_t x_hist_bins_count, y_hist_bins_count, *x_hist_bins, *y_hist_bins;
|
||
float centroid_x_acc, centroid_y_acc, rotation_acc_x, rotation_acc_y, roundness_acc;
|
||
} find_blobs_list_lnk_data_t;
|
||
|
||
typedef struct find_lines_list_lnk_data {
|
||
line_t line;
|
||
uint32_t magnitude;
|
||
int16_t theta, rho;
|
||
} find_lines_list_lnk_data_t;
|
||
|
||
typedef struct find_circles_list_lnk_data {
|
||
point_t p;
|
||
uint16_t r, magnitude;
|
||
} find_circles_list_lnk_data_t;
|
||
|
||
typedef struct find_rects_list_lnk_data {
|
||
point_t corners[4];
|
||
rectangle_t rect;
|
||
uint32_t magnitude;
|
||
} find_rects_list_lnk_data_t;
|
||
|
||
typedef struct find_qrcodes_list_lnk_data {
|
||
point_t corners[4];
|
||
rectangle_t rect;
|
||
size_t payload_len;
|
||
char *payload;
|
||
uint8_t version, ecc_level, mask, data_type;
|
||
uint32_t eci;
|
||
} find_qrcodes_list_lnk_data_t;
|
||
|
||
typedef enum apriltag_families {
|
||
TAG16H5 = 1,
|
||
TAG25H7 = 2,
|
||
TAG25H9 = 4,
|
||
TAG36H10 = 8,
|
||
TAG36H11 = 16,
|
||
ARTOOLKIT = 32
|
||
} apriltag_families_t;
|
||
|
||
typedef struct find_apriltags_list_lnk_data {
|
||
point_t corners[4];
|
||
rectangle_t rect;
|
||
uint16_t id;
|
||
uint8_t family, hamming;
|
||
point_t centroid;
|
||
float goodness, decision_margin;
|
||
float x_translation, y_translation, z_translation;
|
||
float x_rotation, y_rotation, z_rotation;
|
||
} find_apriltags_list_lnk_data_t;
|
||
|
||
typedef struct find_datamatrices_list_lnk_data {
|
||
point_t corners[4];
|
||
rectangle_t rect;
|
||
size_t payload_len;
|
||
char *payload;
|
||
uint16_t rotation;
|
||
uint8_t rows, columns;
|
||
uint16_t capacity, padding;
|
||
} find_datamatrices_list_lnk_data_t;
|
||
|
||
typedef enum barcodes {
|
||
BARCODE_EAN2,
|
||
BARCODE_EAN5,
|
||
BARCODE_EAN8,
|
||
BARCODE_UPCE,
|
||
BARCODE_ISBN10,
|
||
BARCODE_UPCA,
|
||
BARCODE_EAN13,
|
||
BARCODE_ISBN13,
|
||
BARCODE_I25,
|
||
BARCODE_DATABAR,
|
||
BARCODE_DATABAR_EXP,
|
||
BARCODE_CODABAR,
|
||
BARCODE_CODE39,
|
||
BARCODE_PDF417,
|
||
BARCODE_CODE93,
|
||
BARCODE_CODE128
|
||
} barcodes_t;
|
||
|
||
typedef struct find_barcodes_list_lnk_data {
|
||
point_t corners[4];
|
||
rectangle_t rect;
|
||
size_t payload_len;
|
||
char *payload;
|
||
uint16_t type, rotation;
|
||
int quality;
|
||
} find_barcodes_list_lnk_data_t;
|
||
|
||
typedef enum image_hint {
|
||
IMAGE_HINT_AREA = 1 << 0,
|
||
IMAGE_HINT_BILINEAR = 1 << 1,
|
||
IMAGE_HINT_BICUBIC = 1 << 2,
|
||
IMAGE_HINT_CENTER = 1 << 7,
|
||
IMAGE_HINT_EXTRACT_RGB_CHANNEL_FIRST = 1 << 8,
|
||
IMAGE_HINT_APPLY_COLOR_PALETTE_FIRST = 1 << 9,
|
||
IMAGE_HINT_BLACK_BACKGROUND = 1 << 31
|
||
} image_hint_t;
|
||
|
||
typedef struct imlib_draw_row_data {
|
||
image_t *dst_img; // user
|
||
pixformat_t src_img_pixfmt; // user
|
||
int rgb_channel; // user
|
||
int alpha; // user
|
||
const uint16_t *color_palette; // user
|
||
const uint8_t *alpha_palette; // user
|
||
bool black_background; // user
|
||
void *callback; // user
|
||
void *dst_row_override; // user
|
||
int toggle; // private
|
||
void *row_buffer[2]; // private
|
||
#ifdef IMLIB_ENABLE_DMA2D
|
||
bool dma2d_request; // user
|
||
bool dma2d_enabled; // private
|
||
bool dma2d_initialized; // private
|
||
DMA2D_HandleTypeDef dma2d; // private
|
||
#endif
|
||
long smuad_alpha; // private
|
||
uint32_t *smuad_alpha_palette; // private
|
||
} imlib_draw_row_data_t;
|
||
|
||
typedef void (*imlib_draw_row_callback_t)(int x_start, int x_end, int y_row, imlib_draw_row_data_t *data);
|
||
|
||
// Library Hardware Init
|
||
void imlib_init_all();
|
||
void imlib_deinit_all();
|
||
|
||
//imlib base operation
|
||
void imlib_pixfmt_to(image_t *dst, image_t *src, rectangle_t *roi_i);
|
||
void imlib_image_resize(image_t *dst, image_t *src, int hist);
|
||
|
||
// Generic Helper Functions
|
||
void imlib_fill_image_from_float(image_t *img, int w, int h, float *data, float min, float max,
|
||
bool mirror, bool flip, bool dst_transpose, bool src_transpose);
|
||
|
||
// Bayer Image Processing
|
||
void imlib_debayer_line(int x_start, int x_end, int y_row, void *dst_row_ptr, pixformat_t pixfmt, image_t *src);
|
||
void imlib_debayer_image(image_t *dst, image_t *src);
|
||
|
||
// YUV Image Processing
|
||
void imlib_deyuv_line(int x_start, int x_end, int y_row, void *dst_row_ptr, pixformat_t pixfmt, image_t *src);
|
||
void imlib_deyuv_image(image_t *dst, image_t *src);
|
||
|
||
/* Color space functions */
|
||
int8_t imlib_rgb565_to_l(uint16_t pixel);
|
||
int8_t imlib_rgb565_to_a(uint16_t pixel);
|
||
int8_t imlib_rgb565_to_b(uint16_t pixel);
|
||
int8_t imlib_rgb888_to_l(uint32_t pixel);
|
||
int8_t imlib_rgb888_to_a(uint32_t pixel);
|
||
int8_t imlib_rgb888_to_b(uint32_t pixel);
|
||
uint16_t imlib_lab_to_rgb(uint8_t l, int8_t a, int8_t b);
|
||
uint16_t imlib_yuv_to_rgb(uint8_t y, int8_t u, int8_t v);
|
||
uint32_t imlib_lab_to_rgb888(uint8_t l, int8_t a, int8_t b);
|
||
uint32_t imlib_yuv_to_rgb888(uint8_t y, int8_t u, int8_t v);
|
||
|
||
/* Image file functions */
|
||
void ppm_read_geometry(FIL *fp, image_t *img, const char *path, ppm_read_settings_t *rs);
|
||
void ppm_read_pixels(FIL *fp, image_t *img, int n_lines, ppm_read_settings_t *rs);
|
||
void ppm_read(image_t *img, const char *path);
|
||
void ppm_write_subimg(image_t *img, const char *path, rectangle_t *r);
|
||
bool bmp_read_geometry(FIL *fp, image_t *img, const char *path, bmp_read_settings_t *rs);
|
||
void bmp_read_pixels(FIL *fp, image_t *img, int n_lines, bmp_read_settings_t *rs);
|
||
void bmp_read(image_t *img, const char *path);
|
||
void bmp_write_subimg(image_t *img, const char *path, rectangle_t *r);
|
||
#if (OMV_HARDWARE_JPEG == 1)
|
||
void imlib_jpeg_compress_init();
|
||
void imlib_jpeg_compress_deinit();
|
||
void jpeg_mdma_irq_handler();
|
||
#endif
|
||
void jpeg_decompress(image_t *dst, image_t *src);
|
||
bool jpeg_compress(image_t *src, image_t *dst, int quality, bool realloc);
|
||
int jpeg_clean_trailing_bytes(int bpp, uint8_t *data);
|
||
void jpeg_read_geometry(FIL *fp, image_t *img, const char *path, jpg_read_settings_t *rs);
|
||
void jpeg_read_pixels(FIL *fp, image_t *img);
|
||
void jpeg_read(image_t *img, const char *path);
|
||
void jpeg_write(image_t *img, const char *path, int quality);
|
||
void png_decompress(image_t *dst, image_t *src);
|
||
bool png_compress(image_t *src, image_t *dst);
|
||
void png_read_geometry(FIL *fp, image_t *img, const char *path, png_read_settings_t *rs);
|
||
void png_read_pixels(FIL *fp, image_t *img);
|
||
void png_read(image_t *img, const char *path);
|
||
void png_write(image_t *img, const char *path);
|
||
bool imlib_read_geometry(FIL *fp, image_t *img, const char *path, img_read_settings_t *rs);
|
||
void imlib_image_operation(image_t *img, const char *path, image_t *other, int scalar, line_op_t op, void *data);
|
||
void imlib_load_image(image_t *img, const char *path);
|
||
void imlib_save_image(image_t *img, const char *path, rectangle_t *roi, int quality);
|
||
|
||
/* GIF functions */
|
||
void gif_open(FIL *fp, int width, int height, bool color, bool loop);
|
||
void gif_add_frame(FIL *fp, image_t *img, uint16_t delay);
|
||
void gif_close(FIL *fp);
|
||
|
||
/* MJPEG functions */
|
||
void mjpeg_open(FIL *fp, int width, int height);
|
||
void mjpeg_add_frame(FIL *fp, uint32_t *frames, uint32_t *bytes, image_t *img, int quality);
|
||
void mjpeg_close(FIL *fp, uint32_t *frames, uint32_t *bytes, float fps);
|
||
|
||
/* Point functions */
|
||
point_t *point_alloc(int16_t x, int16_t y);
|
||
bool point_equal(point_t *p1, point_t *p2);
|
||
float point_distance(point_t *p1, point_t *p2);
|
||
|
||
/* Rectangle functions */
|
||
rectangle_t *rectangle_alloc(int16_t x, int16_t y, int16_t w, int16_t h);
|
||
bool rectangle_equal(rectangle_t *r1, rectangle_t *r2);
|
||
bool rectangle_intersects(rectangle_t *r1, rectangle_t *r2);
|
||
bool rectangle_subimg(image_t *img, rectangle_t *r, rectangle_t *r_out);
|
||
array_t *rectangle_merge(array_t *rectangles);
|
||
void rectangle_expand(rectangle_t *r, int x, int y);
|
||
|
||
/* Separable 2D convolution */
|
||
void imlib_sepconv3(image_t *img, const int8_t *krn, const float m, const int b);
|
||
|
||
/* Image Statistics */
|
||
int imlib_image_mean(image_t *src, int *r_mean, int *g_mean, int *b_mean);
|
||
int imlib_image_std(image_t *src); // grayscale only
|
||
|
||
/* Template Matching */
|
||
void imlib_midpoint_pool(image_t *img_i, image_t *img_o, int x_div, int y_div, const int bias);
|
||
void imlib_mean_pool(image_t *img_i, image_t *img_o, int x_div, int y_div);
|
||
float imlib_template_match_ds(image_t *image, image_t *template_obj, rectangle_t *r);
|
||
float imlib_template_match_ex(image_t *image, image_t *template_obj, rectangle_t *roi, int step, rectangle_t *r);
|
||
|
||
/* Clustering functions */
|
||
array_t *cluster_kmeans(array_t *points, int k, cluster_dist_t dist_func);
|
||
|
||
/* Integral image functions */
|
||
void imlib_integral_image_alloc(struct integral_image *sum, int w, int h);
|
||
void imlib_integral_image_free(struct integral_image *sum);
|
||
void imlib_integral_image(struct image *src, struct integral_image *sum);
|
||
void imlib_integral_image_sq(struct image *src, struct integral_image *sum);
|
||
void imlib_integral_image_scaled(struct image *src, struct integral_image *sum);
|
||
uint32_t imlib_integral_lookup(struct integral_image *src, int x, int y, int w, int h);
|
||
|
||
// Integral moving window
|
||
void imlib_integral_mw_alloc(mw_image_t *sum, int w, int h);
|
||
void imlib_integral_mw_free(mw_image_t *sum);
|
||
void imlib_integral_mw_scale(rectangle_t *roi, mw_image_t *sum, int w, int h);
|
||
void imlib_integral_mw(image_t *src, mw_image_t *sum);
|
||
void imlib_integral_mw_sq(image_t *src, mw_image_t *sum);
|
||
void imlib_integral_mw_shift(image_t *src, mw_image_t *sum, int n);
|
||
void imlib_integral_mw_shift_sq(image_t *src, mw_image_t *sum, int n);
|
||
void imlib_integral_mw_ss(image_t *src, mw_image_t *sum, mw_image_t *ssq, rectangle_t *roi);
|
||
void imlib_integral_mw_shift_ss(image_t *src, mw_image_t *sum, mw_image_t *ssq, rectangle_t *roi, int n);
|
||
long imlib_integral_mw_lookup(mw_image_t *sum, int x, int y, int w, int h);
|
||
|
||
/* Haar/VJ */
|
||
int imlib_load_cascade(struct cascade* cascade, const char *path);
|
||
array_t *imlib_detect_objects(struct image *image, struct cascade *cascade, struct rectangle *roi);
|
||
|
||
/* Corner detectors */
|
||
void fast_detect(image_t *image, array_t *keypoints, int threshold, rectangle_t *roi);
|
||
void agast_detect(image_t *image, array_t *keypoints, int threshold, rectangle_t *roi);
|
||
|
||
/* ORB descriptor */
|
||
array_t *orb_find_keypoints(image_t *image, bool normalized, int threshold,
|
||
float scale_factor, int max_keypoints, corner_detector_t corner_detector, rectangle_t *roi);
|
||
int orb_match_keypoints(array_t *kpts1, array_t *kpts2, int *match, int threshold, rectangle_t *r, point_t *c, int *angle);
|
||
int orb_filter_keypoints(array_t *kpts, rectangle_t *r, point_t *c);
|
||
int orb_save_descriptor(FIL *fp, array_t *kpts);
|
||
int orb_load_descriptor(FIL *fp, array_t *kpts);
|
||
float orb_cluster_dist(int cx, int cy, void *kp);
|
||
|
||
/* LBP Operator */
|
||
uint8_t *imlib_lbp_desc(image_t *image, rectangle_t *roi);
|
||
int imlib_lbp_desc_distance(uint8_t *d0, uint8_t *d1);
|
||
int imlib_lbp_desc_save(FIL *fp, uint8_t *desc);
|
||
int imlib_lbp_desc_load(FIL *fp, uint8_t **desc);
|
||
|
||
/* Iris detector */
|
||
void imlib_find_iris(image_t *src, point_t *iris, rectangle_t *roi);
|
||
|
||
// Image filter functions
|
||
void im_filter_bw(uint8_t *src, uint8_t *dst, int size, int bpp, void *args);
|
||
void im_filter_skin(uint8_t *src, uint8_t *dst, int size, int bpp, void *args);
|
||
|
||
// Edge detection
|
||
void imlib_edge_simple(image_t *src, rectangle_t *roi, int low_thresh, int high_thresh);
|
||
void imlib_edge_canny(image_t *src, rectangle_t *roi, int low_thresh, int high_thresh);
|
||
|
||
// HoG
|
||
void imlib_find_hog(image_t *src, rectangle_t *roi, int cell_size);
|
||
|
||
// Helper Functions
|
||
void imlib_zero(image_t *img, image_t *mask, bool invert);
|
||
void imlib_draw_row_setup(imlib_draw_row_data_t *data);
|
||
void imlib_draw_row_teardown(imlib_draw_row_data_t *data);
|
||
#ifdef IMLIB_ENABLE_DMA2D
|
||
void imlib_draw_row_deinit_all();
|
||
#endif
|
||
void *imlib_draw_row_get_row_buffer(imlib_draw_row_data_t *data);
|
||
void imlib_draw_row_put_row_buffer(imlib_draw_row_data_t *data, void *row_buffer);
|
||
void imlib_draw_row(int x_start, int x_end, int y_row, imlib_draw_row_data_t *data);
|
||
bool imlib_draw_image_rectangle(image_t *dst_img, image_t *src_img, int dst_x_start, int dst_y_start, float x_scale, float y_scale, rectangle_t *roi,
|
||
int alpha, const uint8_t *alpha_palette, image_hint_t hint,
|
||
int *x0, int *x1, int *y0, int *y1);
|
||
void imlib_flood_fill_int(image_t *out, image_t *img, int x, int y,
|
||
int seed_threshold, int floating_threshold,
|
||
flood_fill_call_back_t cb, void *data);
|
||
// Drawing Functions
|
||
int imlib_get_pixel(image_t *img, int x, int y);
|
||
int imlib_get_pixel_fast(image_t *img, const void *row_ptr, int x);
|
||
void imlib_set_pixel(image_t *img, int x, int y, int p);
|
||
void imlib_draw_line(image_t *img, int x0, int y0, int x1, int y1, int c, int thickness);
|
||
void imlib_draw_rectangle(image_t *img, int rx, int ry, int rw, int rh, int c, int thickness, bool fill);
|
||
void imlib_draw_circle(image_t *img, int cx, int cy, int r, int c, int thickness, bool fill);
|
||
void imlib_draw_ellipse(image_t *img, int cx, int cy, int rx, int ry, int rotation, int c, int thickness, bool fill);
|
||
void imlib_draw_string(image_t *img, int x_off, int y_off, const char *str, int c, float scale, int x_spacing, int y_spacing, bool mono_space,
|
||
int char_rotation, bool char_hmirror, bool char_vflip, int string_rotation, bool string_hmirror, bool string_hflip);
|
||
void imlib_draw_image_fast(image_t *img, image_t *other, int x_off, int y_off, float x_scale, float y_scale, float alpha, image_t *mask);
|
||
void imlib_draw_image(image_t *dst_img, image_t *src_img, int dst_x_start, int dst_y_start, float x_scale, float y_scale, rectangle_t *roi,
|
||
int rgb_channel, int alpha, const uint16_t *color_palette, const uint8_t *alpha_palette, image_hint_t hint,
|
||
imlib_draw_row_callback_t callback, void *dst_row_override);
|
||
void imlib_flood_fill(image_t *img, int x, int y,
|
||
float seed_threshold, float floating_threshold,
|
||
int c, bool invert, bool clear_background, image_t *mask);
|
||
void imlib_draw_cross(image_t *img, int x, int y, int c, int size, int thickness);
|
||
// ISP Functions
|
||
void imlib_awb(image_t *img, bool max);
|
||
void imlib_ccm(image_t *img, float *ccm, bool offset);
|
||
void imlib_gamma(image_t *img, float gamma, float scale, float offset);
|
||
// Binary Functions
|
||
void imlib_binary(image_t *out, image_t *img, list_t *thresholds, bool invert, bool zero, image_t *mask);
|
||
void imlib_invert(image_t *img);
|
||
void imlib_b_and(image_t *img, const char *path, image_t *other, int scalar, image_t *mask);
|
||
void imlib_b_nand(image_t *img, const char *path, image_t *other, int scalar, image_t *mask);
|
||
void imlib_b_or(image_t *img, const char *path, image_t *other, int scalar, image_t *mask);
|
||
void imlib_b_nor(image_t *img, const char *path, image_t *other, int scalar, image_t *mask);
|
||
void imlib_b_xor(image_t *img, const char *path, image_t *other, int scalar, image_t *mask);
|
||
void imlib_b_xnor(image_t *img, const char *path, image_t *other, int scalar, image_t *mask);
|
||
void imlib_erode(image_t *img, int ksize, int threshold, image_t *mask);
|
||
void imlib_dilate(image_t *img, int ksize, int threshold, image_t *mask);
|
||
void imlib_open(image_t *img, int ksize, int threshold, image_t *mask);
|
||
void imlib_close(image_t *img, int ksize, int threshold, image_t *mask);
|
||
void imlib_top_hat(image_t *img, int ksize, int threshold, image_t *mask);
|
||
void imlib_black_hat(image_t *img, int ksize, int threshold, image_t *mask);
|
||
// Math Functions
|
||
void imlib_gamma_corr(image_t *img, float gamma, float scale, float offset);
|
||
void imlib_negate(image_t *img);
|
||
void imlib_replace(image_t *img, const char *path, image_t *other, int scalar, bool hmirror, bool vflip, bool transpose, image_t *mask);
|
||
void imlib_add(image_t *img, const char *path, image_t *other, int scalar, image_t *mask);
|
||
void imlib_sub(image_t *img, const char *path, image_t *other, int scalar, bool reverse, image_t *mask);
|
||
void imlib_mul(image_t *img, const char *path, image_t *other, int scalar, bool invert, image_t *mask);
|
||
void imlib_div(image_t *img, const char *path, image_t *other, int scalar, bool invert, bool mod, image_t *mask);
|
||
void imlib_min(image_t *img, const char *path, image_t *other, int scalar, image_t *mask);
|
||
void imlib_max(image_t *img, const char *path, image_t *other, int scalar, image_t *mask);
|
||
void imlib_difference(image_t *img, const char *path, image_t *other, int scalar, image_t *mask);
|
||
void imlib_blend(image_t *img, const char *path, image_t *other, int scalar, float alpha, image_t *mask);
|
||
// Filtering Functions
|
||
void imlib_histeq(image_t *img, image_t *mask);
|
||
void imlib_clahe_histeq(image_t *img, float clip_limit, image_t *mask);
|
||
void imlib_mean_filter(image_t *img, const int ksize, bool threshold, int offset, bool invert, image_t *mask);
|
||
void imlib_median_filter(image_t *img, const int ksize, float percentile, bool threshold, int offset, bool invert, image_t *mask);
|
||
void imlib_mode_filter(image_t *img, const int ksize, bool threshold, int offset, bool invert, image_t *mask);
|
||
void imlib_midpoint_filter(image_t *img, const int ksize, float bias, bool threshold, int offset, bool invert, image_t *mask);
|
||
void imlib_morph(image_t *img, const int ksize, const int *krn, const float m, const int b, bool threshold, int offset, bool invert, image_t *mask);
|
||
void imlib_bilateral_filter(image_t *img, const int ksize, float color_sigma, float space_sigma, bool threshold, int offset, bool invert, image_t *mask);
|
||
void imlib_cartoon_filter(image_t *img, float seed_threshold, float floating_threshold, image_t *mask);
|
||
// Image Correction
|
||
void imlib_logpolar_int(image_t *dst, image_t *src, rectangle_t *roi, bool linear, bool reverse); // helper/internal
|
||
void imlib_logpolar(image_t *img, bool linear, bool reverse);
|
||
// Lens/Rotation Correction
|
||
void imlib_lens_corr(image_t *img, float strength, float zoom, float x_corr, float y_corr);
|
||
void imlib_rotation_corr(image_t *img, float x_rotation, float y_rotation,
|
||
float z_rotation, float x_translation, float y_translation,
|
||
float zoom, float fov, float *corners);
|
||
// Statistics
|
||
void imlib_get_similarity(image_t *img, const char *path, image_t *other, int scalar, float *avg, float *std, float *min, float *max);
|
||
void imlib_get_histogram(histogram_t *out, image_t *ptr, rectangle_t *roi, list_t *thresholds, bool invert, image_t *other);
|
||
void imlib_get_percentile(percentile_t *out, pixformat_t pixfmt, histogram_t *ptr, float percentile);
|
||
void imlib_get_threshold(threshold_t *out, pixformat_t pixfmt, histogram_t *ptr);
|
||
void imlib_get_statistics(statistics_t *out, pixformat_t pixfmt, histogram_t *ptr);
|
||
bool imlib_get_regression(find_lines_list_lnk_data_t *out, image_t *ptr, rectangle_t *roi, unsigned int x_stride, unsigned int y_stride,
|
||
list_t *thresholds, bool invert, unsigned int area_threshold, unsigned int pixels_threshold, bool robust);
|
||
// Color Tracking
|
||
void imlib_find_blobs(list_t *out, image_t *ptr, rectangle_t *roi, unsigned int x_stride, unsigned int y_stride,
|
||
list_t *thresholds, bool invert, unsigned int area_threshold, unsigned int pixels_threshold,
|
||
bool merge, int margin,
|
||
bool (*threshold_cb)(void*,find_blobs_list_lnk_data_t*), void *threshold_cb_arg,
|
||
bool (*merge_cb)(void*,find_blobs_list_lnk_data_t*,find_blobs_list_lnk_data_t*), void *merge_cb_arg,
|
||
unsigned int x_hist_bins_max, unsigned int y_hist_bins_max);
|
||
// Shape Detection
|
||
size_t trace_line(image_t *ptr, line_t *l, int *theta_buffer, uint32_t *mag_buffer, point_t *point_buffer); // helper/internal
|
||
void merge_alot(list_t *out, int threshold, int theta_threshold); // helper/internal
|
||
void imlib_find_lines(list_t *out, image_t *ptr, rectangle_t *roi, unsigned int x_stride, unsigned int y_stride,
|
||
uint32_t threshold, unsigned int theta_margin, unsigned int rho_margin);
|
||
void imlib_lsd_find_line_segments(list_t *out, image_t *ptr, rectangle_t *roi, unsigned int merge_distance, unsigned int max_theta_diff);
|
||
void imlib_find_line_segments(list_t *out, image_t *ptr, rectangle_t *roi, unsigned int x_stride, unsigned int y_stride,
|
||
uint32_t threshold, unsigned int theta_margin, unsigned int rho_margin,
|
||
uint32_t segment_threshold);
|
||
void imlib_find_circles(list_t *out, image_t *ptr, rectangle_t *roi, unsigned int x_stride, unsigned int y_stride,
|
||
uint32_t threshold, unsigned int x_margin, unsigned int y_margin, unsigned int r_margin,
|
||
unsigned int r_min, unsigned int r_max, unsigned int r_step);
|
||
void imlib_find_rects(list_t *out, image_t *ptr, rectangle_t *roi,
|
||
uint32_t threshold);
|
||
// 1/2D Bar Codes
|
||
void imlib_find_qrcodes(list_t *out, image_t *ptr, rectangle_t *roi);
|
||
void custom_imlib_find_apriltags(list_t *out, image_t *ptr, rectangle_t *roi, apriltag_families_t families,
|
||
float fx, float fy, float cx, float cy, int status);
|
||
void imlib_find_apriltags(list_t *out, image_t *ptr, rectangle_t *roi, apriltag_families_t families,
|
||
float fx, float fy, float cx, float cy);
|
||
void imlib_find_datamatrices(list_t *out, image_t *ptr, rectangle_t *roi, int effort);
|
||
void imlib_find_barcodes(list_t *out, image_t *ptr, rectangle_t *roi);
|
||
// Template Matching
|
||
void imlib_phasecorrelate(image_t *img0, image_t *img1, rectangle_t *roi0, rectangle_t *roi1, bool logpolar, bool fix_rotation_scale,
|
||
float *x_translation, float *y_translation, float *rotation, float *scale, float *response);
|
||
|
||
array_t *imlib_selective_search(image_t *src, float t, int min_size, float a1, float a2, float a3);
|
||
|
||
|
||
// custem
|
||
|
||
void imlib_find_domain(image_t* img, image_t** dst, float edge_gate);
|
||
|
||
|
||
|
||
|
||
#ifdef __cplusplus
|
||
}
|
||
#endif
|
||
#endif //__IMLIB_H__
|