Skip to content

Commit

Permalink
Add method to write file to io.Writer
Browse files Browse the repository at this point in the history
  • Loading branch information
fancycode committed Aug 27, 2024
1 parent c377680 commit 7cf4ee9
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 3 deletions.
52 changes: 49 additions & 3 deletions context.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,34 @@
package libheif

// #cgo pkg-config: libheif
// #include <stdlib.h>
// #include <string.h>
// #include <libheif/heif.h>
/*
#include <stdlib.h>
#include <string.h>
#include <libheif/heif.h>
extern struct heif_error writeGo(void* data, size_t size, void* userdata);
struct heif_error writeCgo(struct heif_context* ctx, const void* data, size_t size, void* userdata) {
struct heif_error err = writeGo((char*)data, size, userdata);
if (!err.message) {
switch (err.code) {
case heif_error_Ok:
err.message = "Success";
break;
default:
err.message = "Error writing";
break;
}
}
return err;
}
*/
import "C"

import (
"errors"
"fmt"
"io"
"runtime"
"unsafe"
)
Expand Down Expand Up @@ -112,6 +132,32 @@ func (c *Context) NewEncoder(compression CompressionFormat) (*Encoder, error) {
return c.convertEncoderDescriptor(descriptors[0])
}

// Write saves the current image.
func (c *Context) Write(w io.Writer) error {
defer runtime.KeepAlive(c)

writer := &C.struct_heif_writer{
writer_api_version: 1,

write: (*[0]byte)(C.writeCgo),
}
writerData := &writerData{
w: w,
}

var p runtime.Pinner
p.Pin(w)
defer p.Unpin()

err := C.heif_context_write(c.context, writer, unsafe.Pointer(writerData))
if writerData.err != nil {
// Bubble up error returned by passed io.Writer
return writerData.err
}

return convertHeifError(err)
}

// WriteToFile saves the current image to the given file.
func (c *Context) WriteToFile(filename string) error {
defer runtime.KeepAlive(c)
Expand Down
62 changes: 62 additions & 0 deletions context_writer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* Go interface to libheif
*
* Copyright (c) 2018-2024 struktur AG, Joachim Bauch <[email protected]>
*
* libheif is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* libheif is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with libheif. If not, see <http://www.gnu.org/licenses/>.
*/
package libheif

// #cgo pkg-config: libheif
/*
#include <stdlib.h>
#include <string.h>
#include <libheif/heif.h>
*/
import "C"

import (
"io"
"unsafe"
)

type writerData struct {
w io.Writer
err error
}

//export writeGo
func writeGo(data *C.void, size C.size_t, userdata *C.void) C.struct_heif_error {
writer := (*writerData)(unsafe.Pointer(userdata))
if writer.err != nil {
return C.struct_heif_error{
code: C.heif_error_Ok,
subcode: C.heif_suberror_Unspecified,
}
}

_, err := writer.w.Write(C.GoBytes(unsafe.Pointer(data), C.int(size)))
if err != nil {
writer.err = err
return C.struct_heif_error{
code: C.heif_error_Usage_error,
subcode: C.heif_suberror_Unspecified,
}
}

return C.struct_heif_error{
code: C.heif_error_Ok,
subcode: C.heif_suberror_Unspecified,
}
}

0 comments on commit 7cf4ee9

Please sign in to comment.