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