From cae1319f90bfb88fdac02ed07a38396e7ca4378a Mon Sep 17 00:00:00 2001
From: zhangmeng <775834166@qq.com>
Date: 星期四, 19 十二月 2019 15:48:57 +0800
Subject: [PATCH] update
---
goconv/goconv.go | 258 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 258 insertions(+), 0 deletions(-)
diff --git a/goconv/goconv.go b/goconv/goconv.go
new file mode 100644
index 0000000..db38a94
--- /dev/null
+++ b/goconv/goconv.go
@@ -0,0 +1,258 @@
+package goconv
+
+/*
+#cgo CFLAGS: -I./ -I./inc -I/usr/local/cuda/include
+#cgo CXXFLAGS: -I./ -I./inc -I/usr/local/cuda/include -std=c++11
+#cgo LDFLAGS: -L/usr/local/cuda/lib64 -lnppig -lnppicc -lnppial -lnppisu -lcudart -ldl
+#include <stdlib.h>
+#include "conv.h"
+*/
+import "C"
+import (
+ "unsafe"
+
+ "basic.com/valib/godraw.git"
+ "basic.com/valib/gogpu.git"
+ "github.com/disintegration/imaging"
+)
+
+const (
+ need = 200
+ reserved = 512
+)
+
+func gpuIndex(lastIndex int) int {
+ indices := gogpu.RankGPU()
+ if len(indices) == 0 {
+ return -1
+ }
+
+ for _, v := range indices {
+ if v != lastIndex {
+ if gogpu.SatisfyGPU(v, need, need/2) {
+ return v
+ }
+ }
+ }
+
+ if gogpu.SatisfyGPU(lastIndex, need, reserved) {
+ return lastIndex
+ }
+ return -1
+}
+
+type convertor struct {
+ width int
+ height int
+ rWidth int
+ rHeight int
+ conv C.convHandle
+}
+
+var convts []*convertor
+
+func find(w, h, rw, rh int) *convertor {
+ for _, v := range convts {
+ if v.width == w && v.height == h && v.rWidth == rw && v.rHeight == rh {
+ return v
+ }
+ }
+ gpu := gpuIndex(0)
+ if gpu < 0 {
+ return nil
+ }
+ cw := C.conv_create(C.int(w), C.int(h), C.int(rw), C.int(rh), C.int(gpu))
+ if cw == nil {
+ return nil
+ }
+ c := &convertor{w, h, rw, rh, cw}
+ convts = append(convts, c)
+ return c
+}
+
+// YUV2BGR yuv->bgr
+func YUV2BGR(yuv []byte, w, h int) []byte {
+
+ cw := find(w, h, -1, -1)
+ if cw == nil {
+ return yuv2bgr(yuv, w, h)
+ }
+ var bgr *C.uchar
+ var bgrLen C.int
+ ret := C.yuv2bgr(cw.conv, unsafe.Pointer(&yuv[0]), &bgr, &bgrLen)
+ if ret != 0 {
+ return nil
+ }
+ const maxLen = 0x7fffffff
+ goBGRLen := int(bgrLen)
+ if goBGRLen > 0 {
+ return (*[maxLen]byte)(unsafe.Pointer(bgr))[:goBGRLen:goBGRLen]
+ }
+ return nil
+}
+
+// YUV2ResizedBGR yuv -> resized bgr
+func YUV2ResizedBGR(yuv []byte, w, h, rw, rh int) []byte {
+
+ cw := find(w, h, rw, rh)
+ if cw == nil {
+ bgr := yuv2bgr(yuv, w, h)
+ return bgresize(bgr, w, h, rw, rh)
+ }
+ var bgr *C.uchar
+ var bgrLen C.int
+ ret := C.yuv2resizedbgr(cw.conv, unsafe.Pointer(&yuv[0]), &bgr, &bgrLen)
+ if ret != 0 {
+ return nil
+ }
+ const maxLen = 0x7fffffff
+ goBGRLen := int(bgrLen)
+ if goBGRLen > 0 {
+ return (*[maxLen]byte)(unsafe.Pointer(bgr))[:goBGRLen:goBGRLen]
+ }
+ return nil
+
+}
+
+// ResizeBGR resize
+func ResizeBGR(bgrO []byte, w, h, rw, rh int) []byte {
+ if (rw < 0 && rh < 0) || (rw > w && rh > h) {
+ return bgrO
+ }
+
+ cw := find(w, h, rw, rh)
+ if cw == nil {
+ return bgresize(bgrO, w, h, rw, rh)
+ }
+
+ var bgr *C.uchar
+ var bgrLen C.int
+ ret := C.resizebgr(cw.conv, unsafe.Pointer(&bgrO[0]), &bgr, &bgrLen)
+ if ret != 0 {
+ return nil
+ }
+ const maxLen = 0x7fffffff
+ goBGRLen := int(bgrLen)
+ if goBGRLen > 0 {
+ return (*[maxLen]byte)(unsafe.Pointer(bgr))[:goBGRLen:goBGRLen]
+ }
+ return nil
+}
+
+// ResizeYUV yuv
+func ResizeYUV(yuv []byte, w, h, rw, rh int) []byte {
+ if (rw < 0 && rh < 0) || (rw > w && rh > h) {
+ return yuv
+ }
+
+ cw := find(w, h, rw, rh)
+ if cw == nil {
+ return yuv
+ }
+
+ var resized *C.uchar
+ var resizedLen C.int
+ ret := C.resizeyuv(cw.conv, unsafe.Pointer(&yuv[0]), &resized, &resizedLen)
+ if ret != 0 {
+ return nil
+ }
+
+ const maxLen = 0x7fffffff
+ goResizedLen := int(resizedLen)
+ if goResizedLen > 0 {
+ return (*[maxLen]byte)(unsafe.Pointer(resized))[:goResizedLen:goResizedLen]
+ }
+ return nil
+}
+
+// YUV2BGRandResize conv and resize
+func YUV2BGRandResize(yuv []byte, w, h, rw, rh int) ([]byte, []byte) {
+ cw := find(w, h, rw, rh)
+ if cw == nil {
+ origin := yuv2bgr(yuv, w, h)
+ resized := bgresize(origin, w, h, rw, rh)
+ return origin, resized
+ }
+
+ var bgr *C.uchar
+ var bgrLen C.int
+ var scale *C.uchar
+ var scaleLen C.int
+
+ ret := C.yuv2bgrandresize(cw.conv, unsafe.Pointer(&yuv[0]), &bgr, &bgrLen, &scale, &scaleLen)
+
+ if ret != 0 {
+ return nil, nil
+ }
+ var out, resized []byte
+
+ const maxLen = 0x7fffffff
+ goBGRLen, goScaleLen := int(bgrLen), int(scaleLen)
+ if goBGRLen > 0 {
+ out = (*[maxLen]byte)(unsafe.Pointer(bgr))[:goBGRLen:goBGRLen]
+ }
+ if goScaleLen > 0 {
+ resized = (*[maxLen]byte)(unsafe.Pointer(scale))[:goScaleLen:goScaleLen]
+ }
+ return out, resized
+
+}
+
+// Free free
+func Free() {
+ for _, v := range convts {
+ if v.conv != nil {
+ C.conv_destroy(v.conv)
+ }
+ }
+}
+
+func yuv2bgr(yuv []byte, w, h int) []byte {
+
+ data := make([]byte, 0, w*h*3)
+ start := w * h
+ for i := 0; i < h; i++ {
+ for j := 0; j < w; j++ {
+
+ index := i/2*w + j - (j & 0x01)
+
+ y := int32(yuv[j+i*w])
+ v := int32(yuv[start+index])
+ u := int32(yuv[start+index+1])
+
+ r := y + (140*(v-128))/100
+ g := y - (34*(u-128)+71*(v-128))/100
+ b := y + (177*(u-128))/100
+
+ if r > 255 {
+ r = 255
+ }
+ if r < 0 {
+ r = 0
+ }
+ if g > 255 {
+ g = 255
+ }
+ if g < 0 {
+ g = 0
+ }
+ if b > 255 {
+ b = 255
+ }
+ if b < 0 {
+ b = 0
+ }
+ data = append(data, byte(r), byte(g), byte(b))
+ }
+ }
+ return data
+}
+
+func bgresize(bgr []byte, w, h, rw, rh int) []byte {
+ img, err := godraw.ToImage(bgr, w, h)
+ if err != nil {
+ return nil
+ }
+ dstImg := imaging.Resize(img, rw, rh, imaging.NearestNeighbor)
+ return godraw.Image2BGR(dstImg)
+}
--
Gitblit v1.8.0