Skip to content

Commit

Permalink
Adds more options and default parameters in C
Browse files Browse the repository at this point in the history
  • Loading branch information
davidbyttow committed Jan 7, 2021
1 parent f471817 commit 8d03fa0
Show file tree
Hide file tree
Showing 7 changed files with 163 additions and 118 deletions.
Binary file added resources/jpg-24bit.Black-macos.golden.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added resources/jpg-24bit.DrawRect-macos.golden.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
140 changes: 78 additions & 62 deletions vips/foreign.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "lang.h"
#include "foreign.h"

#include "lang.h"

int load_image_buffer(void *buf, size_t len, int imageType, VipsImage **out) {
int code = 1;

Expand Down Expand Up @@ -31,89 +32,104 @@ int load_image_buffer(void *buf, size_t len, int imageType, VipsImage **out) {

// https://libvips.github.io/libvips/API/current/VipsForeignSave.html#vips-jpegsave-buffer
int save_jpeg_buffer(SaveParams *params) {
return vips_jpegsave_buffer(params->inputImage,
&params->outputBuffer,
&params->outputLen,
"strip", INT_TO_GBOOLEAN(params->stripMetadata),
"Q", params->quality,
"optimize_coding", TRUE,
"interlace", INT_TO_GBOOLEAN(params->interlace),
"subsample_mode", VIPS_FOREIGN_JPEG_SUBSAMPLE_ON,
NULL);
return vips_jpegsave_buffer(
params->inputImage, &params->outputBuffer, &params->outputLen, "strip",
params->stripMetadata, "Q", params->quality, "optimize_coding",
params->jpegOptimizeCoding, "interlace", params->interlace,
"subsample_mode", params->jpegSubsample, NULL);
}

// https://libvips.github.io/libvips/API/current/VipsForeignSave.html#vips-pngsave-buffer
int save_png_buffer(SaveParams *params) {
return vips_pngsave_buffer(params->inputImage,
&params->outputBuffer,
&params->outputLen,
"strip", INT_TO_GBOOLEAN(params->stripMetadata),
"compression", params->pngCompression,
"interlace", INT_TO_GBOOLEAN(params->interlace),
"filter", VIPS_FOREIGN_PNG_FILTER_NONE,
NULL);
return vips_pngsave_buffer(
params->inputImage, &params->outputBuffer, &params->outputLen, "strip",
params->stripMetadata, "compression", params->pngCompression, "interlace",
params->interlace, "filter", params->pngFilter, NULL);
}

// todo: support additional params
// https://github.com/libvips/libvips/blob/master/libvips/foreign/webpsave.c#L524
// https://libvips.github.io/libvips/API/current/VipsForeignSave.html#vips-webpsave-buffer
int save_webp_buffer(SaveParams *params) {
return vips_webpsave_buffer(params->inputImage,
&params->outputBuffer,
&params->outputLen,
"strip", INT_TO_GBOOLEAN(params->stripMetadata),
"Q", params->quality,
"lossless", INT_TO_GBOOLEAN(params->webpLossless),
"reduction_effort", params->webpReductionEffort,
NULL);
return vips_webpsave_buffer(
params->inputImage, &params->outputBuffer, &params->outputLen, "strip",
params->stripMetadata, "Q", params->quality, "lossless",
params->webpLossless, "reduction_effort", params->webpReductionEffort,
NULL);
}

// todo: support additional params
// https://github.com/libvips/libvips/blob/master/libvips/foreign/heifsave.c#L653
int save_heif_buffer(SaveParams *params) {
return vips_heifsave_buffer(params->inputImage,
&params->outputBuffer,
&params->outputLen,
"Q", params->quality,
"lossless", INT_TO_GBOOLEAN(params->heifLossless),
NULL);
return vips_heifsave_buffer(params->inputImage, &params->outputBuffer,
&params->outputLen, "Q", params->quality,
"lossless", params->heifLossless, NULL);
}

// https://libvips.github.io/libvips/API/current/VipsForeignSave.html#vips-tiffsave-buffer
int save_tiff_buffer(SaveParams *params) {
return vips_tiffsave_buffer(params->inputImage,
&params->outputBuffer,
&params->outputLen,
"strip", INT_TO_GBOOLEAN(params->stripMetadata),
"Q", params->quality,
"compression", params->tiffCompression,
"pyramid", FALSE,
"predictor", VIPS_FOREIGN_TIFF_PREDICTOR_HORIZONTAL,
"pyramid", FALSE,
"tile", FALSE,
"tile_height", 256,
"tile_width", 256,
"xres", 1.0,
"yres", 1.0,
NULL);
return vips_tiffsave_buffer(
params->inputImage, &params->outputBuffer, &params->outputLen, "strip",
params->stripMetadata, "Q", params->quality, "compression",
params->tiffCompression, "predictor", params->tiffPredictor, "pyramid",
params->tiffPyramid, "tile_height", params->tiffTileHeight, "tile_width",
params->tiffTileWidth, "tile", params->tiffTile, "xres", params->tiffXRes,
"yres", params->tiffYRes, NULL);
}

int save_to_buffer(SaveParams *params) {
switch (params->outputFormat)
{
case JPEG:
return save_jpeg_buffer(params);
case PNG:
return save_png_buffer(params);
case WEBP:
return save_webp_buffer(params);
case HEIF:
return save_heif_buffer(params);
case TIFF:
return save_tiff_buffer(params);
default:
g_warning("Unsupported output type given: %d", params->outputFormat);
return -1;
switch (params->outputFormat) {
case JPEG:
return save_jpeg_buffer(params);
case PNG:
return save_png_buffer(params);
case WEBP:
return save_webp_buffer(params);
case HEIF:
return save_heif_buffer(params);
case TIFF:
return save_tiff_buffer(params);
default:
g_warning("Unsupported output type given: %d", params->outputFormat);
return -1;
}
}

static SaveParams defaultSaveParams = {
inputImage : NULL,
outputBuffer : NULL,
outputFormat : JPEG,
outputLen : 0,

interlace : FALSE,
quality : 0,
stripMetadata : FALSE,

jpegOptimizeCoding : FALSE,
jpegSubsample : VIPS_FOREIGN_JPEG_SUBSAMPLE_ON,

pngCompression : 6,
pngFilter : VIPS_FOREIGN_PNG_FILTER_NONE,

webpLossless : FALSE,
webpReductionEffort : 4,

heifLossless : FALSE,

tiffCompression : VIPS_FOREIGN_TIFF_COMPRESSION_LZW,
tiffPredictor : VIPS_FOREIGN_TIFF_PREDICTOR_HORIZONTAL,
tiffPyramid : FALSE,
tiffTile : FALSE,
tiffTileHeight : 256,
tiffTileWidth : 256,
tiffXRes : 1.0,
tiffYRes : 1.0
};

SaveParams create_save_params(ImageType outputFormat) {
SaveParams params = defaultSaveParams;
params.outputFormat = outputFormat;
return params;
}

void init_save_params(SaveParams *params) { *params = defaultSaveParams; }
95 changes: 51 additions & 44 deletions vips/foreign.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,24 @@ type TiffCompression int

// TiffCompression enum
const (
TiffCompressionNone TiffCompression = C.VIPS_FOREIGN_TIFF_COMPRESSION_NONE
TiffCompressionLzw TiffCompression = C.VIPS_FOREIGN_TIFF_COMPRESSION_LZW
TiffCompressionNone TiffCompression = C.VIPS_FOREIGN_TIFF_COMPRESSION_NONE
TiffCompressionJpeg TiffCompression = C.VIPS_FOREIGN_TIFF_COMPRESSION_JPEG
TiffCompressionDeflate TiffCompression = C.VIPS_FOREIGN_TIFF_COMPRESSION_DEFLATE
TiffCompressionPackbits TiffCompression = C.VIPS_FOREIGN_TIFF_COMPRESSION_PACKBITS
TiffCompressionFax4 TiffCompression = C.VIPS_FOREIGN_TIFF_COMPRESSION_CCITTFAX4
TiffCompressionLzw TiffCompression = C.VIPS_FOREIGN_TIFF_COMPRESSION_LZW
TiffCompressionWebp TiffCompression = C.VIPS_FOREIGN_TIFF_COMPRESSION_WEBP
TiffCompressionZstd TiffCompression = C.VIPS_FOREIGN_TIFF_COMPRESSION_ZSTD
)

// TiffPredictor represents method for compressing a tiff at export
type TiffPredictor int

// TiffPredictor enum
const (
TiffPredictorNone TiffPredictor = C.VIPS_FOREIGN_TIFF_PREDICTOR_NONE
TiffPredictorHorizontal TiffPredictor = C.VIPS_FOREIGN_TIFF_PREDICTOR_HORIZONTAL
TiffPredictorFloat TiffPredictor = C.VIPS_FOREIGN_TIFF_PREDICTOR_FLOAT
)

// FileExt returns the canonical extension for the ImageType
Expand Down Expand Up @@ -236,72 +252,63 @@ func bmpToPNG(src []byte) ([]byte, error) {
return w.Bytes(), nil
}

func vipsSaveJPEGToBuffer(in *C.VipsImage, params JpegExportParams) ([]byte, error) {
incOpCounter("save_jpeg_buffer")

p := C.create_save_params(C.JPEG)
p.inputImage = in
p.stripMetadata = C.int(boolToInt(params.StripMetadata))
p.quality = C.int(params.Quality)
p.interlace = C.int(boolToInt(params.Interlace))

return vipsSaveToBuffer(p)
}

func vipsSavePNGToBuffer(in *C.VipsImage, params PngExportParams) ([]byte, error) {
incOpCounter("save_png_buffer")

p := C.struct_SaveParams{
inputImage: in,
outputFormat: C.PNG,
stripMetadata: C.int(boolToInt(params.StripMetadata)),
interlace: C.int(boolToInt(params.Interlace)),
pngCompression: C.int(params.Compression),
}
p := C.create_save_params(C.PNG)
p.inputImage = in
p.stripMetadata = C.int(boolToInt(params.StripMetadata))
p.interlace = C.int(boolToInt(params.Interlace))
p.pngCompression = C.int(params.Compression)

return vipsSaveToBuffer(p)
}

func vipsSaveWebPToBuffer(in *C.VipsImage, params WebpExportParams) ([]byte, error) {
incOpCounter("save_webp_buffer")

p := C.struct_SaveParams{
inputImage: in,
outputFormat: C.WEBP,
stripMetadata: C.int(boolToInt(params.StripMetadata)),
quality: C.int(params.Quality),
webpLossless: C.int(boolToInt(params.Lossless)),
webpReductionEffort: C.int(params.ReductionEffort),
}
p := C.create_save_params(C.WEBP)
p.inputImage = in
p.stripMetadata = C.int(boolToInt(params.StripMetadata))
p.quality = C.int(params.Quality)
p.webpLossless = C.int(boolToInt(params.Lossless))
p.webpReductionEffort = C.int(params.ReductionEffort)

return vipsSaveToBuffer(p)
}

func vipsSaveTIFFToBuffer(in *C.VipsImage, params TiffExportParams) ([]byte, error) {
incOpCounter("save_tiff_buffer")

p := C.struct_SaveParams{
inputImage: in,
outputFormat: C.TIFF,
stripMetadata: C.int(boolToInt(params.StripMetadata)),
quality: C.int(params.Quality),
tiffCompression: C.VipsForeignTiffCompression(params.Compression),
}
p := C.create_save_params(C.TIFF)
p.inputImage = in
p.stripMetadata = C.int(boolToInt(params.StripMetadata))
p.quality = C.int(params.Quality)
p.tiffCompression = C.VipsForeignTiffCompression(params.Compression)

return vipsSaveToBuffer(p)
}

func vipsSaveHEIFToBuffer(in *C.VipsImage, params HeifExportParams) ([]byte, error) {
incOpCounter("save_heif_buffer")

p := C.struct_SaveParams{
inputImage: in,
outputFormat: C.HEIF,
quality: C.int(params.Quality),
heifLossless: C.int(boolToInt(params.Lossless)),
}

return vipsSaveToBuffer(p)
}

func vipsSaveJPEGToBuffer(in *C.VipsImage, params JpegExportParams) ([]byte, error) {
incOpCounter("save_jpeg_buffer")

p := C.struct_SaveParams{
inputImage: in,
outputFormat: C.JPEG,
stripMetadata: C.int(boolToInt(params.StripMetadata)),
quality: C.int(params.Quality),
interlace: C.int(boolToInt(params.Interlace)),
}
p := C.create_save_params(C.HEIF)
p.inputImage = in
p.outputFormat = C.HEIF
p.quality = C.int(params.Quality)
p.heifLossless = C.int(boolToInt(params.Lossless))

return vipsSaveToBuffer(p)
}
Expand Down
44 changes: 32 additions & 12 deletions vips/foreign.h
Original file line number Diff line number Diff line change
@@ -1,25 +1,29 @@
// https://libvips.github.io/libvips/API/current/VipsForeignSave.html

// clang-format off
// include order matters
#include <stdlib.h>

#include <vips/vips.h>
#include <vips/foreign.h>
// clang-format n

#ifndef BOOL
#define BOOL int
#endif

typedef enum types {
UNKNOWN = 0,
JPEG,
WEBP,
PNG,
TIFF,
GIF,
PDF,
SVG,
MAGICK,
HEIF,
BMP
UNKNOWN = 0,
JPEG,
WEBP,
PNG,
TIFF,
GIF,
PDF,
SVG,
MAGICK,
HEIF,
BMP
} ImageType;

int load_image_buffer(void *buf, size_t len, int imageType, VipsImage **out);
Expand All @@ -33,9 +37,14 @@ typedef struct SaveParams {
BOOL stripMetadata;
int quality;
BOOL interlace;


// JPEG
BOOL jpegOptimizeCoding;
VipsForeignJpegSubsample jpegSubsample;

// PNG
int pngCompression;
VipsForeignPngFilter pngFilter;

// WEBP
BOOL webpLossless;
Expand All @@ -46,6 +55,17 @@ typedef struct SaveParams {

// TIFF
VipsForeignTiffCompression tiffCompression;
VipsForeignTiffPredictor tiffPredictor;
BOOL tiffPyramid;
BOOL tiffTile;
int tiffTileHeight;
int tiffTileWidth;
double tiffXRes;
double tiffYRes;

} SaveParams;

SaveParams create_save_params(ImageType outputFormat);
void init_save_params(SaveParams *params);

int save_to_buffer(SaveParams *params);
2 changes: 2 additions & 0 deletions vips/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,13 +174,15 @@ type TiffExportParams struct {
StripMetadata bool
Quality int
Compression TiffCompression
Predictor TiffPredictor
}

// NewTiffExportParams creates default values for an export of a TIFF image.
func NewTiffExportParams() *TiffExportParams {
return &TiffExportParams{
Quality: 80,
Compression: TiffCompressionLzw,
Predictor: TiffPredictorHorizontal,
}
}

Expand Down

0 comments on commit 8d03fa0

Please sign in to comment.