mirror of
https://github.com/mickael-kerjean/filestash
synced 2025-12-27 10:42:36 +01:00
fix (thumbnail): memory leak found using ab
This commit is contained in:
parent
e0b31a34d2
commit
2f74a00879
5 changed files with 33 additions and 25 deletions
|
|
@ -140,7 +140,8 @@ func Init(conf *Configuration) {
|
|||
/////////////////////////
|
||||
// Specify transformation
|
||||
transform := &lib.Transform{
|
||||
Temporary: GetAbsolutePath(ImageCachePath + "image_" + QuickString(10)),
|
||||
Input: GetAbsolutePath(ImageCachePath + "imagein_" + QuickString(10)),
|
||||
Output: GetAbsolutePath(ImageCachePath + "imageout_" + QuickString(10)),
|
||||
Size: thumb_size(),
|
||||
Crop: true,
|
||||
Quality: thumb_quality(),
|
||||
|
|
@ -163,7 +164,7 @@ func Init(conf *Configuration) {
|
|||
/////////////////////////////
|
||||
// Insert file in the fs
|
||||
// => lower RAM usage while processing
|
||||
file, err := os.OpenFile(transform.Temporary, os.O_WRONLY|os.O_CREATE, os.ModePerm)
|
||||
file, err := os.OpenFile(transform.Input, os.O_WRONLY|os.O_CREATE, os.ModePerm)
|
||||
if err != nil {
|
||||
return reader, ErrFilesystemError
|
||||
}
|
||||
|
|
@ -171,7 +172,8 @@ func Init(conf *Configuration) {
|
|||
file.Close()
|
||||
reader.Close()
|
||||
defer func() {
|
||||
os.Remove(transform.Temporary)
|
||||
os.Remove(transform.Input)
|
||||
os.Remove(transform.Output)
|
||||
}()
|
||||
|
||||
/////////////////////////
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ func IsRaw(mType string) bool {
|
|||
}
|
||||
|
||||
func ExtractPreview(t *Transform) error {
|
||||
filename := C.CString(t.Temporary)
|
||||
filename := C.CString(t.Input)
|
||||
err := C.raw_process(filename, C.int(t.Size))
|
||||
if err == LIBRAW_MEMORY_ERROR {
|
||||
// libraw acts weird sometimes and I couldn't
|
||||
|
|
|
|||
|
|
@ -1,17 +1,16 @@
|
|||
#include <stdlib.h>
|
||||
#include <vips/vips.h>
|
||||
|
||||
int resizer_init(const int ncpu, const int cache_max, const int cache_mem){
|
||||
int resizer_init(const int ncpu){
|
||||
if(VIPS_INIT("filestash")){
|
||||
return 1;
|
||||
}
|
||||
vips_concurrency_set(100);
|
||||
vips_cache_set_max(cache_max);
|
||||
vips_cache_set_max_mem(cache_mem);
|
||||
vips_concurrency_set(1);
|
||||
vips_cache_set_max(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int resizer_process(const char *filename, void **buf, size_t *len, int size, int crop, int quality, int exif){
|
||||
int resizer_process(const char *input, const char *output, int size, int crop, int quality, int exif){
|
||||
VipsImage *img;
|
||||
int err;
|
||||
|
||||
|
|
@ -22,7 +21,7 @@ int resizer_process(const char *filename, void **buf, size_t *len, int size, int
|
|||
|
||||
if(crop == VIPS_INTERESTING_CENTRE){
|
||||
// Generate a thumbnails: a square picture crop in the center
|
||||
err = vips_thumbnail(filename, &img, size,
|
||||
err = vips_thumbnail(input, &img, size,
|
||||
"size", VIPS_SIZE_BOTH,
|
||||
"auto_rotate", TRUE,
|
||||
"crop", VIPS_INTERESTING_CENTRE,
|
||||
|
|
@ -30,7 +29,7 @@ int resizer_process(const char *filename, void **buf, size_t *len, int size, int
|
|||
);
|
||||
}else{
|
||||
// normal resize of an image with libvips
|
||||
err = vips_thumbnail(filename, &img, size,
|
||||
err = vips_thumbnail(input, &img, size,
|
||||
"size", VIPS_SIZE_DOWN,
|
||||
"auto_rotate", TRUE,
|
||||
"crop", VIPS_INTERESTING_NONE,
|
||||
|
|
@ -41,7 +40,7 @@ int resizer_process(const char *filename, void **buf, size_t *len, int size, int
|
|||
return err;
|
||||
}
|
||||
|
||||
err = vips_jpegsave_buffer(img, buf, len, "Q", quality, "strip", exif, NULL);
|
||||
err = vips_jpegsave(img, output, NULL);
|
||||
g_object_unref(img);
|
||||
return err;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,14 +8,20 @@ import "C"
|
|||
import (
|
||||
. "github.com/mickael-kerjean/filestash/server/common"
|
||||
"io"
|
||||
"os"
|
||||
"runtime"
|
||||
"unsafe"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var LIBVIPS_INSTALLED = false
|
||||
var (
|
||||
LIBVIPS_INSTALLED = false
|
||||
VIPS_LOCK = &sync.Mutex{}
|
||||
)
|
||||
|
||||
type Transform struct {
|
||||
Temporary string
|
||||
Input string
|
||||
Output string
|
||||
Size int
|
||||
Crop bool
|
||||
Quality int
|
||||
|
|
@ -23,7 +29,7 @@ type Transform struct {
|
|||
}
|
||||
|
||||
func init() {
|
||||
if C.resizer_init(C.int(runtime.NumCPU()), 50, 1024) != 0 {
|
||||
if C.resizer_init(C.int(runtime.NumCPU())) != 0 {
|
||||
Log.Warning("Can't load libvips")
|
||||
return
|
||||
}
|
||||
|
|
@ -34,17 +40,18 @@ func CreateThumbnail(t *Transform) (io.ReadCloser, error) {
|
|||
if LIBVIPS_INSTALLED == false {
|
||||
return nil, NewError("Libvips not installed", 501)
|
||||
}
|
||||
filename := C.CString(t.Temporary)
|
||||
defer C.free(unsafe.Pointer(filename))
|
||||
var buffer unsafe.Pointer
|
||||
len := C.size_t(0)
|
||||
filenameInput := C.CString(t.Input)
|
||||
defer C.free(unsafe.Pointer(filenameInput))
|
||||
|
||||
if C.resizer_process(filename, &buffer, &len, C.int(t.Size), boolToCInt(t.Crop), C.int(t.Quality), boolToCInt(t.Exif)) != 0 {
|
||||
filenameOutput := C.CString(t.Output)
|
||||
defer C.free(unsafe.Pointer(filenameOutput))
|
||||
|
||||
VIPS_LOCK.Lock()
|
||||
if C.resizer_process(filenameInput, filenameOutput, C.int(t.Size), boolToCInt(t.Crop), C.int(t.Quality), boolToCInt(t.Exif)) != 0 {
|
||||
return nil, NewError("", 500)
|
||||
}
|
||||
buf := C.GoBytes(buffer, C.int(len))
|
||||
C.g_free(C.gpointer(buffer))
|
||||
return NewReadCloserFromBytes(buf), nil
|
||||
VIPS_LOCK.Unlock()
|
||||
return os.OpenFile(t.Output, os.O_RDONLY, os.ModePerm)
|
||||
}
|
||||
|
||||
func boolToCInt(val bool) C.int {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#include <stdlib.h>
|
||||
#include <vips/vips.h>
|
||||
|
||||
int resizer_init(const int ncpu, const int cache_max, const int cache_mem);
|
||||
int resizer_init(const int ncpu);
|
||||
|
||||
int resizer_process(const char *filename, void **buf, size_t *len, int size, int crop, int quality, int exif);
|
||||
int resizer_process(const char *input, const char *output, int size, int crop, int quality, int exif);
|
||||
|
|
|
|||
Loading…
Reference in a new issue