Skip to content

Commit

Permalink
Merge 22 11 22 (#49)
Browse files Browse the repository at this point in the history
* Original image type (davidbyttow#299)

* - add golden

* - freeCString abstraction

* When implicitly converting the image type (BMP to PNG), keep the original format available for query

* gaussian blur support min_ampl (davidbyttow#307)

Co-authored-by: muyouran <muyouran@pinduoduo.com>

* Add APIs to get image EXIF data and ICC profile data (davidbyttow#317)

* Add support for high-bit-depth AVIF and HEIF images (davidbyttow#322)

* Fix bug with icc transform bit depth (davidbyttow#323)

* Determine libvips version runtime (davidbyttow#320)

* add ExtractBandToImage (davidbyttow#324)

* Update image.go

Add function to extract a band into a new image instead of replacing the current image ref

* Update image.go

* add test

Co-authored-by: Roffe <roffe@roffe.nu>

* BandSplit() split an n-band image into n separate images (davidbyttow#326)

* BandSplit() split an n-band image into n separate images

* move tests

Co-authored-by: Roffe <roffe@roffe.nu>

* Bump CI to latest Ubuntu (davidbyttow#329)

* Improved exif extraction (davidbyttow#325)

* Add support for reading + writing EXIF data

* Fix test for removing exif

* Cleanup tests

* Fix removes exif test on ubuntu

* TIFF may not iptc data

* Cleanup test images

* add images for ubuntu 22 lts (davidbyttow#328)

Co-authored-by: Roffe <roffe@roffe.nu>

* don't use deprecated functions

Co-authored-by: Qisen <1620671486@qq.com>
Co-authored-by: muyouran <muyouran@pinduoduo.com>
Co-authored-by: Logan Shire <logan.shire@gmail.com>
Co-authored-by: tgmpje <65441725+tgmpje@users.noreply.github.com>
Co-authored-by: Joakim Karlsson <5434736+roffe@users.noreply.github.com>
Co-authored-by: Roffe <roffe@roffe.nu>
Co-authored-by: Toni Melisma <59022391+tonimelisma@users.noreply.github.com>
  • Loading branch information
8 people authored Nov 22, 2022
1 parent 5eb41a8 commit 224a27b
Show file tree
Hide file tree
Showing 128 changed files with 561 additions and 99 deletions.
9 changes: 3 additions & 6 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
CGO_CFLAGS_ALLOW: -Xpreprocessor
strategy:
matrix:
os: [ubuntu-20.04, macos-11]
os: [ubuntu-22.04, macos-11]

steps:
- name: Set up Go 1.x
Expand All @@ -22,11 +22,8 @@ jobs:
uses: actions/checkout@v2

- name: Install linux deps
if: matrix.os == 'ubuntu-20.04'
if: matrix.os == 'ubuntu-22.04'
run: |
sudo add-apt-repository -y ppa:strukturag/libde265
sudo add-apt-repository -y ppa:strukturag/libheif
sudo add-apt-repository -y ppa:tonimelisma/ppa
sudo apt-get -y install libopenjp2-7
sudo apt-get -y install libvips-dev
Expand All @@ -46,7 +43,7 @@ jobs:
run: go test -v -coverprofile=profile.cov ./...

- name: Coveralls
if: matrix.os == 'ubuntu-20.04'
if: matrix.os == 'ubuntu-22.04'
uses: shogo82148/actions-goveralls@v1
with:
path-to-profile: profile.cov
Binary file not shown.
Binary file not shown.
File renamed without changes.
Binary file added resources/bmp.Decode_BMP-linux-jammy.golden.png
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.
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.
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.
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.
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.
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.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
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.
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.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
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.
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.
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.
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.
Binary file added resources/jpg-24bit.Add-linux-jammy.golden.jpeg
Binary file added resources/jpg-24bit.Black-linux-jammy.golden.jpeg
Binary file added resources/jpg-24bit.Embed-linux-jammy.golden.jpeg
Binary file added resources/jpg-24bit.Flip-linux-jammy.golden.jpeg
Binary file modified resources/jpg-24bit.GaussianBlur-macos-12.golden.jpeg
Binary file added resources/jpg-24bit.Zoom-linux-jammy.golden.jpeg
Binary file not shown.
Binary file not shown.
Binary file added resources/png-24bit.Rank-linux-jammy.golden.png
Binary file not shown.
Binary file not shown.
Binary file added resources/tif-16bit.tif
Binary file not shown.
Binary file not shown.
Binary file added resources/tif.Tiff-macos-13.golden.tiff
Binary file not shown.
Binary file added resources/with_alpha.Flatten-linux-jammy.golden.png
7 changes: 2 additions & 5 deletions vips/color.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@ package vips

// #include "color.h"
import "C"
import (
"unsafe"
)

// Color represents an RGB
type Color struct {
Expand Down Expand Up @@ -80,11 +77,11 @@ func vipsICCTransform(in *C.VipsImage, outputProfile string, inputProfile string
var cEmbedded C.gboolean

cOutputProfile := C.CString(outputProfile)
defer C.free(unsafe.Pointer(cOutputProfile))
defer freeCString(cOutputProfile)

if inputProfile != "" {
cInputProfile = C.CString(inputProfile)
defer C.free(unsafe.Pointer(cInputProfile))
defer freeCString(cInputProfile)
}

if embedded {
Expand Down
10 changes: 10 additions & 0 deletions vips/conversion.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
#include "conversion.h"

int copy_image_changing_interpretation(VipsImage *in, VipsImage **out,
VipsInterpretation interpretation) {
return vips_copy(in, out, "interpretation", interpretation, NULL);
}

int copy_image_changing_resolution(VipsImage *in, VipsImage **out, double xres,
double yres) {
return vips_copy(in, out, "xres", xres, "yres", yres, NULL);
}

int copy_image(VipsImage *in, VipsImage **out) {
return vips_copy(in, out, NULL);
}
Expand Down
20 changes: 20 additions & 0 deletions vips/conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,26 @@ const (
InterestingLast Interesting = C.VIPS_INTERESTING_LAST
)

func vipsCopyImageChangingInterpretation(in *C.VipsImage, interpretation Interpretation) (*C.VipsImage, error) {
var out *C.VipsImage

if err := C.copy_image_changing_interpretation(in, &out, C.VipsInterpretation(interpretation)); int(err) != 0 {
return nil, handleImageError(out)
}

return out, nil
}

func vipsCopyImageChangingResolution(in *C.VipsImage, xres float64, yres float64) (*C.VipsImage, error) {
var out *C.VipsImage

if err := C.copy_image_changing_resolution(in, &out, C.double(xres), C.double(yres)); int(err) != 0 {
return nil, handleImageError(out)
}

return out, nil
}

// https://libvips.github.io/libvips/API/current/libvips-conversion.html#vips-copy
func vipsCopyImage(in *C.VipsImage) (*C.VipsImage, error) {
var out *C.VipsImage
Expand Down
4 changes: 4 additions & 0 deletions vips/conversion.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
#include <stdlib.h>
#include <vips/vips.h>

int copy_image_changing_interpretation(VipsImage *in, VipsImage **out,
VipsInterpretation interpretation);
int copy_image_changing_resolution(VipsImage *in, VipsImage **out, double xres,
double yres);
int copy_image(VipsImage *in, VipsImage **out);

int embed_image(VipsImage *in, VipsImage **out, int left, int top, int width,
Expand Down
4 changes: 2 additions & 2 deletions vips/convolution.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include "convolution.h"

int gaussian_blur_image(VipsImage *in, VipsImage **out, double sigma) {
return vips_gaussblur(in, out, sigma, NULL);
int gaussian_blur_image(VipsImage *in, VipsImage **out, double sigma, double min_ampl) {
return vips_gaussblur(in, out, sigma, "min_ampl", min_ampl, NULL);
}

int sharpen_image(VipsImage *in, VipsImage **out, double sigma, double x1,
Expand Down
4 changes: 2 additions & 2 deletions vips/convolution.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ package vips
import "C"

// https://libvips.github.io/libvips/API/current/libvips-convolution.html#vips-gaussblur
func vipsGaussianBlur(in *C.VipsImage, sigma float64) (*C.VipsImage, error) {
func vipsGaussianBlur(in *C.VipsImage, sigma, minAmpl float64) (*C.VipsImage, error) {
incOpCounter("gaussblur")
var out *C.VipsImage

if err := C.gaussian_blur_image(in, &out, C.double(sigma)); err != 0 {
if err := C.gaussian_blur_image(in, &out, C.double(sigma), C.double(minAmpl)); err != 0 {
return nil, handleImageError(out)
}

Expand Down
2 changes: 1 addition & 1 deletion vips/convolution.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
#include <stdlib.h>
#include <vips/vips.h>

int gaussian_blur_image(VipsImage *in, VipsImage **out, double sigma);
int gaussian_blur_image(VipsImage *in, VipsImage **out, double sigma, double min_ampl);
int sharpen_image(VipsImage *in, VipsImage **out, double sigma, double x1,
double m2);
66 changes: 45 additions & 21 deletions vips/foreign.c
Original file line number Diff line number Diff line change
Expand Up @@ -294,26 +294,13 @@ int set_webpsave_options(VipsOperation *operation, SaveParams *params) {
return ret;
}

// https://github.com/libvips/libvips/blob/master/libvips/foreign/heifsave.c#L653
int set_heifsave_options(VipsOperation *operation, SaveParams *params) {
int ret = vips_object_set(VIPS_OBJECT(operation), "lossless",
params->heifLossless, NULL);

if (!ret && params->quality) {
ret = vips_object_set(VIPS_OBJECT(operation), "Q", params->quality, NULL);
}

return ret;
}

// https://libvips.github.io/libvips/API/current/VipsForeignSave.html#vips-tiffsave-buffer
int set_tiffsave_options(VipsOperation *operation, SaveParams *params) {
int ret = vips_object_set(
VIPS_OBJECT(operation), "strip", params->stripMetadata, "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);
params->tiffTileWidth, "tile", params->tiffTile, NULL);

if (!ret && params->quality) {
ret = vips_object_set(VIPS_OBJECT(operation), "Q", params->quality, NULL);
Expand Down Expand Up @@ -348,10 +335,49 @@ int set_gifsave_options(VipsOperation *operation, SaveParams *params) {
return ret;
}

// https://github.com/libvips/libvips/blob/master/libvips/foreign/heifsave.c#L653
int set_heifsave_options(VipsOperation *operation, SaveParams *params) {
int ret = vips_object_set(VIPS_OBJECT(operation), "lossless",
params->heifLossless, NULL);

#if (VIPS_MAJOR_VERSION >= 8) && (VIPS_MINOR_VERSION >= 13)
if (!ret && params->heifBitdepth && params->heifEffort) {
ret = vips_object_set(VIPS_OBJECT(operation), "bitdepth",
params->heifBitdepth, "effort", params->heifEffort,
NULL);
}
#else
if (!ret && params->heifEffort) {
ret = vips_object_set(VIPS_OBJECT(operation), "speed", params->heifEffort,
NULL);
}
#endif

if (!ret && params->quality) {
ret = vips_object_set(VIPS_OBJECT(operation), "Q", params->quality, NULL);
}

return ret;
}

// https://github.com/libvips/libvips/blob/master/libvips/foreign/heifsave.c#L653
int set_avifsave_options(VipsOperation *operation, SaveParams *params) {
int ret = vips_object_set(
VIPS_OBJECT(operation), "compression", VIPS_FOREIGN_HEIF_COMPRESSION_AV1,
"lossless", params->heifLossless, "speed", params->avifSpeed, NULL);
int ret = vips_object_set(VIPS_OBJECT(operation), "compression",
VIPS_FOREIGN_HEIF_COMPRESSION_AV1, "lossless",
params->heifLossless, NULL);

#if (VIPS_MAJOR_VERSION >= 8) && (VIPS_MINOR_VERSION >= 13)
if (!ret && params->heifBitdepth && params->heifEffort) {
ret = vips_object_set(VIPS_OBJECT(operation), "bitdepth",
params->heifBitdepth, "effort", params->heifEffort,
NULL);
}
#else
if (!ret && params->heifEffort) {
ret = vips_object_set(VIPS_OBJECT(operation), "speed", params->heifEffort,
NULL);
}
#endif

if (!ret && params->quality) {
ret = vips_object_set(VIPS_OBJECT(operation), "Q", params->quality, NULL);
Expand Down Expand Up @@ -494,18 +520,16 @@ static SaveParams defaultSaveParams = {
.webpReductionEffort = 4,
.webpIccProfile = NULL,

.heifBitdepth = 8,
.heifLossless = FALSE,
.heifEffort = 5,

.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,

.avifSpeed = 5,

.jp2kLossless = FALSE,
.jp2kTileHeight = 512,
Expand Down
13 changes: 11 additions & 2 deletions vips/foreign.go
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ func isBMP(buf []byte) bool {
return bytes.HasPrefix(buf, bmpHeader)
}

//X'0000 000C 6A50 2020 0D0A 870A'
// X'0000 000C 6A50 2020 0D0A 870A'
var jp2kHeader = []byte("\x00\x00\x00\x0C\x6A\x50\x20\x20\x0D\x0A\x87\x0A")

// https://datatracker.ietf.org/doc/html/rfc3745
Expand Down Expand Up @@ -406,19 +406,28 @@ func vipsSaveHEIFToBuffer(in *C.VipsImage, params HeifExportParams) ([]byte, err
p.outputFormat = C.HEIF
p.quality = C.int(params.Quality)
p.heifLossless = C.int(boolToInt(params.Lossless))
p.heifBitdepth = C.int(params.Bitdepth)
p.heifEffort = C.int(params.Effort)

return vipsSaveToBuffer(p)
}

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

// Speed was deprecated but we want to avoid breaking code that still uses it:
effort := params.Effort
if params.Speed != 0 {
effort = params.Speed
}

p := C.create_save_params(C.AVIF)
p.inputImage = in
p.outputFormat = C.AVIF
p.quality = C.int(params.Quality)
p.heifLossless = C.int(boolToInt(params.Lossless))
p.avifSpeed = C.int(params.Speed)
p.heifBitdepth = C.int(params.Bitdepth)
p.heifEffort = C.int(effort)

return vipsSaveToBuffer(p)
}
Expand Down
11 changes: 4 additions & 7 deletions vips/foreign.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,10 @@ typedef struct SaveParams {
int webpReductionEffort;
char *webpIccProfile;

// HEIF
BOOL heifLossless;
// HEIF - https://github.com/libvips/libvips/blob/master/libvips/foreign/heifsave.c#L71
int heifBitdepth; // Bitdepth to save at for >8 bit images
BOOL heifLossless; // Lossless compression
int heifEffort; // CPU effort (0 - 9)

// TIFF
VipsForeignTiffCompression tiffCompression;
Expand All @@ -117,11 +119,6 @@ typedef struct SaveParams {
BOOL tiffTile;
int tiffTileHeight;
int tiffTileWidth;
double tiffXRes;
double tiffYRes;

// AVIF
int avifSpeed;

// JPEG2000
BOOL jp2kLossless;
Expand Down
2 changes: 1 addition & 1 deletion vips/foreign_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ func Test_DetermineImageType__BMP(t *testing.T) {
func Test_DetermineImageType__AVIF(t *testing.T) {
Startup(&Config{})

buf, err := ioutil.ReadFile(resources + "avif.avif")
buf, err := ioutil.ReadFile(resources + "avif-8bit.avif")
assert.NoError(t, err)
assert.NotNil(t, buf)

Expand Down
30 changes: 15 additions & 15 deletions vips/govips.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,6 @@ import (
"sync"
)

// Version is the full libvips version string (x.y.z)
const Version = string(C.VIPS_VERSION)

// MajorVersion is the libvips major component of the version string (x in x.y.z)
const MajorVersion = int(C.VIPS_MAJOR_VERSION)

// MinorVersion is the libvips minor component of the version string (y in x.y.z)
const MinorVersion = int(C.VIPS_MINOR_VERSION)

// MicroVersion is the libvips micro component of the version string (z in x.y.z)
// Also known as patch version
const MicroVersion = int(C.VIPS_MICRO_VERSION)

const (
defaultConcurrencyLevel = 1
defaultMaxCacheMem = 50 * 1024 * 1024
Expand All @@ -34,6 +21,19 @@ const (
)

var (
// Version is the full libvips version string (x.y.z)
Version = C.GoString(C.vips_version_string())

// MajorVersion is the libvips major component of the version string (x in x.y.z)
MajorVersion = int(C.vips_version(0))

// MinorVersion is the libvips minor component of the version string (y in x.y.z)
MinorVersion = int(C.vips_version(1))

// MicroVersion is the libvips micro component of the version string (z in x.y.z)
// Also known as patch version
MicroVersion = int(C.vips_version(2))

running = false
hasShutdown = false
initLock sync.Mutex
Expand Down Expand Up @@ -72,11 +72,11 @@ func Startup(config *Config) {
return
}

if C.VIPS_MAJOR_VERSION < 8 {
if MajorVersion < 8 {
panic("govips requires libvips version 8.10+")
}

if C.VIPS_MAJOR_VERSION == 8 && C.VIPS_MINOR_VERSION < 10 {
if MajorVersion == 8 && MinorVersion < 10 {
panic("govips requires libvips version 8.10+")
}

Expand Down
Loading

0 comments on commit 224a27b

Please sign in to comment.