-
Notifications
You must be signed in to change notification settings - Fork 5
/
morphology.go
129 lines (118 loc) · 2.92 KB
/
morphology.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package blurry
/*
#cgo CFLAGS: -I${SRCDIR}/include
#cgo darwin LDFLAGS: -L${SRCDIR}/lib -lruntime_osx -ldl -lm
#cgo darwin LDFLAGS: -lmorphology_open_osx
#cgo darwin LDFLAGS: -lmorphology_close_osx
#cgo darwin LDFLAGS: -lmorphology_gradient_osx
#cgo linux LDFLAGS: -L${SRCDIR}/lib -lruntime_linux -ldl -lm
#cgo linux LDFLAGS: -lmorphology_open_linux
#cgo linux LDFLAGS: -lmorphology_close_linux
#cgo linux LDFLAGS: -lmorphology_gradient_linux
#include <stdlib.h>
#include <string.h>
#ifdef __APPLE__
#include "libmorphology_open_osx.h"
#include "libmorphology_close_osx.h"
#include "libmorphology_gradient_osx.h"
#elif __linux__
#include "libmorphology_open_linux.h"
#include "libmorphology_close_linux.h"
#include "libmorphology_gradient_linux.h"
#endif
#include "buffer.h"
int call_morphology(
unsigned char mode,
halide_buffer_t *in,
int32_t width, int32_t height,
int32_t size,
halide_buffer_t *out
) {
if(1 == mode) {
return morphology_open(in, width, height, size, out);
}
if(2 == mode) {
return morphology_close(in, width, height, size, out);
}
if(3 == mode) {
return morphology_gradient(in, width, height, size, out);
}
return 1;
}
int libmorphology(
unsigned char *src, int32_t width, int32_t height,
unsigned char mode, int32_t size, int32_t count,
unsigned char *out
) {
// 1
halide_buffer_t *in_rgba_buf = create_rgba_buffer(src, width, height);
if(in_rgba_buf == NULL){
return 1;
}
halide_buffer_t *out_rgba_buf = create_rgba_buffer(out, width, height);
if(out_rgba_buf == NULL){
free_buf(in_rgba_buf);
return 1;
}
if(call_morphology(mode, in_rgba_buf, width, height, size, out_rgba_buf) != 0) {
free_buf(in_rgba_buf);
free_buf(out_rgba_buf);
return 1;
}
free_buf(in_rgba_buf);
free_buf(out_rgba_buf);
// 2 .. count
halide_buffer_t *in_tmp = NULL;
halide_buffer_t *out_tmp = NULL;
for(int i = 1; i < count; i+= 1) {
in_tmp = create_rgba_buffer(out, width, height);
if(in_tmp == NULL) {
return 1;
}
out_tmp = create_rgba_buffer(out, width, height);
if(out_tmp == NULL) {
free_buf(in_tmp);
return 1;
}
if(call_morphology(mode, in_tmp, width, height, size, out_tmp) != 0){
free_buf(in_tmp);
free_buf(out_tmp);
return 1;
}
free_buf(in_tmp);
free_buf(out_tmp);
}
return 0;
}
*/
import "C"
import (
"errors"
"image"
)
type MorphologyMode uint8
const (
MorphologyOpen MorphologyMode = iota + 1
MorphologyClose
MorphologyGradient
)
var (
ErrMorphology = errors.New("morphology cgo call error")
)
func Morphology(img *image.RGBA, mode MorphologyMode, size int, count int) (*image.RGBA, error) {
width, height := wh(img)
out := GetRGBA(width, height)
ret := C.libmorphology(
(*C.uchar)(&img.Pix[0]),
C.int(width),
C.int(height),
C.uchar(mode),
C.int(size),
C.int(count),
(*C.uchar)(&out.Pix[0]),
)
if int(ret) != 0 {
return nil, ErrMorphology
}
return out, nil
}