mirror of
https://github.com/mickael-kerjean/filestash
synced 2025-12-06 08:22:24 +01:00
feature (thumb): support for webp
This commit is contained in:
parent
04ac23d0c7
commit
376fe22770
4 changed files with 119 additions and 0 deletions
106
server/plugin/plg_image_c/image_webp.c
Normal file
106
server/plugin/plg_image_c/image_webp.c
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <webp/decode.h>
|
||||
#include <webp/encode.h>
|
||||
#include "utils.h"
|
||||
|
||||
#define WEBP_QUALITY 75
|
||||
#define INITIAL_BUFFER_SIZE 1024*64 // 128kB
|
||||
#define MAX_BUFFER_SIZE 1024*1024*2 // 2MB
|
||||
|
||||
int webp_to_webp(int inputDesc, int outputDesc, int targetSize) {
|
||||
#ifdef HAS_DEBUG
|
||||
clock_t t;
|
||||
t = clock();
|
||||
#endif
|
||||
if (targetSize < 0) {
|
||||
targetSize = -targetSize;
|
||||
}
|
||||
int status = 0;
|
||||
FILE* input = fdopen(inputDesc, "rb");
|
||||
FILE* output = fdopen(outputDesc, "wb");
|
||||
if (!input || !output) {
|
||||
ERROR("setup");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// STEP1: setup everything
|
||||
size_t data_size = 0;
|
||||
size_t buffer_size = INITIAL_BUFFER_SIZE;
|
||||
uint8_t* data = (uint8_t*)malloc(buffer_size);
|
||||
if (!data) {
|
||||
ERROR("malloc");
|
||||
return 1;
|
||||
}
|
||||
size_t bytes_read;
|
||||
while ((bytes_read = fread(data + data_size, 1, buffer_size - data_size, input)) > 0) {
|
||||
data_size += bytes_read;
|
||||
if (buffer_size - data_size == 0) {
|
||||
DEBUG("realloc");
|
||||
if (buffer_size >= MAX_BUFFER_SIZE) {
|
||||
free(data);
|
||||
ERROR("abort");
|
||||
return 1;
|
||||
}
|
||||
buffer_size *= 2;
|
||||
if (buffer_size > MAX_BUFFER_SIZE) buffer_size = MAX_BUFFER_SIZE;
|
||||
uint8_t* new_data = (uint8_t*)realloc(data, buffer_size);
|
||||
if (!new_data) {
|
||||
free(data);
|
||||
ERROR("realloc");
|
||||
return 1;
|
||||
}
|
||||
data = new_data;
|
||||
}
|
||||
}
|
||||
|
||||
// STEP2: decode
|
||||
int width, height, scale_factor;
|
||||
if (!WebPGetInfo(data, data_size, &width, &height)) {
|
||||
free(data);
|
||||
ERROR("init");
|
||||
return 1;
|
||||
}
|
||||
DEBUG("init");
|
||||
WebPDecoderConfig config;
|
||||
if (!WebPInitDecoderConfig(&config)) {
|
||||
free(data);
|
||||
ERROR("config");
|
||||
return 1;
|
||||
}
|
||||
scale_factor = (height > targetSize) ? height / targetSize : 1;
|
||||
config.options.use_scaling = 1;
|
||||
config.options.scaled_width = width / scale_factor;
|
||||
config.options.scaled_height = height / scale_factor;
|
||||
config.output.colorspace = MODE_rgbA;
|
||||
DEBUG("config");
|
||||
if (WebPDecode(data, data_size, &config) != VP8_STATUS_OK) {
|
||||
WebPFreeDecBuffer(&config.output);
|
||||
free(data);
|
||||
ERROR("decode");
|
||||
return 1;
|
||||
}
|
||||
free(data);
|
||||
DEBUG("decode");
|
||||
|
||||
// STEP3: encode
|
||||
size_t output_size = 0;
|
||||
uint8_t* output_data = NULL;
|
||||
output_size = WebPEncodeRGBA(
|
||||
config.output.u.RGBA.rgba, config.options.scaled_width,
|
||||
config.options.scaled_height, config.output.u.RGBA.stride,
|
||||
WEBP_QUALITY, &output_data
|
||||
);
|
||||
if (output_data == NULL) {
|
||||
WebPFreeDecBuffer(&config.output);
|
||||
ERROR("encode");
|
||||
return 1;
|
||||
}
|
||||
DEBUG("encode");
|
||||
fwrite(output_data, output_size, 1, output);
|
||||
fflush(output);
|
||||
WebPFree(output_data);
|
||||
WebPFreeDecBuffer(&config.output);
|
||||
DEBUG("done");
|
||||
return status;
|
||||
}
|
||||
10
server/plugin/plg_image_c/image_webp.go
Normal file
10
server/plugin/plg_image_c/image_webp.go
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
package plg_image_c
|
||||
|
||||
// #include "image_webp.h"
|
||||
// #cgo LDFLAGS: -l:libwebp.a
|
||||
import "C"
|
||||
|
||||
func webp(input uintptr, output uintptr, size int) {
|
||||
C.webp_to_webp(C.int(input), C.int(output), C.int(size))
|
||||
return
|
||||
}
|
||||
1
server/plugin/plg_image_c/image_webp.h
Normal file
1
server/plugin/plg_image_c/image_webp.h
Normal file
|
|
@ -0,0 +1 @@
|
|||
int webp_to_webp(int inputDesc, int outputDesc, int targetSize);
|
||||
|
|
@ -30,6 +30,8 @@ func init() {
|
|||
Hooks.Register.Thumbnailer("image/png", &transcoder{runner(png), "image/webp", -200})
|
||||
Hooks.Register.Thumbnailer("image/gif", &transcoder{runner(gif), "image/webp", -300})
|
||||
Hooks.Register.Thumbnailer("image/heic", &transcoder{runner(heif), "image/jpeg", -200})
|
||||
Hooks.Register.Thumbnailer("image/webp", &transcoder{runner(webp), "image/webp", -200})
|
||||
|
||||
rawMimeType := []string{
|
||||
"image/x-canon-cr2", "image/x-tif", "image/x-canon-cr2", "image/x-canon-crw",
|
||||
"image/x-nikon-nef", "image/x-nikon-nrw", "image/x-sony-arw", "image/x-sony-sr2",
|
||||
|
|
|
|||
Loading…
Reference in a new issue