mirror of
https://github.com/mickael-kerjean/filestash
synced 2025-12-06 08:22:24 +01:00
143 lines
3.7 KiB
C
143 lines
3.7 KiB
C
#include <string.h>
|
|
#include <png.h>
|
|
#include <stdlib.h>
|
|
#include "webp/encode.h"
|
|
#include "utils.h"
|
|
|
|
static int MyWriter(const uint8_t* data, size_t data_size, const WebPPicture* const pic) {
|
|
FILE* const out = (FILE*)pic->custom_ptr;
|
|
return data_size ? (fwrite(data, data_size, 1, out) == 1) : 1;
|
|
}
|
|
|
|
int png_to_webp(FILE* input, FILE* output, int targetSize) {
|
|
WebPPicture picture;
|
|
|
|
#ifdef HAS_DEBUG
|
|
clock_t t;
|
|
t = clock();
|
|
#endif
|
|
png_image image;
|
|
memset(&image, 0, sizeof image);
|
|
image.version = PNG_IMAGE_VERSION;
|
|
DEBUG("reading png");
|
|
if (!png_image_begin_read_from_stdio(&image, input)) {
|
|
ERROR("png_image_begin_read_from_stdio");
|
|
return 1;
|
|
}
|
|
DEBUG("allocate");
|
|
png_bytep buffer;
|
|
image.format = PNG_FORMAT_RGBA;
|
|
buffer = malloc(PNG_IMAGE_SIZE(image));
|
|
if (buffer == NULL) {
|
|
ERROR("png_malloc");
|
|
png_image_free(&image);
|
|
return 1;
|
|
}
|
|
DEBUG("start reading");
|
|
if (!png_image_finish_read(&image, NULL, buffer, 0, NULL)) {
|
|
ERROR("png_image_finish_read");
|
|
png_image_free(&image);
|
|
free(buffer);
|
|
return 1;
|
|
}
|
|
|
|
/////////////////////////////////////////////
|
|
// encode to webp
|
|
DEBUG("start encoding");
|
|
if (!WebPPictureInit(&picture)) {
|
|
ERROR("WebPPictureInit");
|
|
png_image_free(&image);
|
|
free(buffer);
|
|
return 1;
|
|
}
|
|
picture.width = image.width;
|
|
picture.height = image.height;
|
|
if(!WebPPictureAlloc(&picture)) {
|
|
ERROR("WebPPictureAlloc");
|
|
png_image_free(&image);
|
|
free(buffer);
|
|
return 1;
|
|
}
|
|
DEBUG("start encoding import");
|
|
WebPPictureImportRGBA(&picture, buffer, PNG_IMAGE_ROW_STRIDE(image));
|
|
png_image_free(&image);
|
|
free(buffer);
|
|
|
|
WebPConfig webp_config_output;
|
|
picture.writer = MyWriter;
|
|
picture.custom_ptr = output;
|
|
DEBUG("start encoding config init");
|
|
if (!WebPConfigInit(&webp_config_output)) {
|
|
ERROR("ERR config init");
|
|
WebPPictureFree(&picture);
|
|
return 1;
|
|
}
|
|
webp_config_output.method = 0;
|
|
webp_config_output.quality = 30;
|
|
if (!WebPValidateConfig(&webp_config_output)) {
|
|
ERROR("ERR WEB VALIDATION");
|
|
WebPPictureFree(&picture);
|
|
return 1;
|
|
}
|
|
DEBUG("rescale start");
|
|
if (image.width > targetSize && image.height > targetSize) {
|
|
float ratioHeight = (float) image.height / targetSize;
|
|
float ratioWidth = (float) image.width / targetSize;
|
|
float ratio = ratioWidth > ratioHeight ? ratioHeight : ratioWidth;
|
|
if (!WebPPictureRescale(&picture, image.width / ratio, image.height / ratio)) {
|
|
DEBUG("ERR Rescale");
|
|
WebPPictureFree(&picture);
|
|
return 1;
|
|
}
|
|
}
|
|
DEBUG("encoder start");
|
|
WebPEncode(&webp_config_output, &picture);
|
|
DEBUG("encoder done");
|
|
WebPPictureFree(&picture);
|
|
DEBUG("cleaning up");
|
|
return 0;
|
|
}
|
|
|
|
int png_to_png(FILE* input, FILE* output, int targetSize) {
|
|
#ifdef HAS_DEBUG
|
|
clock_t t;
|
|
t = clock();
|
|
#endif
|
|
png_image image;
|
|
memset(&image, 0, sizeof image);
|
|
image.version = PNG_IMAGE_VERSION;
|
|
DEBUG("> reading png");
|
|
if (!png_image_begin_read_from_stdio(&image, input)) {
|
|
DEBUG("png_image_begin_read_from_stdio");
|
|
return 1;
|
|
}
|
|
DEBUG("> allocate");
|
|
png_bytep buffer;
|
|
image.format = PNG_FORMAT_RGBA;
|
|
buffer = malloc(PNG_IMAGE_SIZE(image));
|
|
if (buffer == NULL) {
|
|
DEBUG("png_malloc");
|
|
png_image_free(&image);
|
|
return 1;
|
|
}
|
|
DEBUG("> start reading");
|
|
if (!png_image_finish_read(&image, NULL, buffer, 0, NULL)) {
|
|
DEBUG("png_image_finish_read");
|
|
png_image_free(&image);
|
|
free(buffer);
|
|
return 1;
|
|
}
|
|
|
|
DEBUG("> write");
|
|
if (!png_image_write_to_stdio(&image, output, 0, buffer, 0, NULL)) {
|
|
DEBUG("png_image_write_to_stdio");
|
|
png_image_free(&image);
|
|
free(buffer);
|
|
return 1;
|
|
}
|
|
|
|
DEBUG("> end");
|
|
png_image_free(&image);
|
|
free(buffer);
|
|
return 0;
|
|
}
|