Skip to content

Commit

Permalink
Split Nearblack into Nearblack and NearblackInto functions, add…
Browse files Browse the repository at this point in the history
… tests, add missing `Close()`s
  • Loading branch information
pericles-tpt committed Sep 22, 2023
1 parent b95aaee commit 95b7d58
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 23 deletions.
44 changes: 34 additions & 10 deletions godal.go
Original file line number Diff line number Diff line change
Expand Up @@ -3849,7 +3849,12 @@ func (ds *Dataset) Grid(destPath string, switches []string, opts ...GridOption)
return &Dataset{majorObject{C.GDALMajorObjectH(dsRet)}}, nil
}

// NearBlack runs the library version of GDALNearblack.
// `Nearblack` and `NearblackInto` run the library version of GDALNearblack. The difference between them is:
// - Nearblack: Takes a `destPath` (string) as its first arg, the produced dataset will be output to this "file"
// and returned from the function
// - NearblackInto: Instead takes a `srcDs` (Dataset) as its first arg, the produced dataset will be stored in
// the `Dataset` this method was called from
//
// See the nearblack doc page to determine the valid flags/opts that can be set in switches.
//
// Example switches :
Expand All @@ -3862,7 +3867,7 @@ func (ds *Dataset) Grid(destPath string, switches []string, opts ...GridOption)
//
// NOTE: Some switches are NOT compatible with this binding, as a `nullptr` is passed to a later call to
// `GDALNearblackOptionsNew()` (as the 2nd argument). Those switches are: "-o", "-q", "-quiet"
func (ds *Dataset) Nearblack(destPath string, destDs *Dataset, switches []string, opts ...NearblackOption) (*Dataset, error) {
func (ds *Dataset) Nearblack(destPath string, switches []string, opts ...NearblackOption) (*Dataset, error) {
nearBlackOpts := nearBlackOpts{}
for _, opt := range opts {
opt.setNearblackOpt(&nearBlackOpts)
Expand All @@ -3872,20 +3877,39 @@ func (ds *Dataset) Nearblack(destPath string, destDs *Dataset, switches []string
defer cswitches.free()

dest := unsafe.Pointer(C.CString(destPath))
defer C.free(dest)

cgc := createCGOContext(nil, nearBlackOpts.errorHandler)
defer C.free(unsafe.Pointer(dest))

var dsRet C.GDALDatasetH
if destDs != nil {
dsRet = C.godalNearblack(cgc.cPointer(), (*C.char)(dest), destDs.handle(), ds.handle(), cswitches.cPointer())
} else {
dsRet = C.godalNearblack(cgc.cPointer(), (*C.char)(dest), nil, ds.handle(), cswitches.cPointer())
ret, err := C.godalNearblack(cgc.cPointer(), (*C.char)(dest), nil, ds.handle(), cswitches.cPointer())
if err = cgc.close(); err != nil {
return nil, err
}

return &Dataset{majorObject{C.GDALMajorObjectH(ret)}}, nil
}

func (ds *Dataset) NearblackInto(srcDs *Dataset, switches []string, opts ...NearblackOption) error {
nearBlackOpts := nearBlackOpts{}
for _, opt := range opts {
opt.setNearblackOpt(&nearBlackOpts)
}

cswitches := sliceToCStringArray(switches)
defer cswitches.free()

cgc := createCGOContext(nil, nearBlackOpts.errorHandler)

var srcDsHandle C.GDALDatasetH = nil
if srcDs != nil {
srcDsHandle = srcDs.handle()
}
_ = C.godalNearblack(cgc.cPointer(), nil, ds.handle(), srcDsHandle, cswitches.cPointer())
if err := cgc.close(); err != nil {
return nil, err
return err
}

return &Dataset{majorObject{C.GDALMajorObjectH(dsRet)}}, nil
return nil
}

type cgoContext struct {
Expand Down
89 changes: 76 additions & 13 deletions godal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4314,7 +4314,7 @@ func TestNearblackBlack(t *testing.T) {
// 2. Put the Dataset generated above, through the `Nearblack` function, to set pixels near BLACK to BLACK
argsNbString := "-near 10 -nb 0"
fname2 := "/vsimem/test1.tiff"
nbDs, err := gridDs.Nearblack(fname2, nil, strings.Split(argsNbString, " "))
nbDs, err := gridDs.Nearblack(fname2, strings.Split(argsNbString, " "))
if err != nil {
t.Error(err)
return
Expand Down Expand Up @@ -4343,11 +4343,13 @@ func TestNearblackWhite(t *testing.T) {
t.Error(err)
return
}
defer vrtDs.Close()
geom, err := NewGeometryFromWKT("POLYGON((0 0 255, 0 1 255, 1 1 0, 1 0 0))", nil)
if err != nil {
t.Error(err)
return
}
defer geom.Close()
_, err = vrtDs.CreateLayer("grid", nil, GTPolygon)
if err != nil {
t.Error(err)
Expand Down Expand Up @@ -4384,7 +4386,7 @@ func TestNearblackWhite(t *testing.T) {
// 2. Put the Dataset generated above, through the `Nearblack` function, to set pixels near WHITE to WHITE
argsNbString := "-near 10 -nb 0 -white"
fname2 := "/vsimem/test1.tiff"
nbDs, err := gridDs.Nearblack(fname2, nil, strings.Split(argsNbString, " "))
nbDs, err := gridDs.Nearblack(fname2, strings.Split(argsNbString, " "))
if err != nil {
t.Error(err)
return
Expand All @@ -4402,7 +4404,34 @@ func TestNearblackWhite(t *testing.T) {
}
}

func TestNearblackReplaceSrcDs(t *testing.T) {
func TestNearblackInvalidSwitch(t *testing.T) {
// 1. Create a linearly interpolated image that goes from white -> black, using `Grid()`
var (
outXSize = 256
outYSize = 256
)
fname := "/vsimem/test.tiff"
vrtDs, err := Create(Memory, fname, 1, Byte, outXSize, outYSize)
if err != nil {
t.Error(err)
return
}
defer func() { _ = VSIUnlink(fname) }()
defer vrtDs.Close()

// 2. Put the Dataset generated above, through the `Nearblack`
fname2 := "/vsimem/test1.tiff"

_, err = vrtDs.Nearblack(fname2, []string{"-invalidswitch"})
assert.Error(t, err)
ehc := eh()
_, err = vrtDs.Nearblack(fname2, []string{"-invalidswitch"}, ErrLogger(ehc.ErrorHandler))
assert.Error(t, err)

defer func() { _ = VSIUnlink(fname2) }()
}

func TestNearblackBlackInto(t *testing.T) {
// 1. Create an image, linearly interpolated, from black (on the left) to white (on the right), using `Grid()`
var (
outXSize = 256
Expand All @@ -4413,11 +4442,13 @@ func TestNearblackReplaceSrcDs(t *testing.T) {
t.Error(err)
return
}
defer vrtDs.Close()
geom, err := NewGeometryFromWKT("POLYGON((0 0 0, 0 1 0, 1 1 255, 1 0 255))", nil)
if err != nil {
t.Error(err)
return
}
defer geom.Close()
_, err = vrtDs.CreateLayer("grid", nil, GTPolygon)
if err != nil {
t.Error(err)
Expand Down Expand Up @@ -4452,16 +4483,20 @@ func TestNearblackReplaceSrcDs(t *testing.T) {
gridDs.Read(0, 0, originalColors, outXSize, outYSize)

// 2. Put the Dataset generated above, through the `Nearblack` function, to set pixels near BLACK to BLACK
nbDs, err := Create(Memory, "nbDs", 1, Byte, outXSize, outYSize)
if err != nil {
t.Error(err)
return
}
defer nbDs.Close()
argsNbString := "-near 10 -nb 0"
fname2 := "/vsimem/test1.tiff"
_, err = gridDs.Nearblack(fname2, gridDs, strings.Split(argsNbString, " "))
err = nbDs.NearblackInto(gridDs, strings.Split(argsNbString, " "))
if err != nil {
t.Error(err)
return
}
defer func() { _ = VSIUnlink(fname2) }()
nearblackColors := make([]byte, outXSize*outYSize)
gridDs.Read(0, 0, nearblackColors, outXSize, outYSize)
nbDs.Read(0, 0, nearblackColors, outXSize, outYSize)

// 3. Test on all rows that pixels where abs(0 - pixelValue) <= 10, are set to black (0)
for i := 0; i < outYSize; i++ {
Expand All @@ -4471,7 +4506,7 @@ func TestNearblackReplaceSrcDs(t *testing.T) {
}
}

func TestNearblackInvalidSwitch(t *testing.T) {
func TestNearblackIntoInvalidSwitch(t *testing.T) {
// 1. Create a linearly interpolated image that goes from white -> black, using `Grid()`
var (
outXSize = 256
Expand All @@ -4487,14 +4522,42 @@ func TestNearblackInvalidSwitch(t *testing.T) {
defer vrtDs.Close()

// 2. Put the Dataset generated above, through the `Nearblack`
nbDs := &Dataset{}
fname2 := "/vsimem/test1.tiff"
defer func() { _ = VSIUnlink(fname2) }()
nbDs, err := Create(Memory, "nbDs", 1, Byte, outXSize, outYSize)
if err != nil {
t.Error(err)
return
}
defer nbDs.Close()
err = nbDs.NearblackInto(vrtDs, []string{"-invalidswitch"})
assert.Error(t, err)
ehc := eh()
_, err = vrtDs.Nearblack(fname2, nbDs, []string{"-invalidswitch"}, ErrLogger(ehc.ErrorHandler))
err = nbDs.NearblackInto(vrtDs, []string{"-invalidswitch"}, ErrLogger(ehc.ErrorHandler))
assert.Error(t, err)
}

_, err = vrtDs.Nearblack(fname2, nbDs, []string{"-invalidswitch"})
func TestNearblackIntoNoSrcDs(t *testing.T) {
// 1. Create a linearly interpolated image that goes from white -> black, using `Grid()`
var (
outXSize = 256
outYSize = 256
)
fname := "/vsimem/test.tiff"
vrtDs, err := Create(Memory, fname, 1, Byte, outXSize, outYSize)
if err != nil {
t.Error(err)
return
}
defer func() { _ = VSIUnlink(fname) }()
defer vrtDs.Close()

// 2. Put the Dataset generated above, through the `Nearblack`
nbDs, err := Create(Memory, "nbDs", 1, Byte, outXSize, outYSize)
if err != nil {
t.Error(err)
return
}
defer nbDs.Close()
ehc := eh()
err = nbDs.NearblackInto(nil, []string{}, ErrLogger(ehc.ErrorHandler))
assert.Error(t, err)
}

0 comments on commit 95b7d58

Please sign in to comment.