diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f102392..71f7218 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,7 +12,7 @@ on: jobs: test: - name: Test ImageMagick6 + name: Test ImageMagick6 linux runs-on: ubuntu-latest environment: imagemagick6 env: @@ -31,3 +31,40 @@ jobs: -v $PWD/.cache/go-build:/root/.cache/go-build \ -v $PWD/.cache/go/pkg:/go/pkg \ "$DOCKER_IMAGE" + + test_windows: + name: Test ImageMagick6 windows + runs-on: windows-latest + steps: + - name: Checkout + uses: actions/checkout@v1 + with: + fetch-depth: 1 + + - name: Setup go + uses: actions/setup-go@v4.0.1 + with: + go-version: 1.20.6 + + - name: Setup MSYS2 + uses: msys2/setup-msys2@v2 + with: + update: true + install: >- + base-devel + mingw-w64-x86_64-toolchain + mingw-w64-x86_64-pkg-config + mingw-w64-x86_64-imagemagick=6.9.2.10 + + - name: Install deps + shell: msys2 {0} + run: | + /c/hostedtoolcache/windows/go/1.20.6/x64/bin/go.exe env + pkg-config --cflags --libs MagickWand + MAGICK_CONFIGURE_PATH=/d/a/_temp/msys/msys64/mingw64/etc/ImageMagick-6-9 convert -list configure + + - name: Test + shell: msys2 {0} + run: > + MAGICK_CONFIGURE_PATH=/d/a/_temp/msys/msys64/mingw64/etc/ImageMagick-6-9 + /c/hostedtoolcache/windows/go/1.20.6/x64/bin/go.exe test -v ./imagick diff --git a/imagick/magick_wand_image.go b/imagick/magick_wand_image.go index 38ba2f1..f3c77da 100644 --- a/imagick/magick_wand_image.go +++ b/imagick/magick_wand_image.go @@ -3380,11 +3380,17 @@ func (mw *MagickWand) WriteImagesFile(out *os.File) error { // cfdopen returns a C-level FILE*. mode should be as described in fdopen(3). // Caller is responsible for closing the file when successfully returned, // via C.fclose() -func cfdopen(file *os.File, mode string) (*C.FILE, error) { +func cfdopen(file *os.File, mode string) (cfile *C.FILE, err error) { + cname := C.CString(file.Name()) cmode := C.CString(mode) + defer C.free(unsafe.Pointer(cname)) defer C.free(unsafe.Pointer(cmode)) - cfile, err := C.fdopen(C.dup(C.int(file.Fd())), cmode) + if file.Name() != "" { + cfile, err = C.fopen(cname, cmode) + } else { + cfile, err = C.fdopen(C.dup(C.int(file.Fd())), cmode) + } if err != nil { return nil, err } diff --git a/imagick/magick_wand_test.go b/imagick/magick_wand_test.go index 94e030f..b5477a0 100644 --- a/imagick/magick_wand_test.go +++ b/imagick/magick_wand_test.go @@ -6,6 +6,8 @@ package imagick import ( "fmt" + "io/ioutil" + "os" "reflect" "runtime" "sync/atomic" @@ -127,6 +129,33 @@ func TestDeleteImageArtifact(t *testing.T) { } } +func TestReadImageFile(t *testing.T) { + Initialize() + defer Terminate() + + mw := NewMagickWand() + if err := mw.ReadImage(`logo:`); err != nil { + t.Fatal(err) + } + + tmp, err := ioutil.TempFile("", "imagick_test-*.jpg") + if err != nil { + t.Fatal(err) + } + defer os.Remove(tmp.Name()) + + if err := mw.WriteImage(tmp.Name()); err != nil { + t.Fatal(err) + } + mw.Destroy() + + mw = NewMagickWand() + defer mw.Destroy() + if err := mw.ReadImageFile(tmp); err != nil { + t.Fatal(err) + } +} + func TestReadImageBlob(t *testing.T) { Initialize() defer func(t *testing.T) { diff --git a/imagick/memory.go b/imagick/memory.go index d92079a..3bd4ba1 100644 --- a/imagick/memory.go +++ b/imagick/memory.go @@ -23,6 +23,9 @@ func relinquishMemory(ptr unsafe.Pointer) { // relinquishes memory resources, null terminated array of strings func relinquishMemoryCStringArray(p **C.char) { + if p == nil { + return + } defer relinquishMemory(unsafe.Pointer(p)) for *p != nil { relinquishMemory(unsafe.Pointer(*p))