mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2025-12-31 01:10:20 -06:00
feat(thumbnails): optional libvips based thumbnail generation
Can be enabled by setting the 'enable_vips' tag on 'go build'
This commit is contained in:
committed by
Ralf Haferkamp
parent
358adc15dc
commit
a9a5570050
1
go.mod
1
go.mod
@@ -16,6 +16,7 @@ require (
|
||||
github.com/coreos/go-oidc/v3 v3.11.0
|
||||
github.com/cs3org/go-cs3apis v0.0.0-20240724121416-062c4e3046cb
|
||||
github.com/cs3org/reva/v2 v2.25.1-0.20241016145214-e5baaccf6614
|
||||
github.com/davidbyttow/govips/v2 v2.15.0
|
||||
github.com/dhowden/tag v0.0.0-20230630033851-978a0926ee25
|
||||
github.com/dutchcoders/go-clamd v0.0.0-20170520113014-b970184f4d9e
|
||||
github.com/egirna/icap-client v0.1.1
|
||||
|
||||
6
go.sum
6
go.sum
@@ -259,6 +259,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davidbyttow/govips/v2 v2.15.0 h1:h3lF+rQElBzGXbQSSPqmE3XGySPhcQo2x3t5l/dZ+pU=
|
||||
github.com/davidbyttow/govips/v2 v2.15.0/go.mod h1:3OQCHj0nf5Mnrplh5VlNvmx3IhJXyxbAoTJZPflUjmM=
|
||||
github.com/deckarep/golang-set v1.8.0 h1:sk9/l/KqpunDwP7pSjUg0keiOOLEnOBHzykLrsPppp4=
|
||||
github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS383rP6+o6qqo=
|
||||
github.com/deepmap/oapi-codegen v1.3.11/go.mod h1:suMvK7+rKlx3+tpa8ByptmvoXbAV70wERKTOGH3hLp0=
|
||||
@@ -845,6 +847,7 @@ github.com/nats-io/nkeys v0.4.7/go.mod h1:kqXRgRDPlGy7nGaEDMuYzmiJCIAAWDK0IMBtDm
|
||||
github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
|
||||
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
|
||||
github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/nrdcg/auroradns v1.0.1/go.mod h1:y4pc0i9QXYlFCWrhWrUSIETnZgrf4KuwjDIWmmXo3JI=
|
||||
github.com/nrdcg/desec v0.5.0/go.mod h1:2ejvMazkav1VdDbv2HeQO7w+Ta1CGHqzQr27ZBYTuEQ=
|
||||
github.com/nrdcg/dnspod-go v0.4.0/go.mod h1:vZSoFSFeQVm2gWLMkyX61LZ8HI3BaqtHZWgPTGKr6KQ=
|
||||
@@ -1248,6 +1251,7 @@ golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.10.0/go.mod h1:jtrku+n79PfroUbvDdeUWMAI+heR786BofxrbiSF+J0=
|
||||
golang.org/x/image v0.20.0 h1:7cVCUjQwfL18gyBJOmYvptfSHS8Fb3YUDtfLIZ7Nbpw=
|
||||
golang.org/x/image v0.20.0/go.mod h1:0a88To4CYVBAHp5FXJm8o7QbUl37Vd85ply1vyD8auM=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
@@ -1468,6 +1472,7 @@ golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
|
||||
@@ -1640,6 +1645,7 @@ gopkg.in/cenkalti/backoff.v1 v1.1.0/go.mod h1:J6Vskwqd+OMVJl8C33mmtxTBs2gyzfv7UD
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
//go:build !enable_vips
|
||||
|
||||
package preprocessor
|
||||
|
||||
import (
|
||||
|
||||
20
services/thumbnails/pkg/preprocessor/preprocessor_vips.go
Normal file
20
services/thumbnails/pkg/preprocessor/preprocessor_vips.go
Normal file
@@ -0,0 +1,20 @@
|
||||
//go:build enable_vips
|
||||
|
||||
package preprocessor
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"github.com/davidbyttow/govips/v2/vips"
|
||||
)
|
||||
|
||||
func init() {
|
||||
vips.LoggingSettings(nil, vips.LogLevelError)
|
||||
}
|
||||
|
||||
type ImageDecoder struct{}
|
||||
|
||||
func (v ImageDecoder) Convert(r io.Reader) (interface{}, error) {
|
||||
img, err := vips.NewImageFromReader(r)
|
||||
return img, err
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
//go:build !enable_vips
|
||||
|
||||
package thumbnail
|
||||
|
||||
import (
|
||||
|
||||
66
services/thumbnails/pkg/thumbnail/encoding_vips.go
Normal file
66
services/thumbnails/pkg/thumbnail/encoding_vips.go
Normal file
@@ -0,0 +1,66 @@
|
||||
//go:build enable_vips
|
||||
|
||||
package thumbnail
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"github.com/davidbyttow/govips/v2/vips"
|
||||
"github.com/owncloud/ocis/v2/services/thumbnails/pkg/errors"
|
||||
)
|
||||
|
||||
// PngEncoder encodes to png
|
||||
type PngEncoder struct{}
|
||||
|
||||
// Encode encodes to png format
|
||||
func (e PngEncoder) Encode(w io.Writer, img interface{}) error {
|
||||
m, ok := img.(*vips.ImageRef)
|
||||
if !ok {
|
||||
return errors.ErrInvalidType
|
||||
}
|
||||
|
||||
buf, _, err := m.ExportPng(vips.NewPngExportParams())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = w.Write(buf)
|
||||
return err
|
||||
}
|
||||
|
||||
// Types returns the png suffix
|
||||
func (e PngEncoder) Types() []string {
|
||||
return []string{typePng}
|
||||
}
|
||||
|
||||
// MimeType returns the mimetype for png files.
|
||||
func (e PngEncoder) MimeType() string {
|
||||
return "image/png"
|
||||
}
|
||||
|
||||
// JpegEncoder encodes to jpg
|
||||
type JpegEncoder struct{}
|
||||
|
||||
// Encode encodes to jpg
|
||||
func (e JpegEncoder) Encode(w io.Writer, img interface{}) error {
|
||||
m, ok := img.(*vips.ImageRef)
|
||||
if !ok {
|
||||
return errors.ErrInvalidType
|
||||
}
|
||||
|
||||
buf, _, err := m.ExportJpeg(vips.NewJpegExportParams())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = w.Write(buf)
|
||||
return err
|
||||
}
|
||||
|
||||
// Types returns the jpg suffixes.
|
||||
func (e JpegEncoder) Types() []string {
|
||||
return []string{typeJpeg, typeJpg}
|
||||
}
|
||||
|
||||
// MimeType returns the mimetype for jpg files.
|
||||
func (e JpegEncoder) MimeType() string {
|
||||
return "image/jpeg"
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
//go:build !enable_vips
|
||||
|
||||
package thumbnail
|
||||
|
||||
import (
|
||||
|
||||
62
services/thumbnails/pkg/thumbnail/generator_vips.go
Normal file
62
services/thumbnails/pkg/thumbnail/generator_vips.go
Normal file
@@ -0,0 +1,62 @@
|
||||
//go:build enable_vips
|
||||
|
||||
package thumbnail
|
||||
|
||||
import (
|
||||
"image"
|
||||
"strings"
|
||||
|
||||
"github.com/davidbyttow/govips/v2/vips"
|
||||
"github.com/owncloud/ocis/v2/services/thumbnails/pkg/errors"
|
||||
)
|
||||
|
||||
// SimpleGenerator is the default image generator and is used for all image types expect gif.
|
||||
type SimpleGenerator struct {
|
||||
crop vips.Interesting
|
||||
size vips.Size
|
||||
process string
|
||||
}
|
||||
|
||||
func NewSimpleGenerator(filetype, process string) (SimpleGenerator, error) {
|
||||
switch strings.ToLower(process) {
|
||||
case "thumbnail":
|
||||
return SimpleGenerator{crop: vips.InterestingAttention, process: process, size: vips.SizeBoth}, nil
|
||||
case "fit":
|
||||
return SimpleGenerator{crop: vips.InterestingNone, process: process, size: vips.SizeBoth}, nil
|
||||
case "resize":
|
||||
return SimpleGenerator{crop: vips.InterestingNone, process: process, size: vips.SizeForce}, nil
|
||||
default:
|
||||
return SimpleGenerator{crop: vips.InterestingNone, process: process}, nil
|
||||
}
|
||||
}
|
||||
|
||||
// ProcessorID returns the processor identification.
|
||||
func (g SimpleGenerator) ProcessorID() string {
|
||||
return g.process
|
||||
}
|
||||
|
||||
// Generate generates a alternative image version.
|
||||
func (g SimpleGenerator) Generate(size image.Rectangle, img interface{}) (interface{}, error) {
|
||||
m, ok := img.(*vips.ImageRef)
|
||||
if !ok {
|
||||
return nil, errors.ErrInvalidType
|
||||
}
|
||||
|
||||
if err := m.ThumbnailWithSize(size.Dx(), 0, g.crop, g.size); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := m.RemoveMetadata(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (g SimpleGenerator) Dimensions(img interface{}) (image.Rectangle, error) {
|
||||
m, ok := img.(*vips.ImageRef)
|
||||
if !ok {
|
||||
return image.Rectangle{}, errors.ErrInvalidType
|
||||
}
|
||||
return image.Rect(0, 0, m.Width(), m.Height()), nil
|
||||
}
|
||||
24
vendor/github.com/davidbyttow/govips/v2/LICENSE
generated
vendored
Normal file
24
vendor/github.com/davidbyttow/govips/v2/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
The MIT License
|
||||
|
||||
Copyright (c) Simple Things LLC and contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
71
vendor/github.com/davidbyttow/govips/v2/vips/arithmetic.c
generated
vendored
Normal file
71
vendor/github.com/davidbyttow/govips/v2/vips/arithmetic.c
generated
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
#include "arithmetic.h"
|
||||
|
||||
int add(VipsImage *left, VipsImage *right, VipsImage **out) {
|
||||
return vips_add(left, right, out, NULL);
|
||||
}
|
||||
|
||||
int multiply(VipsImage *left, VipsImage *right, VipsImage **out) {
|
||||
return vips_multiply(left, right, out, NULL);
|
||||
}
|
||||
|
||||
int divide(VipsImage *left, VipsImage *right, VipsImage **out) {
|
||||
return vips_divide(left, right, out, NULL);
|
||||
}
|
||||
|
||||
int linear(VipsImage *in, VipsImage **out, double *a, double *b, int n) {
|
||||
return vips_linear(in, out, a, b, n, NULL);
|
||||
}
|
||||
|
||||
int linear1(VipsImage *in, VipsImage **out, double a, double b) {
|
||||
return vips_linear1(in, out, a, b, NULL);
|
||||
}
|
||||
|
||||
int invert_image(VipsImage *in, VipsImage **out) {
|
||||
return vips_invert(in, out, NULL);
|
||||
}
|
||||
|
||||
int average(VipsImage *in, double *out) {
|
||||
return vips_avg(in, out, NULL);
|
||||
}
|
||||
|
||||
int find_trim(VipsImage *in, int *left, int *top, int *width, int *height,
|
||||
double threshold, double r, double g, double b) {
|
||||
|
||||
if (in->Type == VIPS_INTERPRETATION_RGB16 || in->Type == VIPS_INTERPRETATION_GREY16) {
|
||||
r = 65535 * r / 255;
|
||||
g = 65535 * g / 255;
|
||||
b = 65535 * b / 255;
|
||||
}
|
||||
|
||||
double background[3] = {r, g, b};
|
||||
VipsArrayDouble *vipsBackground = vips_array_double_new(background, 3);
|
||||
|
||||
int code = vips_find_trim(in, left, top, width, height, "threshold", threshold, "background", vipsBackground, NULL);
|
||||
|
||||
vips_area_unref(VIPS_AREA(vipsBackground));
|
||||
return code;
|
||||
}
|
||||
|
||||
int getpoint(VipsImage *in, double **vector, int n, int x, int y) {
|
||||
return vips_getpoint(in, vector, &n, x, y, NULL);
|
||||
}
|
||||
|
||||
int stats(VipsImage *in, VipsImage **out) {
|
||||
return vips_stats(in, out, NULL);
|
||||
}
|
||||
|
||||
int hist_find(VipsImage *in, VipsImage **out) {
|
||||
return vips_hist_find(in, out, NULL);
|
||||
}
|
||||
|
||||
int hist_cum(VipsImage *in, VipsImage **out) {
|
||||
return vips_hist_cum(in, out, NULL);
|
||||
}
|
||||
|
||||
int hist_norm(VipsImage *in, VipsImage **out) {
|
||||
return vips_hist_norm(in, out, NULL);
|
||||
}
|
||||
|
||||
int hist_entropy(VipsImage *in, double *out) {
|
||||
return vips_hist_entropy(in, out, NULL);
|
||||
}
|
||||
176
vendor/github.com/davidbyttow/govips/v2/vips/arithmetic.go
generated
vendored
Normal file
176
vendor/github.com/davidbyttow/govips/v2/vips/arithmetic.go
generated
vendored
Normal file
@@ -0,0 +1,176 @@
|
||||
package vips
|
||||
|
||||
// #include "arithmetic.h"
|
||||
import "C"
|
||||
import "unsafe"
|
||||
|
||||
// https://libvips.github.io/libvips/API/current/libvips-arithmetic.html#vips-add
|
||||
func vipsAdd(left *C.VipsImage, right *C.VipsImage) (*C.VipsImage, error) {
|
||||
incOpCounter("add")
|
||||
var out *C.VipsImage
|
||||
|
||||
if err := C.add(left, right, &out); err != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// https://libvips.github.io/libvips/API/current/libvips-arithmetic.html#vips-multiply
|
||||
func vipsMultiply(left *C.VipsImage, right *C.VipsImage) (*C.VipsImage, error) {
|
||||
incOpCounter("multiply")
|
||||
var out *C.VipsImage
|
||||
|
||||
if err := C.multiply(left, right, &out); err != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// https://libvips.github.io/libvips/API/current/libvips-arithmetic.html#vips-divide
|
||||
func vipsDivide(left *C.VipsImage, right *C.VipsImage) (*C.VipsImage, error) {
|
||||
incOpCounter("divide")
|
||||
var out *C.VipsImage
|
||||
|
||||
if err := C.divide(left, right, &out); err != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// https://libvips.github.io/libvips/API/current/libvips-arithmetic.html#vips-linear
|
||||
func vipsLinear(in *C.VipsImage, a, b []float64, n int) (*C.VipsImage, error) {
|
||||
incOpCounter("linear")
|
||||
var out *C.VipsImage
|
||||
|
||||
if err := C.linear(in, &out, (*C.double)(&a[0]), (*C.double)(&b[0]), C.int(n)); err != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// https://libvips.github.io/libvips/API/current/libvips-arithmetic.html#vips-linear1
|
||||
func vipsLinear1(in *C.VipsImage, a, b float64) (*C.VipsImage, error) {
|
||||
incOpCounter("linear1")
|
||||
var out *C.VipsImage
|
||||
|
||||
if err := C.linear1(in, &out, C.double(a), C.double(b)); err != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// https://libvips.github.io/libvips/API/current/libvips-arithmetic.html#vips-invert
|
||||
func vipsInvert(in *C.VipsImage) (*C.VipsImage, error) {
|
||||
incOpCounter("invert")
|
||||
var out *C.VipsImage
|
||||
|
||||
if err := C.invert_image(in, &out); err != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// https://libvips.github.io/libvips/API/current/libvips-arithmetic.html#vips-avg
|
||||
func vipsAverage(in *C.VipsImage) (float64, error) {
|
||||
incOpCounter("average")
|
||||
var out C.double
|
||||
|
||||
if err := C.average(in, &out); err != 0 {
|
||||
return 0, handleVipsError()
|
||||
}
|
||||
|
||||
return float64(out), nil
|
||||
}
|
||||
|
||||
// https://libvips.github.io/libvips/API/current/libvips-arithmetic.html#vips-find-trim
|
||||
func vipsFindTrim(in *C.VipsImage, threshold float64, backgroundColor *Color) (int, int, int, int, error) {
|
||||
incOpCounter("findTrim")
|
||||
var left, top, width, height C.int
|
||||
|
||||
if err := C.find_trim(in, &left, &top, &width, &height, C.double(threshold), C.double(backgroundColor.R),
|
||||
C.double(backgroundColor.G), C.double(backgroundColor.B)); err != 0 {
|
||||
return -1, -1, -1, -1, handleVipsError()
|
||||
}
|
||||
|
||||
return int(left), int(top), int(width), int(height), nil
|
||||
}
|
||||
|
||||
// https://libvips.github.io/libvips/API/current/libvips-arithmetic.html#vips-getpoint
|
||||
func vipsGetPoint(in *C.VipsImage, n int, x int, y int) ([]float64, error) {
|
||||
incOpCounter("getpoint")
|
||||
var out *C.double
|
||||
defer gFreePointer(unsafe.Pointer(out))
|
||||
|
||||
if err := C.getpoint(in, &out, C.int(n), C.int(x), C.int(y)); err != 0 {
|
||||
return nil, handleVipsError()
|
||||
}
|
||||
|
||||
// maximum n is 4
|
||||
return (*[4]float64)(unsafe.Pointer(out))[:n:n], nil
|
||||
}
|
||||
|
||||
// https://www.libvips.org/API/current/libvips-arithmetic.html#vips-stats
|
||||
func vipsStats(in *C.VipsImage) (*C.VipsImage, error) {
|
||||
incOpCounter("stats")
|
||||
var out *C.VipsImage
|
||||
|
||||
if err := C.stats(in, &out); err != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// https://www.libvips.org/API/current/libvips-arithmetic.html#vips-hist-find
|
||||
func vipsHistFind(in *C.VipsImage) (*C.VipsImage, error) {
|
||||
incOpCounter("histFind")
|
||||
var out *C.VipsImage
|
||||
|
||||
if err := C.hist_find(in, &out); err != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// https://www.libvips.org/API/current/libvips-histogram.html#vips-hist-norm
|
||||
func vipsHistNorm(in *C.VipsImage) (*C.VipsImage, error) {
|
||||
incOpCounter("histNorm")
|
||||
var out *C.VipsImage
|
||||
|
||||
if err := C.hist_norm(in, &out); err != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// https://www.libvips.org/API/current/libvips-histogram.html#vips-hist-cum
|
||||
func vipsHistCum(in *C.VipsImage) (*C.VipsImage, error) {
|
||||
incOpCounter("histCum")
|
||||
var out *C.VipsImage
|
||||
|
||||
if err := C.hist_cum(in, &out); err != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// https://www.libvips.org/API/current/libvips-histogram.html#vips-hist-entropy
|
||||
func vipsHistEntropy(in *C.VipsImage) (float64, error) {
|
||||
incOpCounter("histEntropy")
|
||||
var out C.double
|
||||
|
||||
if err := C.hist_entropy(in, &out); err != 0 {
|
||||
return 0, handleVipsError()
|
||||
}
|
||||
|
||||
return float64(out), nil
|
||||
}
|
||||
20
vendor/github.com/davidbyttow/govips/v2/vips/arithmetic.h
generated
vendored
Normal file
20
vendor/github.com/davidbyttow/govips/v2/vips/arithmetic.h
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
// https://libvips.github.io/libvips/API/current/libvips-arithmetic.html
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <vips/vips.h>
|
||||
|
||||
int add(VipsImage *left, VipsImage *right, VipsImage **out);
|
||||
int multiply(VipsImage *left, VipsImage *right, VipsImage **out);
|
||||
int divide(VipsImage *left, VipsImage *right, VipsImage **out);
|
||||
int linear(VipsImage *in, VipsImage **out, double *a, double *b, int n);
|
||||
int linear1(VipsImage *in, VipsImage **out, double a, double b);
|
||||
int invert_image(VipsImage *in, VipsImage **out);
|
||||
int average(VipsImage *in, double *out);
|
||||
int find_trim(VipsImage *in, int *left, int *top, int *width, int *height,
|
||||
double threshold, double r, double g, double b);
|
||||
int getpoint(VipsImage *in, double **vector, int n, int x, int y);
|
||||
int stats(VipsImage *in, VipsImage **out);
|
||||
int hist_find(VipsImage *in, VipsImage **out);
|
||||
int hist_cum(VipsImage *in, VipsImage **out);
|
||||
int hist_norm(VipsImage *in, VipsImage **out);
|
||||
int hist_entropy(VipsImage *in, double *out);
|
||||
22
vendor/github.com/davidbyttow/govips/v2/vips/color.c
generated
vendored
Normal file
22
vendor/github.com/davidbyttow/govips/v2/vips/color.c
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
#include "color.h"
|
||||
#include <unistd.h>
|
||||
|
||||
int is_colorspace_supported(VipsImage *in) {
|
||||
return vips_colourspace_issupported(in) ? 1 : 0;
|
||||
}
|
||||
|
||||
int to_colorspace(VipsImage *in, VipsImage **out, VipsInterpretation space) {
|
||||
return vips_colourspace(in, out, space, NULL);
|
||||
}
|
||||
|
||||
// https://libvips.github.io/libvips/API/8.6/libvips-colour.html#vips-icc-transform
|
||||
int icc_transform(VipsImage *in, VipsImage **out, const char *output_profile, const char *input_profile, VipsIntent intent,
|
||||
int depth, gboolean embedded) {
|
||||
return vips_icc_transform(
|
||||
in, out, output_profile,
|
||||
"input_profile", input_profile ? input_profile : "none",
|
||||
"intent", intent,
|
||||
"depth", depth ? depth : 8,
|
||||
"embedded", embedded,
|
||||
NULL);
|
||||
}
|
||||
96
vendor/github.com/davidbyttow/govips/v2/vips/color.go
generated
vendored
Normal file
96
vendor/github.com/davidbyttow/govips/v2/vips/color.go
generated
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
package vips
|
||||
|
||||
// #include "color.h"
|
||||
import "C"
|
||||
|
||||
// Color represents an RGB
|
||||
type Color struct {
|
||||
R, G, B uint8
|
||||
}
|
||||
|
||||
// ColorRGBA represents an RGB with alpha channel (A)
|
||||
type ColorRGBA struct {
|
||||
R, G, B, A uint8
|
||||
}
|
||||
|
||||
// Interpretation represents VIPS_INTERPRETATION type
|
||||
type Interpretation int
|
||||
|
||||
// Interpretation enum
|
||||
const (
|
||||
InterpretationError Interpretation = C.VIPS_INTERPRETATION_ERROR
|
||||
InterpretationMultiband Interpretation = C.VIPS_INTERPRETATION_MULTIBAND
|
||||
InterpretationBW Interpretation = C.VIPS_INTERPRETATION_B_W
|
||||
InterpretationHistogram Interpretation = C.VIPS_INTERPRETATION_HISTOGRAM
|
||||
InterpretationXYZ Interpretation = C.VIPS_INTERPRETATION_XYZ
|
||||
InterpretationLAB Interpretation = C.VIPS_INTERPRETATION_LAB
|
||||
InterpretationCMYK Interpretation = C.VIPS_INTERPRETATION_CMYK
|
||||
InterpretationLABQ Interpretation = C.VIPS_INTERPRETATION_LABQ
|
||||
InterpretationRGB Interpretation = C.VIPS_INTERPRETATION_RGB
|
||||
InterpretationRGB16 Interpretation = C.VIPS_INTERPRETATION_RGB16
|
||||
InterpretationCMC Interpretation = C.VIPS_INTERPRETATION_CMC
|
||||
InterpretationLCH Interpretation = C.VIPS_INTERPRETATION_LCH
|
||||
InterpretationLABS Interpretation = C.VIPS_INTERPRETATION_LABS
|
||||
InterpretationSRGB Interpretation = C.VIPS_INTERPRETATION_sRGB
|
||||
InterpretationYXY Interpretation = C.VIPS_INTERPRETATION_YXY
|
||||
InterpretationFourier Interpretation = C.VIPS_INTERPRETATION_FOURIER
|
||||
InterpretationGrey16 Interpretation = C.VIPS_INTERPRETATION_GREY16
|
||||
InterpretationMatrix Interpretation = C.VIPS_INTERPRETATION_MATRIX
|
||||
InterpretationScRGB Interpretation = C.VIPS_INTERPRETATION_scRGB
|
||||
InterpretationHSV Interpretation = C.VIPS_INTERPRETATION_HSV
|
||||
)
|
||||
|
||||
// Intent represents VIPS_INTENT type
|
||||
type Intent int
|
||||
|
||||
// Intent enum
|
||||
const (
|
||||
IntentPerceptual Intent = C.VIPS_INTENT_PERCEPTUAL
|
||||
IntentRelative Intent = C.VIPS_INTENT_RELATIVE
|
||||
IntentSaturation Intent = C.VIPS_INTENT_SATURATION
|
||||
IntentAbsolute Intent = C.VIPS_INTENT_ABSOLUTE
|
||||
IntentLast Intent = C.VIPS_INTENT_LAST
|
||||
)
|
||||
|
||||
func vipsIsColorSpaceSupported(in *C.VipsImage) bool {
|
||||
return C.is_colorspace_supported(in) == 1
|
||||
}
|
||||
|
||||
// https://libvips.github.io/libvips/API/current/libvips-colour.html#vips-colourspace
|
||||
func vipsToColorSpace(in *C.VipsImage, interpretation Interpretation) (*C.VipsImage, error) {
|
||||
incOpCounter("to_colorspace")
|
||||
var out *C.VipsImage
|
||||
|
||||
inter := C.VipsInterpretation(interpretation)
|
||||
|
||||
if err := C.to_colorspace(in, &out, inter); err != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func vipsICCTransform(in *C.VipsImage, outputProfile string, inputProfile string, intent Intent, depth int,
|
||||
embedded bool) (*C.VipsImage, error) {
|
||||
var out *C.VipsImage
|
||||
var cInputProfile *C.char
|
||||
var cEmbedded C.gboolean
|
||||
|
||||
cOutputProfile := C.CString(outputProfile)
|
||||
defer freeCString(cOutputProfile)
|
||||
|
||||
if inputProfile != "" {
|
||||
cInputProfile = C.CString(inputProfile)
|
||||
defer freeCString(cInputProfile)
|
||||
}
|
||||
|
||||
if embedded {
|
||||
cEmbedded = C.TRUE
|
||||
}
|
||||
|
||||
if res := C.icc_transform(in, &out, cOutputProfile, cInputProfile, C.VipsIntent(intent), C.int(depth), cEmbedded); res != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
10
vendor/github.com/davidbyttow/govips/v2/vips/color.h
generated
vendored
Normal file
10
vendor/github.com/davidbyttow/govips/v2/vips/color.h
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
// https://libvips.github.io/libvips/API/current/libvips-colour.html
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <vips/vips.h>
|
||||
|
||||
int is_colorspace_supported(VipsImage *in);
|
||||
int to_colorspace(VipsImage *in, VipsImage **out, VipsInterpretation space);
|
||||
|
||||
int icc_transform(VipsImage *in, VipsImage **out, const char *output_profile, const char *input_profile, VipsIntent intent,
|
||||
int depth, gboolean embedded);
|
||||
27
vendor/github.com/davidbyttow/govips/v2/vips/composite.go
generated
vendored
Normal file
27
vendor/github.com/davidbyttow/govips/v2/vips/composite.go
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
package vips
|
||||
|
||||
// #include <vips/vips.h>
|
||||
import "C"
|
||||
|
||||
// ImageComposite image to composite param
|
||||
type ImageComposite struct {
|
||||
Image *ImageRef
|
||||
BlendMode BlendMode
|
||||
X, Y int
|
||||
}
|
||||
|
||||
func toVipsCompositeStructs(r *ImageRef, datas []*ImageComposite) ([]*C.VipsImage, []C.int, []C.int, []C.int) {
|
||||
ins := []*C.VipsImage{r.image}
|
||||
modes := []C.int{}
|
||||
xs := []C.int{}
|
||||
ys := []C.int{}
|
||||
|
||||
for _, image := range datas {
|
||||
ins = append(ins, image.Image.image)
|
||||
modes = append(modes, C.int(image.BlendMode))
|
||||
xs = append(xs, C.int(image.X))
|
||||
ys = append(ys, C.int(image.Y))
|
||||
}
|
||||
|
||||
return ins, modes, xs, ys
|
||||
}
|
||||
380
vendor/github.com/davidbyttow/govips/v2/vips/conversion.c
generated
vendored
Normal file
380
vendor/github.com/davidbyttow/govips/v2/vips/conversion.c
generated
vendored
Normal file
@@ -0,0 +1,380 @@
|
||||
#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);
|
||||
}
|
||||
|
||||
int embed_image(VipsImage *in, VipsImage **out, int left, int top, int width,
|
||||
int height, int extend) {
|
||||
return vips_embed(in, out, left, top, width, height, "extend", extend, NULL);
|
||||
}
|
||||
|
||||
int embed_image_background(VipsImage *in, VipsImage **out, int left, int top, int width,
|
||||
int height, double r, double g, double b, double a) {
|
||||
|
||||
double background[3] = {r, g, b};
|
||||
double backgroundRGBA[4] = {r, g, b, a};
|
||||
|
||||
VipsArrayDouble *vipsBackground;
|
||||
|
||||
if (in->Bands <= 3) {
|
||||
vipsBackground = vips_array_double_new(background, 3);
|
||||
} else {
|
||||
vipsBackground = vips_array_double_new(backgroundRGBA, 4);
|
||||
}
|
||||
|
||||
int code = vips_embed(in, out, left, top, width, height,
|
||||
"extend", VIPS_EXTEND_BACKGROUND, "background", vipsBackground, NULL);
|
||||
|
||||
vips_area_unref(VIPS_AREA(vipsBackground));
|
||||
return code;
|
||||
}
|
||||
|
||||
int embed_multi_page_image(VipsImage *in, VipsImage **out, int left, int top, int width,
|
||||
int height, int extend) {
|
||||
VipsObject *base = VIPS_OBJECT(vips_image_new());
|
||||
int page_height = vips_image_get_page_height(in);
|
||||
int in_width = in->Xsize;
|
||||
int n_pages = in->Ysize / page_height;
|
||||
|
||||
VipsImage **page = (VipsImage **) vips_object_local_array(base, n_pages);
|
||||
VipsImage **copy = (VipsImage **) vips_object_local_array(base, 1);
|
||||
|
||||
// split image into cropped frames
|
||||
for (int i = 0; i < n_pages; i++) {
|
||||
if (
|
||||
vips_extract_area(in, &page[i], 0, page_height * i, in_width, page_height, NULL) ||
|
||||
vips_embed(page[i], &page[i], left, top, width, height, "extend", extend, NULL)
|
||||
) {
|
||||
g_object_unref(base);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
// reassemble frames and set page height
|
||||
// copy before modifying metadata
|
||||
if(
|
||||
vips_arrayjoin(page, ©[0], n_pages, "across", 1, NULL) ||
|
||||
vips_copy(copy[0], out, NULL)
|
||||
) {
|
||||
g_object_unref(base);
|
||||
return -1;
|
||||
}
|
||||
vips_image_set_int(*out, VIPS_META_PAGE_HEIGHT, height);
|
||||
g_object_unref(base);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int embed_multi_page_image_background(VipsImage *in, VipsImage **out, int left, int top, int width,
|
||||
int height, double r, double g, double b, double a) {
|
||||
double background[3] = {r, g, b};
|
||||
double backgroundRGBA[4] = {r, g, b, a};
|
||||
|
||||
VipsArrayDouble *vipsBackground;
|
||||
|
||||
if (in->Bands <= 3) {
|
||||
vipsBackground = vips_array_double_new(background, 3);
|
||||
} else {
|
||||
vipsBackground = vips_array_double_new(backgroundRGBA, 4);
|
||||
}
|
||||
VipsObject *base = VIPS_OBJECT(vips_image_new());
|
||||
int page_height = vips_image_get_page_height(in);
|
||||
int in_width = in->Xsize;
|
||||
int n_pages = in->Ysize / page_height;
|
||||
|
||||
VipsImage **page = (VipsImage **) vips_object_local_array(base, n_pages);
|
||||
VipsImage **copy = (VipsImage **) vips_object_local_array(base, 1);
|
||||
|
||||
// split image into cropped frames
|
||||
for (int i = 0; i < n_pages; i++) {
|
||||
if (
|
||||
vips_extract_area(in, &page[i], 0, page_height * i, in_width, page_height, NULL) ||
|
||||
vips_embed(page[i], &page[i], left, top, width, height,
|
||||
"extend", VIPS_EXTEND_BACKGROUND, "background", vipsBackground, NULL)
|
||||
) {
|
||||
vips_area_unref(VIPS_AREA(vipsBackground));
|
||||
g_object_unref(base);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
// reassemble frames and set page height
|
||||
// copy before modifying metadata
|
||||
if(
|
||||
vips_arrayjoin(page, ©[0], n_pages, "across", 1, NULL) ||
|
||||
vips_copy(copy[0], out, NULL)
|
||||
) {
|
||||
vips_area_unref(VIPS_AREA(vipsBackground));
|
||||
g_object_unref(base);
|
||||
return -1;
|
||||
}
|
||||
vips_image_set_int(*out, VIPS_META_PAGE_HEIGHT, height);
|
||||
vips_area_unref(VIPS_AREA(vipsBackground));
|
||||
g_object_unref(base);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int flip_image(VipsImage *in, VipsImage **out, int direction) {
|
||||
return vips_flip(in, out, direction, NULL);
|
||||
}
|
||||
|
||||
int recomb_image(VipsImage *in, VipsImage **out, VipsImage *m) {
|
||||
return vips_recomb(in, out, m, NULL);
|
||||
}
|
||||
|
||||
int extract_image_area(VipsImage *in, VipsImage **out, int left, int top,
|
||||
int width, int height) {
|
||||
return vips_extract_area(in, out, left, top, width, height, NULL);
|
||||
}
|
||||
|
||||
int extract_area_multi_page(VipsImage *in, VipsImage **out, int left, int top, int width, int height) {
|
||||
VipsObject *base = VIPS_OBJECT(vips_image_new());
|
||||
int page_height = vips_image_get_page_height(in);
|
||||
int n_pages = in->Ysize / page_height;
|
||||
|
||||
VipsImage **page = (VipsImage **) vips_object_local_array(base, n_pages);
|
||||
VipsImage **copy = (VipsImage **) vips_object_local_array(base, 1);
|
||||
|
||||
// split image into cropped frames
|
||||
for (int i = 0; i < n_pages; i++) {
|
||||
if(vips_extract_area(in, &page[i], left, page_height * i + top, width, height, NULL)) {
|
||||
g_object_unref(base);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
// reassemble frames and set page height
|
||||
// copy before modifying metadata
|
||||
if(
|
||||
vips_arrayjoin(page, ©[0], n_pages, "across", 1, NULL) ||
|
||||
vips_copy(copy[0], out, NULL)
|
||||
) {
|
||||
g_object_unref(base);
|
||||
return -1;
|
||||
}
|
||||
vips_image_set_int(*out, VIPS_META_PAGE_HEIGHT, height);
|
||||
g_object_unref(base);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int extract_band(VipsImage *in, VipsImage **out, int band, int num) {
|
||||
if (num > 0) {
|
||||
return vips_extract_band(in, out, band, "n", num, NULL);
|
||||
}
|
||||
return vips_extract_band(in, out, band, NULL);
|
||||
}
|
||||
|
||||
int rot_image(VipsImage *in, VipsImage **out, VipsAngle angle) {
|
||||
return vips_rot(in, out, angle, NULL);
|
||||
}
|
||||
|
||||
int autorot_image(VipsImage *in, VipsImage **out) {
|
||||
return vips_autorot(in, out, NULL);
|
||||
}
|
||||
|
||||
int zoom_image(VipsImage *in, VipsImage **out, int xfac, int yfac) {
|
||||
return vips_zoom(in, out, xfac, yfac, NULL);
|
||||
}
|
||||
|
||||
int bandjoin(VipsImage **in, VipsImage **out, int n) {
|
||||
return vips_bandjoin(in, out, n, NULL);
|
||||
}
|
||||
|
||||
int bandjoin_const(VipsImage *in, VipsImage **out, double constants[], int n) {
|
||||
return vips_bandjoin_const(in, out, constants, n, NULL);
|
||||
}
|
||||
|
||||
int similarity(VipsImage *in, VipsImage **out, double scale, double angle,
|
||||
double r, double g, double b, double a, double idx, double idy,
|
||||
double odx, double ody) {
|
||||
if (is_16bit(in->Type)) {
|
||||
r = 65535 * r / 255;
|
||||
g = 65535 * g / 255;
|
||||
b = 65535 * b / 255;
|
||||
a = 65535 * a / 255;
|
||||
}
|
||||
|
||||
double background[3] = {r, g, b};
|
||||
double backgroundRGBA[4] = {r, g, b, a};
|
||||
|
||||
VipsArrayDouble *vipsBackground;
|
||||
|
||||
// Ignore the alpha channel if the image doesn't have one
|
||||
if (in->Bands <= 3) {
|
||||
vipsBackground = vips_array_double_new(background, 3);
|
||||
} else {
|
||||
vipsBackground = vips_array_double_new(backgroundRGBA, 4);
|
||||
}
|
||||
|
||||
int code = vips_similarity(in, out, "scale", scale, "angle", angle,
|
||||
"background", vipsBackground, "idx", idx, "idy",
|
||||
idy, "odx", odx, "ody", ody, NULL);
|
||||
|
||||
vips_area_unref(VIPS_AREA(vipsBackground));
|
||||
return code;
|
||||
}
|
||||
|
||||
int smartcrop(VipsImage *in, VipsImage **out, int width, int height,
|
||||
int interesting) {
|
||||
return vips_smartcrop(in, out, width, height, "interesting", interesting,
|
||||
NULL);
|
||||
}
|
||||
|
||||
int crop(VipsImage *in, VipsImage **out, int left, int top,
|
||||
int width, int height) {
|
||||
// resolve image pages
|
||||
int page_height = vips_image_get_page_height(in);
|
||||
int n_pages = in->Ysize / page_height;
|
||||
if (n_pages <= 1) {
|
||||
return vips_crop(in, out, left, top, width, height, NULL);
|
||||
}
|
||||
|
||||
int in_width = in->Xsize;
|
||||
VipsObject *base = VIPS_OBJECT(vips_image_new());
|
||||
VipsImage **page = (VipsImage **) vips_object_local_array(base, n_pages);
|
||||
VipsImage **copy = (VipsImage **) vips_object_local_array(base, 1);
|
||||
// split image into cropped frames
|
||||
for (int i = 0; i < n_pages; i++) {
|
||||
if (
|
||||
vips_extract_area(in, &page[i], 0, page_height * i, in_width, page_height, NULL) ||
|
||||
vips_crop(page[i], &page[i], left, top, width, height, NULL)
|
||||
) {
|
||||
g_object_unref(base);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// reassemble frames and set page height
|
||||
// copy before modifying metadata
|
||||
if(
|
||||
vips_arrayjoin(page, ©[0], n_pages, "across", 1, NULL) ||
|
||||
vips_copy(copy[0], out, NULL)
|
||||
) {
|
||||
g_object_unref(base);
|
||||
return -1;
|
||||
}
|
||||
vips_image_set_int(*out, VIPS_META_PAGE_HEIGHT, height);
|
||||
g_object_unref(base);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int flatten_image(VipsImage *in, VipsImage **out, double r, double g,
|
||||
double b) {
|
||||
if (is_16bit(in->Type)) {
|
||||
r = 65535 * r / 255;
|
||||
g = 65535 * g / 255;
|
||||
b = 65535 * b / 255;
|
||||
}
|
||||
|
||||
double background[3] = {r, g, b};
|
||||
VipsArrayDouble *vipsBackground = vips_array_double_new(background, 3);
|
||||
|
||||
int code = vips_flatten(in, out, "background", vipsBackground, "max_alpha",
|
||||
is_16bit(in->Type) ? 65535.0 : 255.0, NULL);
|
||||
|
||||
vips_area_unref(VIPS_AREA(vipsBackground));
|
||||
return code;
|
||||
}
|
||||
|
||||
int is_16bit(VipsInterpretation interpretation) {
|
||||
return interpretation == VIPS_INTERPRETATION_RGB16 ||
|
||||
interpretation == VIPS_INTERPRETATION_GREY16;
|
||||
}
|
||||
|
||||
int add_alpha(VipsImage *in, VipsImage **out) {
|
||||
return vips_addalpha(in, out, NULL);
|
||||
}
|
||||
|
||||
int premultiply_alpha(VipsImage *in, VipsImage **out) {
|
||||
return vips_premultiply(in, out, "max_alpha", max_alpha(in), NULL);
|
||||
}
|
||||
|
||||
int unpremultiply_alpha(VipsImage *in, VipsImage **out) {
|
||||
return vips_unpremultiply(in, out, NULL);
|
||||
}
|
||||
|
||||
int cast(VipsImage *in, VipsImage **out, int bandFormat) {
|
||||
return vips_cast(in, out, bandFormat, NULL);
|
||||
}
|
||||
|
||||
double max_alpha(VipsImage *in) {
|
||||
switch (in->BandFmt) {
|
||||
case VIPS_FORMAT_USHORT:
|
||||
return 65535;
|
||||
case VIPS_FORMAT_FLOAT:
|
||||
case VIPS_FORMAT_DOUBLE:
|
||||
return 1.0;
|
||||
default:
|
||||
return 255;
|
||||
}
|
||||
}
|
||||
|
||||
int composite_image(VipsImage **in, VipsImage **out, int n, int *mode, int *x,
|
||||
int *y) {
|
||||
VipsArrayInt *xs = vips_array_int_new(x, n - 1);
|
||||
VipsArrayInt *ys = vips_array_int_new(y, n - 1);
|
||||
|
||||
int code = vips_composite(in, out, n, mode, "x", xs, "y", ys, NULL);
|
||||
|
||||
vips_area_unref(VIPS_AREA(xs));
|
||||
vips_area_unref(VIPS_AREA(ys));
|
||||
return code;
|
||||
}
|
||||
|
||||
int composite2_image(VipsImage *base, VipsImage *overlay, VipsImage **out,
|
||||
int mode, gint x, gint y) {
|
||||
return vips_composite2(base, overlay, out, mode, "x", x, "y", y, NULL);
|
||||
}
|
||||
|
||||
int insert_image(VipsImage *main, VipsImage *sub, VipsImage **out, int x, int y, int expand, double r, double g, double b, double a) {
|
||||
if (is_16bit(main->Type)) {
|
||||
r = 65535 * r / 255;
|
||||
g = 65535 * g / 255;
|
||||
b = 65535 * b / 255;
|
||||
a = 65535 * a / 255;
|
||||
}
|
||||
|
||||
double background[3] = {r, g, b};
|
||||
double backgroundRGBA[4] = {r, g, b, a};
|
||||
|
||||
VipsArrayDouble *vipsBackground;
|
||||
|
||||
// Ignore the alpha channel if the image doesn't have one
|
||||
if (main->Bands <= 3) {
|
||||
vipsBackground = vips_array_double_new(background, 3);
|
||||
} else {
|
||||
vipsBackground = vips_array_double_new(backgroundRGBA, 4);
|
||||
}
|
||||
int code = vips_insert(main, sub, out, x, y, "expand", expand, "background", vipsBackground, NULL);
|
||||
|
||||
vips_area_unref(VIPS_AREA(vipsBackground));
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
int join(VipsImage *in1, VipsImage *in2, VipsImage **out, int direction) {
|
||||
return vips_join(in1, in2, out, direction, NULL);
|
||||
}
|
||||
|
||||
int arrayjoin(VipsImage **in, VipsImage **out, int n, int across) {
|
||||
return vips_arrayjoin(in, out, n, "across", across, NULL);
|
||||
}
|
||||
|
||||
int replicate(VipsImage *in, VipsImage **out, int across, int down) {
|
||||
return vips_replicate(in, out, across, down, NULL);
|
||||
}
|
||||
|
||||
int grid(VipsImage *in, VipsImage **out, int tileHeight, int across, int down){
|
||||
return vips_grid(in, out, tileHeight, across, down, NULL);
|
||||
}
|
||||
|
||||
int adjust_gamma(VipsImage *in, VipsImage **out, double g) {
|
||||
return vips_gamma(in, out, "exponent", g, NULL);
|
||||
}
|
||||
520
vendor/github.com/davidbyttow/govips/v2/vips/conversion.go
generated
vendored
Normal file
520
vendor/github.com/davidbyttow/govips/v2/vips/conversion.go
generated
vendored
Normal file
@@ -0,0 +1,520 @@
|
||||
package vips
|
||||
|
||||
// #cgo CFLAGS: -std=c99
|
||||
// #include "conversion.h"
|
||||
import "C"
|
||||
|
||||
// BandFormat represents VIPS_FORMAT type
|
||||
type BandFormat int
|
||||
|
||||
// BandFormat enum
|
||||
const (
|
||||
BandFormatNotSet BandFormat = C.VIPS_FORMAT_NOTSET
|
||||
BandFormatUchar BandFormat = C.VIPS_FORMAT_UCHAR
|
||||
BandFormatChar BandFormat = C.VIPS_FORMAT_CHAR
|
||||
BandFormatUshort BandFormat = C.VIPS_FORMAT_USHORT
|
||||
BandFormatShort BandFormat = C.VIPS_FORMAT_SHORT
|
||||
BandFormatUint BandFormat = C.VIPS_FORMAT_UINT
|
||||
BandFormatInt BandFormat = C.VIPS_FORMAT_INT
|
||||
BandFormatFloat BandFormat = C.VIPS_FORMAT_FLOAT
|
||||
BandFormatComplex BandFormat = C.VIPS_FORMAT_COMPLEX
|
||||
BandFormatDouble BandFormat = C.VIPS_FORMAT_DOUBLE
|
||||
BandFormatDpComplex BandFormat = C.VIPS_FORMAT_DPCOMPLEX
|
||||
)
|
||||
|
||||
// BlendMode gives the various Porter-Duff and PDF blend modes.
|
||||
// See https://libvips.github.io/libvips/API/current/libvips-conversion.html#VipsBlendMode
|
||||
type BlendMode int
|
||||
|
||||
// Constants define the various Porter-Duff and PDF blend modes.
|
||||
// See https://libvips.github.io/libvips/API/current/libvips-conversion.html#VipsBlendMode
|
||||
const (
|
||||
BlendModeClear BlendMode = C.VIPS_BLEND_MODE_CLEAR
|
||||
BlendModeSource BlendMode = C.VIPS_BLEND_MODE_SOURCE
|
||||
BlendModeOver BlendMode = C.VIPS_BLEND_MODE_OVER
|
||||
BlendModeIn BlendMode = C.VIPS_BLEND_MODE_IN
|
||||
BlendModeOut BlendMode = C.VIPS_BLEND_MODE_OUT
|
||||
BlendModeAtop BlendMode = C.VIPS_BLEND_MODE_ATOP
|
||||
BlendModeDest BlendMode = C.VIPS_BLEND_MODE_DEST
|
||||
BlendModeDestOver BlendMode = C.VIPS_BLEND_MODE_DEST_OVER
|
||||
BlendModeDestIn BlendMode = C.VIPS_BLEND_MODE_DEST_IN
|
||||
BlendModeDestOut BlendMode = C.VIPS_BLEND_MODE_DEST_OUT
|
||||
BlendModeDestAtop BlendMode = C.VIPS_BLEND_MODE_DEST_ATOP
|
||||
BlendModeXOR BlendMode = C.VIPS_BLEND_MODE_XOR
|
||||
BlendModeAdd BlendMode = C.VIPS_BLEND_MODE_ADD
|
||||
BlendModeSaturate BlendMode = C.VIPS_BLEND_MODE_SATURATE
|
||||
BlendModeMultiply BlendMode = C.VIPS_BLEND_MODE_MULTIPLY
|
||||
BlendModeScreen BlendMode = C.VIPS_BLEND_MODE_SCREEN
|
||||
BlendModeOverlay BlendMode = C.VIPS_BLEND_MODE_OVERLAY
|
||||
BlendModeDarken BlendMode = C.VIPS_BLEND_MODE_DARKEN
|
||||
BlendModeLighten BlendMode = C.VIPS_BLEND_MODE_LIGHTEN
|
||||
BlendModeColorDodge BlendMode = C.VIPS_BLEND_MODE_COLOUR_DODGE
|
||||
BlendModeColorBurn BlendMode = C.VIPS_BLEND_MODE_COLOUR_BURN
|
||||
BlendModeHardLight BlendMode = C.VIPS_BLEND_MODE_HARD_LIGHT
|
||||
BlendModeSoftLight BlendMode = C.VIPS_BLEND_MODE_SOFT_LIGHT
|
||||
BlendModeDifference BlendMode = C.VIPS_BLEND_MODE_DIFFERENCE
|
||||
BlendModeExclusion BlendMode = C.VIPS_BLEND_MODE_EXCLUSION
|
||||
)
|
||||
|
||||
// Direction represents VIPS_DIRECTION type
|
||||
type Direction int
|
||||
|
||||
// Direction enum
|
||||
const (
|
||||
DirectionHorizontal Direction = C.VIPS_DIRECTION_HORIZONTAL
|
||||
DirectionVertical Direction = C.VIPS_DIRECTION_VERTICAL
|
||||
)
|
||||
|
||||
// Angle represents VIPS_ANGLE type
|
||||
type Angle int
|
||||
|
||||
// Angle enum
|
||||
const (
|
||||
Angle0 Angle = C.VIPS_ANGLE_D0
|
||||
Angle90 Angle = C.VIPS_ANGLE_D90
|
||||
Angle180 Angle = C.VIPS_ANGLE_D180
|
||||
Angle270 Angle = C.VIPS_ANGLE_D270
|
||||
)
|
||||
|
||||
// Angle45 represents VIPS_ANGLE45 type
|
||||
type Angle45 int
|
||||
|
||||
// Angle45 enum
|
||||
const (
|
||||
Angle45_0 Angle45 = C.VIPS_ANGLE45_D0
|
||||
Angle45_45 Angle45 = C.VIPS_ANGLE45_D45
|
||||
Angle45_90 Angle45 = C.VIPS_ANGLE45_D90
|
||||
Angle45_135 Angle45 = C.VIPS_ANGLE45_D135
|
||||
Angle45_180 Angle45 = C.VIPS_ANGLE45_D180
|
||||
Angle45_225 Angle45 = C.VIPS_ANGLE45_D225
|
||||
Angle45_270 Angle45 = C.VIPS_ANGLE45_D270
|
||||
Angle45_315 Angle45 = C.VIPS_ANGLE45_D315
|
||||
)
|
||||
|
||||
// ExtendStrategy represents VIPS_EXTEND type
|
||||
type ExtendStrategy int
|
||||
|
||||
// ExtendStrategy enum
|
||||
const (
|
||||
ExtendBlack ExtendStrategy = C.VIPS_EXTEND_BLACK
|
||||
ExtendCopy ExtendStrategy = C.VIPS_EXTEND_COPY
|
||||
ExtendRepeat ExtendStrategy = C.VIPS_EXTEND_REPEAT
|
||||
ExtendMirror ExtendStrategy = C.VIPS_EXTEND_MIRROR
|
||||
ExtendWhite ExtendStrategy = C.VIPS_EXTEND_WHITE
|
||||
ExtendBackground ExtendStrategy = C.VIPS_EXTEND_BACKGROUND
|
||||
)
|
||||
|
||||
// Interesting represents VIPS_INTERESTING type
|
||||
// https://libvips.github.io/libvips/API/current/libvips-conversion.html#VipsInteresting
|
||||
type Interesting int
|
||||
|
||||
// Interesting constants represent areas of interest which smart cropping will crop based on.
|
||||
const (
|
||||
InterestingNone Interesting = C.VIPS_INTERESTING_NONE
|
||||
InterestingCentre Interesting = C.VIPS_INTERESTING_CENTRE
|
||||
InterestingEntropy Interesting = C.VIPS_INTERESTING_ENTROPY
|
||||
InterestingAttention Interesting = C.VIPS_INTERESTING_ATTENTION
|
||||
InterestingLow Interesting = C.VIPS_INTERESTING_LOW
|
||||
InterestingHigh Interesting = C.VIPS_INTERESTING_HIGH
|
||||
InterestingAll Interesting = C.VIPS_INTERESTING_ALL
|
||||
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
|
||||
|
||||
if err := C.copy_image(in, &out); int(err) != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// https://libvips.github.io/libvips/API/current/libvips-conversion.html#vips-embed
|
||||
func vipsEmbed(in *C.VipsImage, left, top, width, height int, extend ExtendStrategy) (*C.VipsImage, error) {
|
||||
incOpCounter("embed")
|
||||
var out *C.VipsImage
|
||||
|
||||
if err := C.embed_image(in, &out, C.int(left), C.int(top), C.int(width), C.int(height), C.int(extend)); err != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// https://libvips.github.io/libvips/API/current/libvips-conversion.html#vips-embed
|
||||
func vipsEmbedBackground(in *C.VipsImage, left, top, width, height int, backgroundColor *ColorRGBA) (*C.VipsImage, error) {
|
||||
incOpCounter("embed")
|
||||
var out *C.VipsImage
|
||||
|
||||
if err := C.embed_image_background(in, &out, C.int(left), C.int(top), C.int(width),
|
||||
C.int(height), C.double(backgroundColor.R),
|
||||
C.double(backgroundColor.G), C.double(backgroundColor.B), C.double(backgroundColor.A)); err != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func vipsEmbedMultiPage(in *C.VipsImage, left, top, width, height int, extend ExtendStrategy) (*C.VipsImage, error) {
|
||||
incOpCounter("embedMultiPage")
|
||||
var out *C.VipsImage
|
||||
|
||||
if err := C.embed_multi_page_image(in, &out, C.int(left), C.int(top), C.int(width), C.int(height), C.int(extend)); err != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func vipsEmbedMultiPageBackground(in *C.VipsImage, left, top, width, height int, backgroundColor *ColorRGBA) (*C.VipsImage, error) {
|
||||
incOpCounter("embedMultiPageBackground")
|
||||
var out *C.VipsImage
|
||||
|
||||
if err := C.embed_multi_page_image_background(in, &out, C.int(left), C.int(top), C.int(width),
|
||||
C.int(height), C.double(backgroundColor.R),
|
||||
C.double(backgroundColor.G), C.double(backgroundColor.B), C.double(backgroundColor.A)); err != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// https://libvips.github.io/libvips/API/current/libvips-conversion.html#vips-flip
|
||||
func vipsFlip(in *C.VipsImage, direction Direction) (*C.VipsImage, error) {
|
||||
incOpCounter("flip")
|
||||
var out *C.VipsImage
|
||||
|
||||
if err := C.flip_image(in, &out, C.int(direction)); err != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// https://libvips.github.io/libvips/API/current/libvips-conversion.html#vips-recomb
|
||||
func vipsRecomb(in *C.VipsImage, m *C.VipsImage) (*C.VipsImage, error) {
|
||||
incOpCounter("recomb")
|
||||
var out *C.VipsImage
|
||||
|
||||
if err := C.recomb_image(in, &out, m); err != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// https://libvips.github.io/libvips/API/current/libvips-conversion.html#vips-extract-area
|
||||
func vipsExtractArea(in *C.VipsImage, left, top, width, height int) (*C.VipsImage, error) {
|
||||
incOpCounter("extractArea")
|
||||
var out *C.VipsImage
|
||||
|
||||
if err := C.extract_image_area(in, &out, C.int(left), C.int(top), C.int(width), C.int(height)); err != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func vipsExtractAreaMultiPage(in *C.VipsImage, left, top, width, height int) (*C.VipsImage, error) {
|
||||
incOpCounter("extractAreaMultiPage")
|
||||
var out *C.VipsImage
|
||||
|
||||
if err := C.extract_area_multi_page(in, &out, C.int(left), C.int(top), C.int(width), C.int(height)); err != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// https://libvips.github.io/libvips/API/current/libvips-conversion.html#vips-extract-band
|
||||
func vipsExtractBand(in *C.VipsImage, band, num int) (*C.VipsImage, error) {
|
||||
incOpCounter("extractBand")
|
||||
var out *C.VipsImage
|
||||
|
||||
if err := C.extract_band(in, &out, C.int(band), C.int(num)); err != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// http://libvips.github.io/libvips/API/current/libvips-resample.html#vips-similarity
|
||||
func vipsSimilarity(in *C.VipsImage, scale float64, angle float64, color *ColorRGBA,
|
||||
idx float64, idy float64, odx float64, ody float64) (*C.VipsImage, error) {
|
||||
incOpCounter("similarity")
|
||||
var out *C.VipsImage
|
||||
|
||||
if err := C.similarity(in, &out, C.double(scale), C.double(angle),
|
||||
C.double(color.R), C.double(color.G), C.double(color.B), C.double(color.A),
|
||||
C.double(idx), C.double(idy), C.double(odx), C.double(ody)); err != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// http://libvips.github.io/libvips/API/current/libvips-conversion.html#vips-smartcrop
|
||||
func vipsSmartCrop(in *C.VipsImage, width int, height int, interesting Interesting) (*C.VipsImage, error) {
|
||||
incOpCounter("smartcrop")
|
||||
var out *C.VipsImage
|
||||
|
||||
if err := C.smartcrop(in, &out, C.int(width), C.int(height), C.int(interesting)); err != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// http://libvips.github.io/libvips/API/current/libvips-conversion.html#vips-crop
|
||||
func vipsCrop(in *C.VipsImage, left int, top int, width int, height int) (*C.VipsImage, error) {
|
||||
incOpCounter("crop")
|
||||
var out *C.VipsImage
|
||||
|
||||
if err := C.crop(in, &out, C.int(left), C.int(top), C.int(width), C.int(height)); err != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// https://libvips.github.io/libvips/API/current/libvips-conversion.html#vips-rot
|
||||
func vipsRotate(in *C.VipsImage, angle Angle) (*C.VipsImage, error) {
|
||||
incOpCounter("rot")
|
||||
var out *C.VipsImage
|
||||
|
||||
if err := C.rot_image(in, &out, C.VipsAngle(angle)); err != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// https://libvips.github.io/libvips/API/current/libvips-conversion.html#vips-autorot
|
||||
func vipsAutoRotate(in *C.VipsImage) (*C.VipsImage, error) {
|
||||
incOpCounter("autorot")
|
||||
var out *C.VipsImage
|
||||
|
||||
if err := C.autorot_image(in, &out); err != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// https://libvips.github.io/libvips/API/current/libvips-conversion.html#vips-zoom
|
||||
func vipsZoom(in *C.VipsImage, xFactor, yFactor int) (*C.VipsImage, error) {
|
||||
incOpCounter("zoom")
|
||||
var out *C.VipsImage
|
||||
|
||||
if err := C.zoom_image(in, &out, C.int(xFactor), C.int(yFactor)); err != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// https://libvips.github.io/libvips/API/current/libvips-conversion.html#vips-bandjoin
|
||||
func vipsBandJoin(ins []*C.VipsImage) (*C.VipsImage, error) {
|
||||
incOpCounter("bandjoin")
|
||||
var out *C.VipsImage
|
||||
|
||||
if err := C.bandjoin(&ins[0], &out, C.int(len(ins))); err != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// http://libvips.github.io/libvips/API/current/libvips-conversion.html#vips-bandjoin-const
|
||||
func vipsBandJoinConst(in *C.VipsImage, constants []float64) (*C.VipsImage, error) {
|
||||
incOpCounter("bandjoin_const")
|
||||
var out *C.VipsImage
|
||||
|
||||
if err := C.bandjoin_const(in, &out, (*C.double)(&constants[0]), C.int(len(constants))); err != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// https://libvips.github.io/libvips/API/current/libvips-conversion.html#vips-flatten
|
||||
func vipsFlatten(in *C.VipsImage, color *Color) (*C.VipsImage, error) {
|
||||
incOpCounter("flatten")
|
||||
var out *C.VipsImage
|
||||
|
||||
err := C.flatten_image(in, &out, C.double(color.R), C.double(color.G), C.double(color.B))
|
||||
if int(err) != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func vipsAddAlpha(in *C.VipsImage) (*C.VipsImage, error) {
|
||||
incOpCounter("addAlpha")
|
||||
var out *C.VipsImage
|
||||
|
||||
if err := C.add_alpha(in, &out); err != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// https://libvips.github.io/libvips/API/current/libvips-conversion.html#vips-premultiply
|
||||
func vipsPremultiplyAlpha(in *C.VipsImage) (*C.VipsImage, error) {
|
||||
incOpCounter("premultiplyAlpha")
|
||||
var out *C.VipsImage
|
||||
|
||||
if err := C.premultiply_alpha(in, &out); err != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// https://libvips.github.io/libvips/API/current/libvips-conversion.html#vips-unpremultiply
|
||||
func vipsUnpremultiplyAlpha(in *C.VipsImage) (*C.VipsImage, error) {
|
||||
incOpCounter("unpremultiplyAlpha")
|
||||
var out *C.VipsImage
|
||||
|
||||
if err := C.unpremultiply_alpha(in, &out); err != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func vipsCast(in *C.VipsImage, bandFormat BandFormat) (*C.VipsImage, error) {
|
||||
incOpCounter("cast")
|
||||
var out *C.VipsImage
|
||||
|
||||
if err := C.cast(in, &out, C.int(bandFormat)); err != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// https://libvips.github.io/libvips/API/current/libvips-conversion.html#vips-composite
|
||||
func vipsComposite(ins []*C.VipsImage, modes []C.int, xs, ys []C.int) (*C.VipsImage, error) {
|
||||
incOpCounter("composite_multi")
|
||||
var out *C.VipsImage
|
||||
|
||||
if err := C.composite_image(&ins[0], &out, C.int(len(ins)), &modes[0], &xs[0], &ys[0]); err != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// https://libvips.github.io/libvips/API/current/libvips-conversion.html#vips-composite2
|
||||
func vipsComposite2(base *C.VipsImage, overlay *C.VipsImage, mode BlendMode, x, y int) (*C.VipsImage, error) {
|
||||
incOpCounter("composite")
|
||||
var out *C.VipsImage
|
||||
|
||||
if err := C.composite2_image(base, overlay, &out, C.int(mode), C.gint(x), C.gint(y)); err != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func vipsInsert(main *C.VipsImage, sub *C.VipsImage, x, y int, expand bool, background *ColorRGBA) (*C.VipsImage, error) {
|
||||
incOpCounter("insert")
|
||||
var out *C.VipsImage
|
||||
|
||||
if background == nil {
|
||||
background = &ColorRGBA{R: 0.0, G: 0.0, B: 0.0, A: 255.0}
|
||||
}
|
||||
|
||||
expandInt := 0
|
||||
if expand {
|
||||
expandInt = 1
|
||||
}
|
||||
|
||||
if err := C.insert_image(main, sub, &out, C.int(x), C.int(y), C.int(expandInt), C.double(background.R), C.double(background.G), C.double(background.B), C.double(background.A)); err != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// https://libvips.github.io/libvips/API/current/libvips-conversion.html#vips-join
|
||||
func vipsJoin(input1 *C.VipsImage, input2 *C.VipsImage, dir Direction) (*C.VipsImage, error) {
|
||||
incOpCounter("join")
|
||||
var out *C.VipsImage
|
||||
|
||||
defer C.g_object_unref(C.gpointer(input1))
|
||||
defer C.g_object_unref(C.gpointer(input2))
|
||||
if err := C.join(input1, input2, &out, C.int(dir)); err != 0 {
|
||||
return nil, handleVipsError()
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// https://libvips.github.io/libvips/API/current/libvips-conversion.html#vips-arrayjoin
|
||||
func vipsArrayJoin(inputs []*C.VipsImage, across int) (*C.VipsImage, error) {
|
||||
incOpCounter("arrayjoin")
|
||||
var out *C.VipsImage
|
||||
|
||||
if err := C.arrayjoin(&inputs[0], &out, C.int(len(inputs)), C.int(across)); err != 0 {
|
||||
return nil, handleVipsError()
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// https://www.libvips.org/API/current/libvips-conversion.html#vips-replicate
|
||||
func vipsReplicate(in *C.VipsImage, across int, down int) (*C.VipsImage, error) {
|
||||
incOpCounter("replicate")
|
||||
var out *C.VipsImage
|
||||
|
||||
if err := C.replicate(in, &out, C.int(across), C.int(down)); err != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// https://www.libvips.org/API/current/libvips-conversion.html#vips-grid
|
||||
func vipsGrid(in *C.VipsImage, tileHeight, across, down int) (*C.VipsImage, error) {
|
||||
incOpCounter("grid")
|
||||
var out *C.VipsImage
|
||||
|
||||
if err := C.grid(in, &out, C.int(tileHeight), C.int(across), C.int(down)); err != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func vipsGamma(image *C.VipsImage, gamma float64) (*C.VipsImage, error) {
|
||||
incOpCounter("gamma")
|
||||
var out *C.VipsImage
|
||||
|
||||
if err := C.adjust_gamma(image, &out, C.double(gamma)); err != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
70
vendor/github.com/davidbyttow/govips/v2/vips/conversion.h
generated
vendored
Normal file
70
vendor/github.com/davidbyttow/govips/v2/vips/conversion.h
generated
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
// https://libvips.github.io/libvips/API/current/libvips-conversion.html
|
||||
|
||||
#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,
|
||||
int height, int extend);
|
||||
int embed_image_background(VipsImage *in, VipsImage **out, int left, int top, int width,
|
||||
int height, double r, double g, double b, double a);
|
||||
int embed_multi_page_image(VipsImage *in, VipsImage **out, int left, int top, int width,
|
||||
int height, int extend);
|
||||
int embed_multi_page_image_background(VipsImage *in, VipsImage **out, int left, int top,
|
||||
int width, int height, double r, double g, double b, double a);
|
||||
|
||||
int flip_image(VipsImage *in, VipsImage **out, int direction);
|
||||
|
||||
int recomb_image(VipsImage *in, VipsImage **out, VipsImage *m);
|
||||
|
||||
int extract_image_area(VipsImage *in, VipsImage **out, int left, int top,
|
||||
int width, int height);
|
||||
int extract_area_multi_page(VipsImage *in, VipsImage **out, int left, int top,
|
||||
int width, int height);
|
||||
|
||||
int extract_band(VipsImage *in, VipsImage **out, int band, int num);
|
||||
|
||||
int rot_image(VipsImage *in, VipsImage **out, VipsAngle angle);
|
||||
int autorot_image(VipsImage *in, VipsImage **out);
|
||||
|
||||
int zoom_image(VipsImage *in, VipsImage **out, int xfac, int yfac);
|
||||
int smartcrop(VipsImage *in, VipsImage **out, int width, int height,
|
||||
int interesting);
|
||||
int crop(VipsImage *in, VipsImage **out, int left, int top,
|
||||
int width, int height);
|
||||
|
||||
int bandjoin(VipsImage **in, VipsImage **out, int n);
|
||||
int bandjoin_const(VipsImage *in, VipsImage **out, double constants[], int n);
|
||||
int similarity(VipsImage *in, VipsImage **out, double scale, double angle,
|
||||
double r, double g, double b, double a, double idx, double idy,
|
||||
double odx, double ody);
|
||||
int flatten_image(VipsImage *in, VipsImage **out, double r, double g, double b);
|
||||
int add_alpha(VipsImage *in, VipsImage **out);
|
||||
int premultiply_alpha(VipsImage *in, VipsImage **out);
|
||||
int unpremultiply_alpha(VipsImage *in, VipsImage **out);
|
||||
int cast(VipsImage *in, VipsImage **out, int bandFormat);
|
||||
double max_alpha(VipsImage *in);
|
||||
|
||||
int composite_image(VipsImage **in, VipsImage **out, int n, int *mode, int *x,
|
||||
int *y);
|
||||
int composite2_image(VipsImage *base, VipsImage *overlay, VipsImage **out,
|
||||
int mode, gint x, gint y);
|
||||
|
||||
int insert_image(VipsImage *main, VipsImage *sub, VipsImage **out, int x, int y,
|
||||
int expand, double r, double g, double b, double a);
|
||||
|
||||
int join(VipsImage *in1, VipsImage *in2, VipsImage **out, int direction);
|
||||
int arrayjoin(VipsImage **in, VipsImage **out, int n, int across);
|
||||
|
||||
int is_16bit(VipsInterpretation interpretation);
|
||||
|
||||
int replicate(VipsImage *in, VipsImage **out, int across, int down);
|
||||
|
||||
int grid(VipsImage *in, VipsImage **out, int tileHeight, int across, int down);
|
||||
|
||||
int adjust_gamma(VipsImage *in, VipsImage **out, double g);
|
||||
14
vendor/github.com/davidbyttow/govips/v2/vips/convolution.c
generated
vendored
Normal file
14
vendor/github.com/davidbyttow/govips/v2/vips/convolution.c
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
#include "convolution.h"
|
||||
|
||||
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,
|
||||
double m2) {
|
||||
return vips_sharpen(in, out, "sigma", sigma, "x1", x1, "m2", m2, NULL);
|
||||
}
|
||||
|
||||
int sobel_image(VipsImage *in, VipsImage **out) {
|
||||
return vips_sobel(in, out, NULL);
|
||||
}
|
||||
40
vendor/github.com/davidbyttow/govips/v2/vips/convolution.go
generated
vendored
Normal file
40
vendor/github.com/davidbyttow/govips/v2/vips/convolution.go
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
package vips
|
||||
|
||||
// #include "convolution.h"
|
||||
import "C"
|
||||
|
||||
// https://libvips.github.io/libvips/API/current/libvips-convolution.html#vips-gaussblur
|
||||
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), C.double(minAmpl)); err != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// https://libvips.github.io/libvips/API/current/libvips-convolution.html#vips-sharpen
|
||||
func vipsSharpen(in *C.VipsImage, sigma float64, x1 float64, m2 float64) (*C.VipsImage, error) {
|
||||
incOpCounter("sharpen")
|
||||
var out *C.VipsImage
|
||||
|
||||
if err := C.sharpen_image(in, &out, C.double(sigma), C.double(x1), C.double(m2)); err != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// https://libvips.github.io/libvips/API/current/libvips-convolution.html#vips-sobel
|
||||
func vipsSobel(in *C.VipsImage) (*C.VipsImage, error) {
|
||||
incOpCounter("sobel")
|
||||
var out *C.VipsImage
|
||||
|
||||
if err := C.sobel_image(in, &out); err != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
9
vendor/github.com/davidbyttow/govips/v2/vips/convolution.h
generated
vendored
Normal file
9
vendor/github.com/davidbyttow/govips/v2/vips/convolution.h
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
// https://libvips.github.io/libvips/API/current/libvips-convolution.html
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <vips/vips.h>
|
||||
|
||||
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);
|
||||
int sobel_image(VipsImage *in, VipsImage **out);
|
||||
24
vendor/github.com/davidbyttow/govips/v2/vips/create.c
generated
vendored
Normal file
24
vendor/github.com/davidbyttow/govips/v2/vips/create.c
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
// clang-format off
|
||||
// include order matters
|
||||
#include "lang.h"
|
||||
#include "create.h"
|
||||
// clang-format on
|
||||
|
||||
// https://libvips.github.io/libvips/API/current/libvips-create.html#vips-xyz
|
||||
int xyz(VipsImage **out, int width, int height) {
|
||||
return vips_xyz(out, width, height, NULL);
|
||||
}
|
||||
|
||||
// http://libvips.github.io/libvips/API/current/libvips-create.html#vips-black
|
||||
int black(VipsImage **out, int width, int height) {
|
||||
return vips_black(out, width, height, NULL);
|
||||
}
|
||||
|
||||
// https://libvips.github.io/libvips/API/current/libvips-create.html#vips-identity
|
||||
int identity(VipsImage **out, int ushort) {
|
||||
if (ushort > 0) {
|
||||
return vips_identity(out, "ushort", TRUE, NULL);
|
||||
} else {
|
||||
return vips_identity(out, NULL);
|
||||
}
|
||||
}
|
||||
37
vendor/github.com/davidbyttow/govips/v2/vips/create.go
generated
vendored
Normal file
37
vendor/github.com/davidbyttow/govips/v2/vips/create.go
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
package vips
|
||||
|
||||
// #include "create.h"
|
||||
import "C"
|
||||
|
||||
// https://libvips.github.io/libvips/API/current/libvips-create.html#vips-xyz
|
||||
func vipsXYZ(width int, height int) (*C.VipsImage, error) {
|
||||
var out *C.VipsImage
|
||||
|
||||
if err := C.xyz(&out, C.int(width), C.int(height)); err != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// http://libvips.github.io/libvips/API/current/libvips-create.html#vips-black
|
||||
func vipsBlack(width int, height int) (*C.VipsImage, error) {
|
||||
var out *C.VipsImage
|
||||
|
||||
if err := C.black(&out, C.int(width), C.int(height)); err != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// https://libvips.github.io/libvips/API/current/libvips-create.html#vips-identity
|
||||
func vipsIdentity(ushort bool) (*C.VipsImage, error) {
|
||||
var out *C.VipsImage
|
||||
ushortInt := C.int(boolToInt(ushort))
|
||||
if err := C.identity(&out, ushortInt); err != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
12
vendor/github.com/davidbyttow/govips/v2/vips/create.h
generated
vendored
Normal file
12
vendor/github.com/davidbyttow/govips/v2/vips/create.h
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
// https://libvips.github.io/libvips/API/current/libvips-create.html
|
||||
|
||||
// clang-format off
|
||||
// include order matters
|
||||
#include <stdlib.h>
|
||||
#include <vips/vips.h>
|
||||
#include <vips/foreign.h>
|
||||
// clang-format on
|
||||
|
||||
int xyz(VipsImage **out, int width, int height);
|
||||
int black(VipsImage **out, int width, int height);
|
||||
int identity(VipsImage **out, int ushort);
|
||||
24
vendor/github.com/davidbyttow/govips/v2/vips/draw.c
generated
vendored
Normal file
24
vendor/github.com/davidbyttow/govips/v2/vips/draw.c
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
#include "draw.h"
|
||||
|
||||
#include "conversion.h"
|
||||
|
||||
int draw_rect(VipsImage *in, double r, double g, double b, double a, int left,
|
||||
int top, int width, int height, int fill) {
|
||||
if (is_16bit(in->Type)) {
|
||||
r = 65535 * r / 255;
|
||||
g = 65535 * g / 255;
|
||||
b = 65535 * b / 255;
|
||||
a = 65535 * a / 255;
|
||||
}
|
||||
|
||||
double background[3] = {r, g, b};
|
||||
double backgroundRGBA[4] = {r, g, b, a};
|
||||
|
||||
if (in->Bands <= 3) {
|
||||
return vips_draw_rect(in, background, 3, left, top, width, height, "fill",
|
||||
fill, NULL);
|
||||
} else {
|
||||
return vips_draw_rect(in, backgroundRGBA, 4, left, top, width, height,
|
||||
"fill", fill, NULL);
|
||||
}
|
||||
}
|
||||
21
vendor/github.com/davidbyttow/govips/v2/vips/draw.go
generated
vendored
Normal file
21
vendor/github.com/davidbyttow/govips/v2/vips/draw.go
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
package vips
|
||||
|
||||
// #include "draw.h"
|
||||
import "C"
|
||||
|
||||
// https://libvips.github.io/libvips/API/current/libvips-draw.html#vips-draw-rect
|
||||
func vipsDrawRect(in *C.VipsImage, color ColorRGBA, left int, top int, width int, height int, fill bool) error {
|
||||
incOpCounter("draw_rect")
|
||||
|
||||
fillBit := 0
|
||||
if fill {
|
||||
fillBit = 1
|
||||
}
|
||||
|
||||
if err := C.draw_rect(in, C.double(color.R), C.double(color.G), C.double(color.B), C.double(color.A),
|
||||
C.int(left), C.int(top), C.int(width), C.int(height), C.int(fillBit)); err != 0 {
|
||||
return handleImageError(in)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
7
vendor/github.com/davidbyttow/govips/v2/vips/draw.h
generated
vendored
Normal file
7
vendor/github.com/davidbyttow/govips/v2/vips/draw.h
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
// https://libvips.github.io/libvips/API/current/libvips-draw.html
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <vips/vips.h>
|
||||
|
||||
int draw_rect(VipsImage *in, double r, double g, double b, double a, int left,
|
||||
int top, int width, int height, int fill);
|
||||
39
vendor/github.com/davidbyttow/govips/v2/vips/error.go
generated
vendored
Normal file
39
vendor/github.com/davidbyttow/govips/v2/vips/error.go
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
package vips
|
||||
|
||||
// #include <vips/vips.h>
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
dbg "runtime/debug"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrUnsupportedImageFormat when image type is unsupported
|
||||
ErrUnsupportedImageFormat = errors.New("unsupported image format")
|
||||
)
|
||||
|
||||
func handleImageError(out *C.VipsImage) error {
|
||||
if out != nil {
|
||||
clearImage(out)
|
||||
}
|
||||
|
||||
return handleVipsError()
|
||||
}
|
||||
|
||||
func handleSaveBufferError(out unsafe.Pointer) error {
|
||||
if out != nil {
|
||||
gFreePointer(out)
|
||||
}
|
||||
|
||||
return handleVipsError()
|
||||
}
|
||||
|
||||
func handleVipsError() error {
|
||||
s := C.GoString(C.vips_error_buffer())
|
||||
C.vips_error_clear()
|
||||
|
||||
return fmt.Errorf("%v\nStack:\n%s", s, dbg.Stack())
|
||||
}
|
||||
578
vendor/github.com/davidbyttow/govips/v2/vips/foreign.c
generated
vendored
Normal file
578
vendor/github.com/davidbyttow/govips/v2/vips/foreign.c
generated
vendored
Normal file
@@ -0,0 +1,578 @@
|
||||
#include "foreign.h"
|
||||
|
||||
#include "lang.h"
|
||||
|
||||
void set_bool_param(Param *p, gboolean b) {
|
||||
p->type = PARAM_TYPE_BOOL;
|
||||
p->value.b = b;
|
||||
p->is_set = TRUE;
|
||||
}
|
||||
|
||||
void set_int_param(Param *p, gint i) {
|
||||
p->type = PARAM_TYPE_INT;
|
||||
p->value.i = i;
|
||||
p->is_set = TRUE;
|
||||
}
|
||||
|
||||
void set_double_param(Param *p, gdouble d) {
|
||||
p->type = PARAM_TYPE_DOUBLE;
|
||||
p->value.d = d;
|
||||
p->is_set = TRUE;
|
||||
}
|
||||
|
||||
int load_image_buffer(LoadParams *params, void *buf, size_t len,
|
||||
VipsImage **out) {
|
||||
int code = 1;
|
||||
ImageType imageType = params->inputFormat;
|
||||
|
||||
if (imageType == JPEG) {
|
||||
// shrink: int, fail: bool, autorotate: bool
|
||||
code = vips_jpegload_buffer(buf, len, out, "fail", params->fail,
|
||||
"autorotate", params->autorotate, "shrink",
|
||||
params->jpegShrink, NULL);
|
||||
} else if (imageType == PNG) {
|
||||
code = vips_pngload_buffer(buf, len, out, NULL);
|
||||
} else if (imageType == WEBP) {
|
||||
// page: int, n: int, scale: double
|
||||
code = vips_webpload_buffer(buf, len, out, "page", params->page, "n",
|
||||
params->n, NULL);
|
||||
} else if (imageType == TIFF) {
|
||||
// page: int, n: int, autorotate: bool, subifd: int
|
||||
code =
|
||||
vips_tiffload_buffer(buf, len, out, "page", params->page, "n",
|
||||
params->n, "autorotate", params->autorotate, NULL);
|
||||
} else if (imageType == GIF) {
|
||||
// page: int, n: int, scale: double
|
||||
code = vips_gifload_buffer(buf, len, out, "page", params->page, "n",
|
||||
params->n, NULL);
|
||||
} else if (imageType == PDF) {
|
||||
// page: int, n: int, dpi: double, scale: double, background: color
|
||||
code = vips_pdfload_buffer(buf, len, out, "page", params->page, "n",
|
||||
params->n, "dpi", params->dpi, NULL);
|
||||
} else if (imageType == SVG) {
|
||||
// dpi: double, scale: double, unlimited: bool
|
||||
code = vips_svgload_buffer(buf, len, out, "dpi", params->dpi, "unlimited",
|
||||
params->svgUnlimited, NULL);
|
||||
} else if (imageType == HEIF) {
|
||||
// added autorotate on load as currently it addresses orientation issues
|
||||
// https://github.com/libvips/libvips/pull/1680
|
||||
// page: int, n: int, thumbnail: bool
|
||||
code = vips_heifload_buffer(buf, len, out, "page", params->page, "n",
|
||||
params->n, "thumbnail", params->heifThumbnail,
|
||||
"autorotate", TRUE, NULL);
|
||||
} else if (imageType == MAGICK) {
|
||||
// page: int, n: int, density: string
|
||||
code = vips_magickload_buffer(buf, len, out, "page", params->page, "n",
|
||||
params->n, NULL);
|
||||
} else if (imageType == AVIF) {
|
||||
code = vips_heifload_buffer(buf, len, out, "page", params->page, "n",
|
||||
params->n, "thumbnail", params->heifThumbnail,
|
||||
"autorotate", params->autorotate, NULL);
|
||||
|
||||
}
|
||||
#if (VIPS_MAJOR_VERSION >= 8) && (VIPS_MINOR_VERSION >= 11)
|
||||
else if (imageType == JP2K) {
|
||||
code = vips_jp2kload_buffer(buf, len, out, "page", params->page, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
#define MAYBE_SET_BOOL(OP, PARAM, NAME) \
|
||||
if (PARAM.is_set) { \
|
||||
vips_object_set(VIPS_OBJECT(OP), NAME, PARAM.value.b, NULL); \
|
||||
}
|
||||
|
||||
#define MAYBE_SET_INT(OP, PARAM, NAME) \
|
||||
if (PARAM.is_set) { \
|
||||
vips_object_set(VIPS_OBJECT(OP), NAME, PARAM.value.i, NULL); \
|
||||
}
|
||||
|
||||
#define MAYBE_SET_DOUBLE(OP, PARAM, NAME) \
|
||||
if (PARAM.is_set) { \
|
||||
vips_object_set(VIPS_OBJECT(OP), NAME, PARAM.value.d, NULL); \
|
||||
}
|
||||
|
||||
typedef int (*SetLoadOptionsFn)(VipsOperation *operation, LoadParams *params);
|
||||
|
||||
int set_jpegload_options(VipsOperation *operation, LoadParams *params) {
|
||||
MAYBE_SET_BOOL(operation, params->autorotate, "autorotate");
|
||||
MAYBE_SET_BOOL(operation, params->fail, "fail");
|
||||
MAYBE_SET_INT(operation, params->jpegShrink, "shrink");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int set_pngload_options(VipsOperation *operation, LoadParams *params) {
|
||||
MAYBE_SET_BOOL(operation, params->fail, "fail");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int set_webpload_options(VipsOperation *operation, LoadParams *params) {
|
||||
MAYBE_SET_INT(operation, params->page, "page");
|
||||
MAYBE_SET_INT(operation, params->n, "n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int set_tiffload_options(VipsOperation *operation, LoadParams *params) {
|
||||
MAYBE_SET_BOOL(operation, params->autorotate, "autorotate");
|
||||
MAYBE_SET_INT(operation, params->page, "page");
|
||||
MAYBE_SET_INT(operation, params->n, "n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int set_gifload_options(VipsOperation *operation, LoadParams *params) {
|
||||
MAYBE_SET_INT(operation, params->page, "page");
|
||||
MAYBE_SET_INT(operation, params->n, "n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int set_pdfload_options(VipsOperation *operation, LoadParams *params) {
|
||||
MAYBE_SET_INT(operation, params->page, "page");
|
||||
MAYBE_SET_INT(operation, params->n, "n");
|
||||
MAYBE_SET_DOUBLE(operation, params->dpi, "dpi");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int set_svgload_options(VipsOperation *operation, LoadParams *params) {
|
||||
MAYBE_SET_BOOL(operation, params->svgUnlimited, "unlimited");
|
||||
MAYBE_SET_DOUBLE(operation, params->dpi, "dpi");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int set_heifload_options(VipsOperation *operation, LoadParams *params) {
|
||||
MAYBE_SET_BOOL(operation, params->autorotate, "autorotate");
|
||||
MAYBE_SET_BOOL(operation, params->heifThumbnail, "thumbnail");
|
||||
MAYBE_SET_INT(operation, params->page, "page");
|
||||
MAYBE_SET_INT(operation, params->n, "n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int set_jp2kload_options(VipsOperation *operation, LoadParams *params) {
|
||||
MAYBE_SET_INT(operation, params->page, "page");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int set_jxlload_options(VipsOperation *operation, LoadParams *params) {
|
||||
// nothing need to do
|
||||
return 0;
|
||||
}
|
||||
|
||||
int set_magickload_options(VipsOperation *operation, LoadParams *params) {
|
||||
MAYBE_SET_INT(operation, params->page, "page");
|
||||
MAYBE_SET_INT(operation, params->n, "n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int load_buffer(const char *operationName, void *buf, size_t len,
|
||||
LoadParams *params, SetLoadOptionsFn setLoadOptions) {
|
||||
VipsBlob *blob = vips_blob_new(NULL, buf, len);
|
||||
|
||||
VipsOperation *operation = vips_operation_new(operationName);
|
||||
if (!operation) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (vips_object_set(VIPS_OBJECT(operation), "buffer", blob, NULL)) {
|
||||
vips_area_unref(VIPS_AREA(blob));
|
||||
return 1;
|
||||
}
|
||||
|
||||
vips_area_unref(VIPS_AREA(blob));
|
||||
|
||||
if (setLoadOptions(operation, params)) {
|
||||
vips_object_unref_outputs(VIPS_OBJECT(operation));
|
||||
g_object_unref(operation);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (vips_cache_operation_buildp(&operation)) {
|
||||
vips_object_unref_outputs(VIPS_OBJECT(operation));
|
||||
g_object_unref(operation);
|
||||
return 1;
|
||||
}
|
||||
|
||||
g_object_get(VIPS_OBJECT(operation), "out", ¶ms->outputImage, NULL);
|
||||
|
||||
vips_object_unref_outputs(VIPS_OBJECT(operation));
|
||||
g_object_unref(operation);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef int (*SetSaveOptionsFn)(VipsOperation *operation, SaveParams *params);
|
||||
|
||||
int save_buffer(const char *operationName, SaveParams *params,
|
||||
SetSaveOptionsFn setSaveOptions) {
|
||||
VipsBlob *blob;
|
||||
VipsOperation *operation = vips_operation_new(operationName);
|
||||
if (!operation) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (vips_object_set(VIPS_OBJECT(operation), "in", params->inputImage, NULL)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (setSaveOptions(operation, params)) {
|
||||
g_object_unref(operation);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (vips_cache_operation_buildp(&operation)) {
|
||||
vips_object_unref_outputs(VIPS_OBJECT(operation));
|
||||
g_object_unref(operation);
|
||||
return 1;
|
||||
}
|
||||
|
||||
g_object_get(VIPS_OBJECT(operation), "buffer", &blob, NULL);
|
||||
g_object_unref(operation);
|
||||
|
||||
VipsArea *area = VIPS_AREA(blob);
|
||||
|
||||
params->outputBuffer = (char *)(area->data);
|
||||
params->outputLen = area->length;
|
||||
area->free_fn = NULL;
|
||||
vips_area_unref(area);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// https://libvips.github.io/libvips/API/current/VipsForeignSave.html#vips-jpegsave-buffer
|
||||
int set_jpegsave_options(VipsOperation *operation, SaveParams *params) {
|
||||
int ret = vips_object_set(
|
||||
VIPS_OBJECT(operation), "strip", params->stripMetadata, "optimize_coding",
|
||||
params->jpegOptimizeCoding, "interlace", params->interlace,
|
||||
"subsample_mode", params->jpegSubsample, "trellis_quant",
|
||||
params->jpegTrellisQuant, "overshoot_deringing",
|
||||
params->jpegOvershootDeringing, "optimize_scans",
|
||||
params->jpegOptimizeScans, "quant_table", params->jpegQuantTable, 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-pngsave-buffer
|
||||
int set_pngsave_options(VipsOperation *operation, SaveParams *params) {
|
||||
int ret =
|
||||
vips_object_set(VIPS_OBJECT(operation), "strip", params->stripMetadata,
|
||||
"compression", params->pngCompression, "interlace",
|
||||
params->interlace, "filter", params->pngFilter, "palette",
|
||||
params->pngPalette, NULL);
|
||||
|
||||
if (!ret && params->quality) {
|
||||
ret = vips_object_set(VIPS_OBJECT(operation), "Q", params->quality, NULL);
|
||||
}
|
||||
|
||||
if (!ret && params->pngDither) {
|
||||
ret = vips_object_set(VIPS_OBJECT(operation), "dither", params->pngDither, NULL);
|
||||
}
|
||||
|
||||
if (!ret && params->pngBitdepth) {
|
||||
ret = vips_object_set(VIPS_OBJECT(operation), "bitdepth", params->pngBitdepth, NULL);
|
||||
}
|
||||
|
||||
// TODO: Handle `profile` param.
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// 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 set_webpsave_options(VipsOperation *operation, SaveParams *params) {
|
||||
int ret =
|
||||
vips_object_set(VIPS_OBJECT(operation),
|
||||
"strip", params->stripMetadata,
|
||||
"lossless", params->webpLossless,
|
||||
"near_lossless", params->webpNearLossless,
|
||||
"reduction_effort", params->webpReductionEffort,
|
||||
"profile", params->webpIccProfile ? params->webpIccProfile : "none",
|
||||
"min_size", params->webpMinSize,
|
||||
"kmin", params->webpKMin,
|
||||
"kmax", params->webpKMax,
|
||||
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, 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-magicksave-buffer
|
||||
int set_magicksave_options(VipsOperation *operation, SaveParams *params) {
|
||||
int ret = vips_object_set(VIPS_OBJECT(operation), "format", "GIF", "bitdepth", params->gifBitdepth, NULL);
|
||||
|
||||
if (!ret && params->quality) {
|
||||
ret = vips_object_set(VIPS_OBJECT(operation), "quality", params->quality,
|
||||
NULL);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// https://libvips.github.io/libvips/API/current/VipsForeignSave.html#vips-gifsave-buffer
|
||||
int set_gifsave_options(VipsOperation *operation, SaveParams *params) {
|
||||
int ret = 0;
|
||||
// See for argument values: https://www.libvips.org/API/current/VipsForeignSave.html#vips-gifsave
|
||||
if (params->gifDither > 0.0 && params->gifDither <= 10) {
|
||||
ret = vips_object_set(VIPS_OBJECT(operation), "dither", params->gifDither, NULL);
|
||||
}
|
||||
if (params->gifEffort >= 1 && params->gifEffort <= 10) {
|
||||
ret = vips_object_set(VIPS_OBJECT(operation), "effort", params->gifEffort, NULL);
|
||||
}
|
||||
if (params->gifBitdepth >= 1 && params->gifBitdepth <= 8) {
|
||||
ret = vips_object_set(VIPS_OBJECT(operation), "bitdepth", params->gifBitdepth, NULL);
|
||||
}
|
||||
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), "strip", params->stripMetadata, "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);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int set_jp2ksave_options(VipsOperation *operation, SaveParams *params) {
|
||||
int ret = vips_object_set(
|
||||
VIPS_OBJECT(operation), "subsample_mode", params->jpegSubsample,
|
||||
"tile_height", params->jp2kTileHeight, "tile_width", params->jp2kTileWidth,
|
||||
"lossless", params->jp2kLossless, NULL);
|
||||
|
||||
if (!ret && params->quality) {
|
||||
ret = vips_object_set(VIPS_OBJECT(operation), "Q", params->quality, NULL);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int set_jxlsave_options(VipsOperation *operation, SaveParams *params) {
|
||||
int ret = vips_object_set(
|
||||
VIPS_OBJECT(operation), "tier", params->jxlTier,
|
||||
"distance", params->jxlDistance, "effort", params->jxlEffort,
|
||||
"lossless", params->jxlLossless, NULL);
|
||||
|
||||
if (!ret && params->quality) {
|
||||
ret = vips_object_set(VIPS_OBJECT(operation), "Q", params->quality, NULL);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int load_from_buffer(LoadParams *params, void *buf, size_t len) {
|
||||
switch (params->inputFormat) {
|
||||
case JPEG:
|
||||
return load_buffer("jpegload_buffer", buf, len, params,
|
||||
set_jpegload_options);
|
||||
case PNG:
|
||||
return load_buffer("pngload_buffer", buf, len, params,
|
||||
set_pngload_options);
|
||||
case WEBP:
|
||||
return load_buffer("webpload_buffer", buf, len, params,
|
||||
set_webpload_options);
|
||||
case HEIF:
|
||||
return load_buffer("heifload_buffer", buf, len, params,
|
||||
set_heifload_options);
|
||||
case TIFF:
|
||||
return load_buffer("tiffload_buffer", buf, len, params,
|
||||
set_tiffload_options);
|
||||
case SVG:
|
||||
return load_buffer("svgload_buffer", buf, len, params,
|
||||
set_svgload_options);
|
||||
case GIF:
|
||||
return load_buffer("gifload_buffer", buf, len, params,
|
||||
set_gifload_options);
|
||||
case PDF:
|
||||
return load_buffer("pdfload_buffer", buf, len, params,
|
||||
set_pdfload_options);
|
||||
case MAGICK:
|
||||
return load_buffer("magickload_buffer", buf, len, params,
|
||||
set_magickload_options);
|
||||
case AVIF:
|
||||
return load_buffer("heifload_buffer", buf, len, params,
|
||||
set_heifload_options);
|
||||
case JP2K:
|
||||
return load_buffer("jp2kload_buffer", buf, len, params,
|
||||
set_jp2kload_options);
|
||||
case JXL:
|
||||
return load_buffer("jxlload_buffer", buf, len, params,
|
||||
set_jxlload_options);
|
||||
default:
|
||||
g_warning("Unsupported input type given: %d", params->inputFormat);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int save_to_buffer(SaveParams *params) {
|
||||
switch (params->outputFormat) {
|
||||
case JPEG:
|
||||
return save_buffer("jpegsave_buffer", params, set_jpegsave_options);
|
||||
case PNG:
|
||||
return save_buffer("pngsave_buffer", params, set_pngsave_options);
|
||||
case WEBP:
|
||||
return save_buffer("webpsave_buffer", params, set_webpsave_options);
|
||||
case HEIF:
|
||||
return save_buffer("heifsave_buffer", params, set_heifsave_options);
|
||||
case TIFF:
|
||||
return save_buffer("tiffsave_buffer", params, set_tiffsave_options);
|
||||
case GIF:
|
||||
#if (VIPS_MAJOR_VERSION >= 8) && (VIPS_MINOR_VERSION >= 12)
|
||||
return save_buffer("gifsave_buffer", params, set_gifsave_options);
|
||||
#else
|
||||
return save_buffer("magicksave_buffer", params, set_magicksave_options);
|
||||
#endif
|
||||
case AVIF:
|
||||
return save_buffer("heifsave_buffer", params, set_avifsave_options);
|
||||
case JP2K:
|
||||
return save_buffer("jp2ksave_buffer", params, set_jp2ksave_options);
|
||||
case JXL:
|
||||
return save_buffer("jxlsave_buffer", params, set_jxlsave_options);
|
||||
default:
|
||||
g_warning("Unsupported output type given: %d", params->outputFormat);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
LoadParams create_load_params(ImageType inputFormat) {
|
||||
Param defaultParam = {};
|
||||
LoadParams p = {
|
||||
.inputFormat = inputFormat,
|
||||
.inputBlob = NULL,
|
||||
.outputImage = NULL,
|
||||
.autorotate = defaultParam,
|
||||
.fail = defaultParam,
|
||||
.page = defaultParam,
|
||||
.n = defaultParam,
|
||||
.dpi = defaultParam,
|
||||
.jpegShrink = defaultParam,
|
||||
.heifThumbnail = defaultParam,
|
||||
.svgUnlimited = defaultParam,
|
||||
};
|
||||
return p;
|
||||
}
|
||||
|
||||
// TODO: Change to same pattern as ImportParams
|
||||
|
||||
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,
|
||||
.jpegTrellisQuant = FALSE,
|
||||
.jpegOvershootDeringing = FALSE,
|
||||
.jpegOptimizeScans = FALSE,
|
||||
.jpegQuantTable = 0,
|
||||
|
||||
.pngCompression = 6,
|
||||
.pngPalette = FALSE,
|
||||
.pngBitdepth = 0,
|
||||
.pngDither = 0,
|
||||
.pngFilter = VIPS_FOREIGN_PNG_FILTER_NONE,
|
||||
|
||||
.gifDither = 0.0,
|
||||
.gifEffort = 0,
|
||||
.gifBitdepth = 0,
|
||||
|
||||
.webpLossless = FALSE,
|
||||
.webpNearLossless = FALSE,
|
||||
.webpReductionEffort = 4,
|
||||
.webpIccProfile = NULL,
|
||||
.webpKMax = 0,
|
||||
.webpKMin = 0,
|
||||
.webpMinSize = FALSE,
|
||||
|
||||
.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,
|
||||
|
||||
.jp2kLossless = FALSE,
|
||||
.jp2kTileHeight = 512,
|
||||
.jp2kTileWidth = 512,
|
||||
|
||||
.jxlTier = 0,
|
||||
.jxlDistance = 1.0,
|
||||
.jxlEffort = 7,
|
||||
.jxlLossless = FALSE,
|
||||
};
|
||||
|
||||
SaveParams create_save_params(ImageType outputFormat) {
|
||||
SaveParams params = defaultSaveParams;
|
||||
params.outputFormat = outputFormat;
|
||||
return params;
|
||||
}
|
||||
502
vendor/github.com/davidbyttow/govips/v2/vips/foreign.go
generated
vendored
Normal file
502
vendor/github.com/davidbyttow/govips/v2/vips/foreign.go
generated
vendored
Normal file
@@ -0,0 +1,502 @@
|
||||
package vips
|
||||
|
||||
// #include "foreign.h"
|
||||
import "C"
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"image/png"
|
||||
"math"
|
||||
"runtime"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/image/bmp"
|
||||
"golang.org/x/net/html/charset"
|
||||
)
|
||||
|
||||
// SubsampleMode correlates to a libvips subsample mode
|
||||
type SubsampleMode int
|
||||
|
||||
// SubsampleMode enum correlating to libvips subsample modes
|
||||
const (
|
||||
VipsForeignSubsampleAuto SubsampleMode = C.VIPS_FOREIGN_JPEG_SUBSAMPLE_AUTO
|
||||
VipsForeignSubsampleOn SubsampleMode = C.VIPS_FOREIGN_JPEG_SUBSAMPLE_ON
|
||||
VipsForeignSubsampleOff SubsampleMode = C.VIPS_FOREIGN_JPEG_SUBSAMPLE_OFF
|
||||
VipsForeignSubsampleLast SubsampleMode = C.VIPS_FOREIGN_JPEG_SUBSAMPLE_LAST
|
||||
)
|
||||
|
||||
// ImageType represents an image type
|
||||
type ImageType int
|
||||
|
||||
// ImageType enum
|
||||
const (
|
||||
ImageTypeUnknown ImageType = C.UNKNOWN
|
||||
ImageTypeGIF ImageType = C.GIF
|
||||
ImageTypeJPEG ImageType = C.JPEG
|
||||
ImageTypeMagick ImageType = C.MAGICK
|
||||
ImageTypePDF ImageType = C.PDF
|
||||
ImageTypePNG ImageType = C.PNG
|
||||
ImageTypeSVG ImageType = C.SVG
|
||||
ImageTypeTIFF ImageType = C.TIFF
|
||||
ImageTypeWEBP ImageType = C.WEBP
|
||||
ImageTypeHEIF ImageType = C.HEIF
|
||||
ImageTypeBMP ImageType = C.BMP
|
||||
ImageTypeAVIF ImageType = C.AVIF
|
||||
ImageTypeJP2K ImageType = C.JP2K
|
||||
ImageTypeJXL ImageType = C.JXL
|
||||
)
|
||||
|
||||
var imageTypeExtensionMap = map[ImageType]string{
|
||||
ImageTypeGIF: ".gif",
|
||||
ImageTypeJPEG: ".jpeg",
|
||||
ImageTypeMagick: ".magick",
|
||||
ImageTypePDF: ".pdf",
|
||||
ImageTypePNG: ".png",
|
||||
ImageTypeSVG: ".svg",
|
||||
ImageTypeTIFF: ".tiff",
|
||||
ImageTypeWEBP: ".webp",
|
||||
ImageTypeHEIF: ".heic",
|
||||
ImageTypeBMP: ".bmp",
|
||||
ImageTypeAVIF: ".avif",
|
||||
ImageTypeJP2K: ".jp2",
|
||||
ImageTypeJXL: ".jxl",
|
||||
}
|
||||
|
||||
// ImageTypes defines the various image types supported by govips
|
||||
var ImageTypes = map[ImageType]string{
|
||||
ImageTypeGIF: "gif",
|
||||
ImageTypeJPEG: "jpeg",
|
||||
ImageTypeMagick: "magick",
|
||||
ImageTypePDF: "pdf",
|
||||
ImageTypePNG: "png",
|
||||
ImageTypeSVG: "svg",
|
||||
ImageTypeTIFF: "tiff",
|
||||
ImageTypeWEBP: "webp",
|
||||
ImageTypeHEIF: "heif",
|
||||
ImageTypeBMP: "bmp",
|
||||
ImageTypeAVIF: "heif",
|
||||
ImageTypeJP2K: "jp2k",
|
||||
ImageTypeJXL: "jxl",
|
||||
}
|
||||
|
||||
// TiffCompression represents method for compressing a tiff at export
|
||||
type TiffCompression int
|
||||
|
||||
// TiffCompression enum
|
||||
const (
|
||||
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
|
||||
)
|
||||
|
||||
// PngFilter represents filter algorithms that can be applied before compression.
|
||||
// See https://www.w3.org/TR/PNG-Filters.html
|
||||
type PngFilter int
|
||||
|
||||
// PngFilter enum
|
||||
const (
|
||||
PngFilterNone PngFilter = C.VIPS_FOREIGN_PNG_FILTER_NONE
|
||||
PngFilterSub PngFilter = C.VIPS_FOREIGN_PNG_FILTER_SUB
|
||||
PngFilterUo PngFilter = C.VIPS_FOREIGN_PNG_FILTER_UP
|
||||
PngFilterAvg PngFilter = C.VIPS_FOREIGN_PNG_FILTER_AVG
|
||||
PngFilterPaeth PngFilter = C.VIPS_FOREIGN_PNG_FILTER_PAETH
|
||||
PngFilterAll PngFilter = C.VIPS_FOREIGN_PNG_FILTER_ALL
|
||||
)
|
||||
|
||||
// FileExt returns the canonical extension for the ImageType
|
||||
func (i ImageType) FileExt() string {
|
||||
if ext, ok := imageTypeExtensionMap[i]; ok {
|
||||
return ext
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// IsTypeSupported checks whether given image type is supported by govips
|
||||
func IsTypeSupported(imageType ImageType) bool {
|
||||
startupIfNeeded()
|
||||
|
||||
return supportedImageTypes[imageType]
|
||||
}
|
||||
|
||||
// DetermineImageType attempts to determine the image type of the given buffer
|
||||
func DetermineImageType(buf []byte) ImageType {
|
||||
if len(buf) < 12 {
|
||||
return ImageTypeUnknown
|
||||
} else if isJPEG(buf) {
|
||||
return ImageTypeJPEG
|
||||
} else if isPNG(buf) {
|
||||
return ImageTypePNG
|
||||
} else if isGIF(buf) {
|
||||
return ImageTypeGIF
|
||||
} else if isTIFF(buf) {
|
||||
return ImageTypeTIFF
|
||||
} else if isWEBP(buf) {
|
||||
return ImageTypeWEBP
|
||||
} else if isAVIF(buf) {
|
||||
return ImageTypeAVIF
|
||||
} else if isHEIF(buf) {
|
||||
return ImageTypeHEIF
|
||||
} else if isSVG(buf) {
|
||||
return ImageTypeSVG
|
||||
} else if isPDF(buf) {
|
||||
return ImageTypePDF
|
||||
} else if isBMP(buf) {
|
||||
return ImageTypeBMP
|
||||
} else if isJP2K(buf) {
|
||||
return ImageTypeJP2K
|
||||
} else if isJXL(buf) {
|
||||
return ImageTypeJXL
|
||||
} else {
|
||||
return ImageTypeUnknown
|
||||
}
|
||||
}
|
||||
|
||||
var jpeg = []byte("\xFF\xD8\xFF")
|
||||
|
||||
func isJPEG(buf []byte) bool {
|
||||
return bytes.HasPrefix(buf, jpeg)
|
||||
}
|
||||
|
||||
var gifHeader = []byte("\x47\x49\x46")
|
||||
|
||||
func isGIF(buf []byte) bool {
|
||||
return bytes.HasPrefix(buf, gifHeader)
|
||||
}
|
||||
|
||||
var pngHeader = []byte("\x89\x50\x4E\x47")
|
||||
|
||||
func isPNG(buf []byte) bool {
|
||||
return bytes.HasPrefix(buf, pngHeader)
|
||||
}
|
||||
|
||||
var tifII = []byte("\x49\x49\x2A\x00")
|
||||
var tifMM = []byte("\x4D\x4D\x00\x2A")
|
||||
|
||||
func isTIFF(buf []byte) bool {
|
||||
return bytes.HasPrefix(buf, tifII) || bytes.HasPrefix(buf, tifMM)
|
||||
}
|
||||
|
||||
var webpHeader = []byte("\x57\x45\x42\x50")
|
||||
|
||||
func isWEBP(buf []byte) bool {
|
||||
return bytes.Equal(buf[8:12], webpHeader)
|
||||
}
|
||||
|
||||
// https://github.com/strukturag/libheif/blob/master/libheif/heif.cc
|
||||
var ftyp = []byte("ftyp")
|
||||
var heic = []byte("heic")
|
||||
var mif1 = []byte("mif1")
|
||||
var msf1 = []byte("msf1")
|
||||
var avif = []byte("avif")
|
||||
|
||||
func isHEIF(buf []byte) bool {
|
||||
return bytes.Equal(buf[4:8], ftyp) && (bytes.Equal(buf[8:12], heic) ||
|
||||
bytes.Equal(buf[8:12], mif1) ||
|
||||
bytes.Equal(buf[8:12], msf1)) ||
|
||||
isAVIF(buf)
|
||||
}
|
||||
|
||||
func isAVIF(buf []byte) bool {
|
||||
return bytes.Equal(buf[4:8], ftyp) && bytes.Equal(buf[8:12], avif)
|
||||
}
|
||||
|
||||
var svg = []byte("<svg")
|
||||
|
||||
func isSVG(buf []byte) bool {
|
||||
sub := buf[:int(math.Min(1024.0, float64(len(buf))))]
|
||||
if bytes.Contains(sub, svg) {
|
||||
data := &struct {
|
||||
XMLName xml.Name `xml:"svg"`
|
||||
}{}
|
||||
reader := bytes.NewReader(buf)
|
||||
decoder := xml.NewDecoder(reader)
|
||||
decoder.Strict = false
|
||||
decoder.CharsetReader = charset.NewReaderLabel
|
||||
|
||||
err := decoder.Decode(data)
|
||||
|
||||
return err == nil && data.XMLName.Local == "svg"
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
var pdf = []byte("\x25\x50\x44\x46")
|
||||
|
||||
func isPDF(buf []byte) bool {
|
||||
return bytes.HasPrefix(buf, pdf)
|
||||
}
|
||||
|
||||
var bmpHeader = []byte("BM")
|
||||
|
||||
func isBMP(buf []byte) bool {
|
||||
return bytes.HasPrefix(buf, bmpHeader)
|
||||
}
|
||||
|
||||
// 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
|
||||
func isJP2K(buf []byte) bool {
|
||||
return bytes.HasPrefix(buf, jp2kHeader)
|
||||
}
|
||||
|
||||
var jxlHeader = []byte("\xff\x0a")
|
||||
|
||||
func isJXL(buf []byte) bool {
|
||||
return bytes.HasPrefix(buf, jxlHeader)
|
||||
}
|
||||
|
||||
func vipsLoadFromBuffer(buf []byte, params *ImportParams) (*C.VipsImage, ImageType, ImageType, error) {
|
||||
src := buf
|
||||
// Reference src here so it's not garbage collected during image initialization.
|
||||
defer runtime.KeepAlive(src)
|
||||
|
||||
var err error
|
||||
|
||||
originalType := DetermineImageType(src)
|
||||
currentType := originalType
|
||||
|
||||
if originalType == ImageTypeBMP {
|
||||
src, err = bmpToPNG(src)
|
||||
if err != nil {
|
||||
return nil, currentType, originalType, err
|
||||
}
|
||||
|
||||
currentType = ImageTypePNG
|
||||
}
|
||||
|
||||
if !IsTypeSupported(currentType) {
|
||||
govipsLog("govips", LogLevelInfo, fmt.Sprintf("failed to understand image format size=%d", len(src)))
|
||||
return nil, currentType, originalType, ErrUnsupportedImageFormat
|
||||
}
|
||||
|
||||
importParams := createImportParams(currentType, params)
|
||||
|
||||
if err := C.load_from_buffer(&importParams, unsafe.Pointer(&src[0]), C.size_t(len(src))); err != 0 {
|
||||
return nil, currentType, originalType, handleImageError(importParams.outputImage)
|
||||
}
|
||||
|
||||
return importParams.outputImage, currentType, originalType, nil
|
||||
}
|
||||
|
||||
func bmpToPNG(src []byte) ([]byte, error) {
|
||||
i, err := bmp.Decode(bytes.NewReader(src))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var w bytes.Buffer
|
||||
pngEnc := png.Encoder{
|
||||
CompressionLevel: png.NoCompression,
|
||||
}
|
||||
err = pngEnc.Encode(&w, i)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return w.Bytes(), nil
|
||||
}
|
||||
|
||||
func maybeSetBoolParam(p BoolParameter, cp *C.Param) {
|
||||
if p.IsSet() {
|
||||
C.set_bool_param(cp, toGboolean(p.Get()))
|
||||
}
|
||||
}
|
||||
|
||||
func maybeSetIntParam(p IntParameter, cp *C.Param) {
|
||||
if p.IsSet() {
|
||||
C.set_int_param(cp, C.int(p.Get()))
|
||||
}
|
||||
}
|
||||
|
||||
func createImportParams(format ImageType, params *ImportParams) C.LoadParams {
|
||||
p := C.create_load_params(C.ImageType(format))
|
||||
|
||||
maybeSetBoolParam(params.AutoRotate, &p.autorotate)
|
||||
maybeSetBoolParam(params.FailOnError, &p.fail)
|
||||
maybeSetIntParam(params.Page, &p.page)
|
||||
maybeSetIntParam(params.NumPages, &p.n)
|
||||
maybeSetIntParam(params.JpegShrinkFactor, &p.jpegShrink)
|
||||
maybeSetBoolParam(params.HeifThumbnail, &p.heifThumbnail)
|
||||
maybeSetBoolParam(params.SvgUnlimited, &p.svgUnlimited)
|
||||
|
||||
if params.Density.IsSet() {
|
||||
C.set_double_param(&p.dpi, C.gdouble(params.Density.Get()))
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
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))
|
||||
p.jpegOptimizeCoding = C.int(boolToInt(params.OptimizeCoding))
|
||||
p.jpegSubsample = C.VipsForeignJpegSubsample(params.SubsampleMode)
|
||||
p.jpegTrellisQuant = C.int(boolToInt(params.TrellisQuant))
|
||||
p.jpegOvershootDeringing = C.int(boolToInt(params.OvershootDeringing))
|
||||
p.jpegOptimizeScans = C.int(boolToInt(params.OptimizeScans))
|
||||
p.jpegQuantTable = C.int(params.QuantTable)
|
||||
|
||||
return vipsSaveToBuffer(p)
|
||||
}
|
||||
|
||||
func vipsSavePNGToBuffer(in *C.VipsImage, params PngExportParams) ([]byte, error) {
|
||||
incOpCounter("save_png_buffer")
|
||||
|
||||
p := C.create_save_params(C.PNG)
|
||||
p.inputImage = in
|
||||
p.quality = C.int(params.Quality)
|
||||
p.stripMetadata = C.int(boolToInt(params.StripMetadata))
|
||||
p.interlace = C.int(boolToInt(params.Interlace))
|
||||
p.pngCompression = C.int(params.Compression)
|
||||
p.pngFilter = C.VipsForeignPngFilter(params.Filter)
|
||||
p.pngPalette = C.int(boolToInt(params.Palette))
|
||||
p.pngDither = C.double(params.Dither)
|
||||
p.pngBitdepth = C.int(params.Bitdepth)
|
||||
|
||||
return vipsSaveToBuffer(p)
|
||||
}
|
||||
|
||||
func vipsSaveWebPToBuffer(in *C.VipsImage, params WebpExportParams) ([]byte, error) {
|
||||
incOpCounter("save_webp_buffer")
|
||||
|
||||
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.webpNearLossless = C.int(boolToInt(params.NearLossless))
|
||||
p.webpReductionEffort = C.int(params.ReductionEffort)
|
||||
p.webpMinSize = C.int(boolToInt(params.MinSize))
|
||||
p.webpKMin = C.int(params.MinKeyFrames)
|
||||
p.webpKMax = C.int(params.MaxKeyFrames)
|
||||
|
||||
if params.IccProfile != "" {
|
||||
p.webpIccProfile = C.CString(params.IccProfile)
|
||||
defer C.free(unsafe.Pointer(p.webpIccProfile))
|
||||
}
|
||||
|
||||
return vipsSaveToBuffer(p)
|
||||
}
|
||||
|
||||
func vipsSaveTIFFToBuffer(in *C.VipsImage, params TiffExportParams) ([]byte, error) {
|
||||
incOpCounter("save_tiff_buffer")
|
||||
|
||||
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.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))
|
||||
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.stripMetadata = C.int(boolToInt(params.StripMetadata))
|
||||
p.outputFormat = C.AVIF
|
||||
p.quality = C.int(params.Quality)
|
||||
p.heifLossless = C.int(boolToInt(params.Lossless))
|
||||
p.heifBitdepth = C.int(params.Bitdepth)
|
||||
p.heifEffort = C.int(effort)
|
||||
|
||||
return vipsSaveToBuffer(p)
|
||||
}
|
||||
|
||||
func vipsSaveJP2KToBuffer(in *C.VipsImage, params Jp2kExportParams) ([]byte, error) {
|
||||
incOpCounter("save_jp2k_buffer")
|
||||
|
||||
p := C.create_save_params(C.JP2K)
|
||||
p.inputImage = in
|
||||
p.outputFormat = C.JP2K
|
||||
p.quality = C.int(params.Quality)
|
||||
p.jp2kLossless = C.int(boolToInt(params.Lossless))
|
||||
p.jp2kTileWidth = C.int(params.TileWidth)
|
||||
p.jp2kTileHeight = C.int(params.TileHeight)
|
||||
p.jpegSubsample = C.VipsForeignJpegSubsample(params.SubsampleMode)
|
||||
|
||||
return vipsSaveToBuffer(p)
|
||||
}
|
||||
|
||||
func vipsSaveGIFToBuffer(in *C.VipsImage, params GifExportParams) ([]byte, error) {
|
||||
incOpCounter("save_gif_buffer")
|
||||
|
||||
p := C.create_save_params(C.GIF)
|
||||
p.inputImage = in
|
||||
p.quality = C.int(params.Quality)
|
||||
p.gifDither = C.double(params.Dither)
|
||||
p.gifEffort = C.int(params.Effort)
|
||||
p.gifBitdepth = C.int(params.Bitdepth)
|
||||
|
||||
return vipsSaveToBuffer(p)
|
||||
}
|
||||
|
||||
func vipsSaveJxlToBuffer(in *C.VipsImage, params JxlExportParams) ([]byte, error) {
|
||||
incOpCounter("save_jxl_buffer")
|
||||
|
||||
p := C.create_save_params(C.JXL)
|
||||
p.inputImage = in
|
||||
p.outputFormat = C.JXL
|
||||
p.quality = C.int(params.Quality)
|
||||
p.jxlLossless = C.int(boolToInt(params.Lossless))
|
||||
p.jxlTier = C.int(params.Tier)
|
||||
p.jxlDistance = C.double(params.Distance)
|
||||
p.jxlEffort = C.int(params.Effort)
|
||||
|
||||
return vipsSaveToBuffer(p)
|
||||
}
|
||||
|
||||
func vipsSaveToBuffer(params C.struct_SaveParams) ([]byte, error) {
|
||||
if err := C.save_to_buffer(¶ms); err != 0 {
|
||||
return nil, handleSaveBufferError(params.outputBuffer)
|
||||
}
|
||||
|
||||
buf := C.GoBytes(params.outputBuffer, C.int(params.outputLen))
|
||||
defer gFreePointer(params.outputBuffer)
|
||||
|
||||
return buf, nil
|
||||
}
|
||||
141
vendor/github.com/davidbyttow/govips/v2/vips/foreign.h
generated
vendored
Normal file
141
vendor/github.com/davidbyttow/govips/v2/vips/foreign.h
generated
vendored
Normal file
@@ -0,0 +1,141 @@
|
||||
// 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,
|
||||
AVIF,
|
||||
JP2K,
|
||||
JXL
|
||||
} ImageType;
|
||||
|
||||
typedef enum ParamType {
|
||||
PARAM_TYPE_NULL,
|
||||
PARAM_TYPE_BOOL,
|
||||
PARAM_TYPE_INT,
|
||||
PARAM_TYPE_DOUBLE,
|
||||
} ParamType;
|
||||
|
||||
typedef struct Param {
|
||||
ParamType type;
|
||||
|
||||
union Value {
|
||||
gboolean b;
|
||||
gint i;
|
||||
gdouble d;
|
||||
} value;
|
||||
|
||||
gboolean is_set;
|
||||
|
||||
} Param;
|
||||
|
||||
void set_bool_param(Param *p, gboolean b);
|
||||
void set_int_param(Param *p, gint i);
|
||||
void set_double_param(Param *p, gdouble d);
|
||||
|
||||
typedef struct LoadParams {
|
||||
ImageType inputFormat;
|
||||
VipsBlob *inputBlob;
|
||||
VipsImage *outputImage;
|
||||
|
||||
Param autorotate;
|
||||
Param fail;
|
||||
Param page;
|
||||
Param n;
|
||||
Param dpi;
|
||||
Param jpegShrink;
|
||||
Param heifThumbnail;
|
||||
Param svgUnlimited;
|
||||
|
||||
} LoadParams;
|
||||
|
||||
LoadParams create_load_params(ImageType inputFormat);
|
||||
int load_from_buffer(LoadParams *params, void *buf, size_t len);
|
||||
|
||||
typedef struct SaveParams {
|
||||
VipsImage *inputImage;
|
||||
void *outputBuffer;
|
||||
ImageType outputFormat;
|
||||
size_t outputLen;
|
||||
|
||||
BOOL stripMetadata;
|
||||
int quality;
|
||||
BOOL interlace;
|
||||
|
||||
// JPEG
|
||||
BOOL jpegOptimizeCoding;
|
||||
VipsForeignJpegSubsample jpegSubsample;
|
||||
BOOL jpegTrellisQuant;
|
||||
BOOL jpegOvershootDeringing;
|
||||
BOOL jpegOptimizeScans;
|
||||
int jpegQuantTable;
|
||||
|
||||
// PNG
|
||||
int pngCompression;
|
||||
VipsForeignPngFilter pngFilter;
|
||||
BOOL pngPalette;
|
||||
double pngDither;
|
||||
int pngBitdepth;
|
||||
|
||||
// GIF (with CGIF)
|
||||
double gifDither;
|
||||
int gifEffort;
|
||||
int gifBitdepth;
|
||||
|
||||
// WEBP
|
||||
BOOL webpLossless;
|
||||
BOOL webpNearLossless;
|
||||
int webpReductionEffort;
|
||||
char *webpIccProfile;
|
||||
BOOL webpMinSize;
|
||||
int webpKMin;
|
||||
int webpKMax;
|
||||
|
||||
// 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;
|
||||
VipsForeignTiffPredictor tiffPredictor;
|
||||
BOOL tiffPyramid;
|
||||
BOOL tiffTile;
|
||||
int tiffTileHeight;
|
||||
int tiffTileWidth;
|
||||
|
||||
// JPEG2000
|
||||
BOOL jp2kLossless;
|
||||
int jp2kTileWidth;
|
||||
int jp2kTileHeight;
|
||||
|
||||
// JXL
|
||||
int jxlTier;
|
||||
double jxlDistance;
|
||||
int jxlEffort;
|
||||
BOOL jxlLossless;
|
||||
} SaveParams;
|
||||
|
||||
SaveParams create_save_params(ImageType outputFormat);
|
||||
int save_to_buffer(SaveParams *params);
|
||||
|
||||
27
vendor/github.com/davidbyttow/govips/v2/vips/govips.c
generated
vendored
Normal file
27
vendor/github.com/davidbyttow/govips/v2/vips/govips.c
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
#include "govips.h"
|
||||
|
||||
static void govips_logging_handler(const gchar *log_domain,
|
||||
GLogLevelFlags log_level,
|
||||
const gchar *message, gpointer user_data) {
|
||||
govipsLoggingHandler((char *)log_domain, (int)log_level, (char *)message);
|
||||
}
|
||||
|
||||
static void null_logging_handler(const gchar *log_domain,
|
||||
GLogLevelFlags log_level, const gchar *message,
|
||||
gpointer user_data) {}
|
||||
|
||||
void vips_set_logging_handler(void) {
|
||||
g_log_set_default_handler(govips_logging_handler, NULL);
|
||||
}
|
||||
|
||||
void vips_unset_logging_handler(void) {
|
||||
g_log_set_default_handler(null_logging_handler, NULL);
|
||||
}
|
||||
|
||||
/* This function skips the Govips logging handler and logs
|
||||
directly to stdout. To be used only for testing and debugging.
|
||||
Needed for CI because of a Go macOS bug which doesn't clean cgo callbacks on
|
||||
exit. */
|
||||
void vips_default_logging_handler(void) {
|
||||
g_log_set_default_handler(g_log_default_handler, NULL);
|
||||
}
|
||||
265
vendor/github.com/davidbyttow/govips/v2/vips/govips.go
generated
vendored
Normal file
265
vendor/github.com/davidbyttow/govips/v2/vips/govips.go
generated
vendored
Normal file
@@ -0,0 +1,265 @@
|
||||
// Package vips provides go bindings for libvips, a fast image processing library.
|
||||
package vips
|
||||
|
||||
// #cgo pkg-config: vips
|
||||
// #include <vips/vips.h>
|
||||
// #include "govips.h"
|
||||
import "C"
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultConcurrencyLevel = 1
|
||||
defaultMaxCacheMem = 50 * 1024 * 1024
|
||||
defaultMaxCacheSize = 100
|
||||
defaultMaxCacheFiles = 0
|
||||
)
|
||||
|
||||
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
|
||||
statCollectorDone chan struct{}
|
||||
once sync.Once
|
||||
typeLoaders = make(map[string]ImageType)
|
||||
supportedImageTypes = make(map[ImageType]bool)
|
||||
)
|
||||
|
||||
// Config allows fine-tuning of libvips library
|
||||
type Config struct {
|
||||
ConcurrencyLevel int
|
||||
MaxCacheFiles int
|
||||
MaxCacheMem int
|
||||
MaxCacheSize int
|
||||
ReportLeaks bool
|
||||
CacheTrace bool
|
||||
CollectStats bool
|
||||
}
|
||||
|
||||
// Startup sets up the libvips support and ensures the versions are correct. Pass in nil for
|
||||
// default configuration.
|
||||
func Startup(config *Config) {
|
||||
if hasShutdown {
|
||||
panic("govips cannot be stopped and restarted")
|
||||
}
|
||||
|
||||
initLock.Lock()
|
||||
defer initLock.Unlock()
|
||||
|
||||
runtime.LockOSThread()
|
||||
defer runtime.UnlockOSThread()
|
||||
|
||||
if running {
|
||||
govipsLog("govips", LogLevelInfo, "warning libvips already started")
|
||||
return
|
||||
}
|
||||
|
||||
if MajorVersion < 8 {
|
||||
panic("govips requires libvips version 8.10+")
|
||||
}
|
||||
|
||||
if MajorVersion == 8 && MinorVersion < 10 {
|
||||
panic("govips requires libvips version 8.10+")
|
||||
}
|
||||
|
||||
cName := C.CString("govips")
|
||||
defer freeCString(cName)
|
||||
|
||||
// Initialize govips logging handler and verbosity filter to historical default
|
||||
if !currentLoggingOverridden {
|
||||
govipsLoggingSettings(nil, LogLevelInfo)
|
||||
}
|
||||
|
||||
// Override default glib logging handler to intercept logging messages
|
||||
enableLogging()
|
||||
|
||||
err := C.vips_init(cName)
|
||||
if err != 0 {
|
||||
panic(fmt.Sprintf("Failed to start vips code=%v", err))
|
||||
}
|
||||
|
||||
initializeICCProfiles()
|
||||
|
||||
running = true
|
||||
|
||||
if config != nil {
|
||||
if config.CollectStats {
|
||||
statCollectorDone = collectStats()
|
||||
}
|
||||
|
||||
C.vips_leak_set(toGboolean(config.ReportLeaks))
|
||||
|
||||
if config.ConcurrencyLevel >= 0 {
|
||||
C.vips_concurrency_set(C.int(config.ConcurrencyLevel))
|
||||
} else {
|
||||
C.vips_concurrency_set(defaultConcurrencyLevel)
|
||||
}
|
||||
|
||||
if config.MaxCacheFiles >= 0 {
|
||||
C.vips_cache_set_max_files(C.int(config.MaxCacheFiles))
|
||||
} else {
|
||||
C.vips_cache_set_max_files(defaultMaxCacheFiles)
|
||||
}
|
||||
|
||||
if config.MaxCacheMem >= 0 {
|
||||
C.vips_cache_set_max_mem(C.size_t(config.MaxCacheMem))
|
||||
} else {
|
||||
C.vips_cache_set_max_mem(defaultMaxCacheMem)
|
||||
}
|
||||
|
||||
if config.MaxCacheSize >= 0 {
|
||||
C.vips_cache_set_max(C.int(config.MaxCacheSize))
|
||||
} else {
|
||||
C.vips_cache_set_max(defaultMaxCacheSize)
|
||||
}
|
||||
|
||||
if config.CacheTrace {
|
||||
C.vips_cache_set_trace(toGboolean(true))
|
||||
}
|
||||
} else {
|
||||
C.vips_concurrency_set(defaultConcurrencyLevel)
|
||||
C.vips_cache_set_max(defaultMaxCacheSize)
|
||||
C.vips_cache_set_max_mem(defaultMaxCacheMem)
|
||||
C.vips_cache_set_max_files(defaultMaxCacheFiles)
|
||||
}
|
||||
|
||||
govipsLog("govips", LogLevelInfo, fmt.Sprintf("vips %s started with concurrency=%d cache_max_files=%d cache_max_mem=%d cache_max=%d",
|
||||
Version,
|
||||
int(C.vips_concurrency_get()),
|
||||
int(C.vips_cache_get_max_files()),
|
||||
int(C.vips_cache_get_max_mem()),
|
||||
int(C.vips_cache_get_max())))
|
||||
|
||||
initTypes()
|
||||
}
|
||||
|
||||
func enableLogging() {
|
||||
C.vips_set_logging_handler()
|
||||
}
|
||||
|
||||
func disableLogging() {
|
||||
C.vips_unset_logging_handler()
|
||||
}
|
||||
|
||||
// consoleLogging overrides the Govips logging handler and makes glib
|
||||
// use its default logging handler which outputs everything to console.
|
||||
// Needed for CI unit testing due to a macOS bug in Go (doesn't clean cgo callbacks on exit)
|
||||
func consoleLogging() {
|
||||
C.vips_default_logging_handler()
|
||||
}
|
||||
|
||||
// Shutdown libvips
|
||||
func Shutdown() {
|
||||
hasShutdown = true
|
||||
|
||||
if statCollectorDone != nil {
|
||||
statCollectorDone <- struct{}{}
|
||||
}
|
||||
|
||||
initLock.Lock()
|
||||
defer initLock.Unlock()
|
||||
|
||||
runtime.LockOSThread()
|
||||
defer runtime.UnlockOSThread()
|
||||
|
||||
if !running {
|
||||
govipsLog("govips", LogLevelInfo, "warning libvips not started")
|
||||
return
|
||||
}
|
||||
|
||||
os.RemoveAll(temporaryDirectory)
|
||||
|
||||
C.vips_shutdown()
|
||||
disableLogging()
|
||||
running = false
|
||||
}
|
||||
|
||||
// ShutdownThread clears the cache for for the given thread. This needs to be
|
||||
// called when a thread using vips exits.
|
||||
func ShutdownThread() {
|
||||
C.vips_thread_shutdown()
|
||||
}
|
||||
|
||||
// ClearCache drops the whole operation cache, handy for leak tracking.
|
||||
func ClearCache() {
|
||||
C.vips_cache_drop_all()
|
||||
}
|
||||
|
||||
// PrintCache prints the whole operation cache to stdout for debugging purposes.
|
||||
func PrintCache() {
|
||||
C.vips_cache_print()
|
||||
}
|
||||
|
||||
// PrintObjectReport outputs all of the current internal objects in libvips
|
||||
func PrintObjectReport(label string) {
|
||||
govipsLog("govips", LogLevelInfo, fmt.Sprintf("\n=======================================\nvips live objects: %s...\n", label))
|
||||
C.vips_object_print_all()
|
||||
govipsLog("govips", LogLevelInfo, "=======================================\n\n")
|
||||
}
|
||||
|
||||
// MemoryStats is a data structure that houses various memory statistics from ReadVipsMemStats()
|
||||
type MemoryStats struct {
|
||||
Mem int64
|
||||
MemHigh int64
|
||||
Files int64
|
||||
Allocs int64
|
||||
}
|
||||
|
||||
// ReadVipsMemStats returns various memory statistics such as allocated memory and open files.
|
||||
func ReadVipsMemStats(stats *MemoryStats) {
|
||||
stats.Mem = int64(C.vips_tracked_get_mem())
|
||||
stats.MemHigh = int64(C.vips_tracked_get_mem_highwater())
|
||||
stats.Allocs = int64(C.vips_tracked_get_allocs())
|
||||
stats.Files = int64(C.vips_tracked_get_files())
|
||||
}
|
||||
|
||||
func startupIfNeeded() {
|
||||
if !running {
|
||||
govipsLog("govips", LogLevelInfo, "libvips was forcibly started automatically, consider calling Startup/Shutdown yourself")
|
||||
Startup(nil)
|
||||
}
|
||||
}
|
||||
|
||||
// InitTypes initializes caches and figures out which image types are supported
|
||||
func initTypes() {
|
||||
once.Do(func() {
|
||||
cType := C.CString("VipsOperation")
|
||||
defer freeCString(cType)
|
||||
|
||||
for k, v := range ImageTypes {
|
||||
name := strings.ToLower("VipsForeignLoad" + v)
|
||||
typeLoaders[name] = k
|
||||
typeLoaders[name+"buffer"] = k
|
||||
|
||||
cFunc := C.CString(v + "load")
|
||||
//noinspection GoDeferInLoop
|
||||
defer freeCString(cFunc)
|
||||
|
||||
ret := C.vips_type_find(cType, cFunc)
|
||||
|
||||
supportedImageTypes[k] = int(ret) != 0
|
||||
|
||||
if supportedImageTypes[k] {
|
||||
govipsLog("govips", LogLevelInfo, fmt.Sprintf("registered image type loader type=%s", v))
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
26
vendor/github.com/davidbyttow/govips/v2/vips/govips.h
generated
vendored
Normal file
26
vendor/github.com/davidbyttow/govips/v2/vips/govips.h
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
|
||||
// clang-format off
|
||||
// include order matters
|
||||
#include <stdlib.h>
|
||||
#include <glib.h>
|
||||
#include <vips/vips.h>
|
||||
// clang-format on
|
||||
|
||||
#if (VIPS_MAJOR_VERSION < 8)
|
||||
error_requires_version_8
|
||||
#endif
|
||||
|
||||
extern void
|
||||
govipsLoggingHandler(char *log_domain, int log_level, char *message);
|
||||
|
||||
static void govips_logging_handler(const gchar *log_domain,
|
||||
GLogLevelFlags log_level,
|
||||
const gchar *message, gpointer user_data);
|
||||
|
||||
static void null_logging_handler(const gchar *log_domain,
|
||||
GLogLevelFlags log_level, const gchar *message,
|
||||
gpointer user_data);
|
||||
|
||||
void vips_set_logging_handler(void);
|
||||
void vips_unset_logging_handler(void);
|
||||
void vips_default_logging_handler(void);
|
||||
122
vendor/github.com/davidbyttow/govips/v2/vips/header.c
generated
vendored
Normal file
122
vendor/github.com/davidbyttow/govips/v2/vips/header.c
generated
vendored
Normal file
@@ -0,0 +1,122 @@
|
||||
#include "header.h"
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
unsigned long has_icc_profile(VipsImage *in) {
|
||||
return vips_image_get_typeof(in, VIPS_META_ICC_NAME);
|
||||
}
|
||||
|
||||
unsigned long get_icc_profile(VipsImage *in, const void **data,
|
||||
size_t *dataLength) {
|
||||
return image_get_blob(in, VIPS_META_ICC_NAME, data, dataLength);
|
||||
}
|
||||
|
||||
gboolean remove_icc_profile(VipsImage *in) {
|
||||
return vips_image_remove(in, VIPS_META_ICC_NAME);
|
||||
}
|
||||
|
||||
unsigned long has_iptc(VipsImage *in) {
|
||||
return vips_image_get_typeof(in, VIPS_META_IPTC_NAME);
|
||||
}
|
||||
|
||||
char **image_get_fields(VipsImage *in) { return vips_image_get_fields(in); }
|
||||
|
||||
void image_set_string(VipsImage *in, const char *name, const char *str) {
|
||||
vips_image_set_string(in, name, str);
|
||||
}
|
||||
|
||||
unsigned long image_get_string(VipsImage *in, const char *name,
|
||||
const char **out) {
|
||||
return vips_image_get_string(in, name, out);
|
||||
}
|
||||
|
||||
unsigned long image_get_as_string(VipsImage *in, const char *name, char **out) {
|
||||
return vips_image_get_as_string(in, name, out);
|
||||
}
|
||||
|
||||
void remove_field(VipsImage *in, char *field) { vips_image_remove(in, field); }
|
||||
|
||||
int get_meta_orientation(VipsImage *in) {
|
||||
int orientation = 0;
|
||||
if (vips_image_get_typeof(in, VIPS_META_ORIENTATION) != 0) {
|
||||
vips_image_get_int(in, VIPS_META_ORIENTATION, &orientation);
|
||||
}
|
||||
|
||||
return orientation;
|
||||
}
|
||||
|
||||
void remove_meta_orientation(VipsImage *in) {
|
||||
vips_image_remove(in, VIPS_META_ORIENTATION);
|
||||
}
|
||||
|
||||
void set_meta_orientation(VipsImage *in, int orientation) {
|
||||
vips_image_set_int(in, VIPS_META_ORIENTATION, orientation);
|
||||
}
|
||||
|
||||
// https://libvips.github.io/libvips/API/current/libvips-header.html#vips-image-get-n-pages
|
||||
int get_image_n_pages(VipsImage *in) {
|
||||
int n_pages = 0;
|
||||
n_pages = vips_image_get_n_pages(in);
|
||||
return n_pages;
|
||||
}
|
||||
|
||||
void set_image_n_pages(VipsImage *in, int n_pages) {
|
||||
vips_image_set_int(in, VIPS_META_N_PAGES, n_pages);
|
||||
}
|
||||
|
||||
// https://www.libvips.org/API/current/libvips-header.html#vips-image-get-page-height
|
||||
int get_page_height(VipsImage *in) {
|
||||
int page_height = 0;
|
||||
page_height = vips_image_get_page_height(in);
|
||||
return page_height;
|
||||
}
|
||||
|
||||
void set_page_height(VipsImage *in, int height) {
|
||||
vips_image_set_int(in, VIPS_META_PAGE_HEIGHT, height);
|
||||
}
|
||||
|
||||
int get_meta_loader(const VipsImage *in, const char **out) {
|
||||
return vips_image_get_string(in, VIPS_META_LOADER, out);
|
||||
}
|
||||
|
||||
int get_image_delay(VipsImage *in, int **out) {
|
||||
return vips_image_get_array_int(in, "delay", out, NULL);
|
||||
}
|
||||
|
||||
void set_image_delay(VipsImage *in, const int *array, int n) {
|
||||
return vips_image_set_array_int(in, "delay", array, n);
|
||||
}
|
||||
|
||||
void image_set_double(VipsImage *in, const char *name, double i) {
|
||||
vips_image_set_double(in, name, i);
|
||||
}
|
||||
|
||||
unsigned long image_get_double(VipsImage *in, const char *name, double *out) {
|
||||
return vips_image_get_double(in, name, out);
|
||||
}
|
||||
|
||||
void image_set_int(VipsImage *in, const char *name, int i) {
|
||||
vips_image_set_int(in, name, i);
|
||||
}
|
||||
|
||||
unsigned long image_get_int(VipsImage *in, const char *name, int *out) {
|
||||
return vips_image_get_int(in, name, out);
|
||||
}
|
||||
|
||||
void image_set_blob(VipsImage *in, const char *name, const void *data,
|
||||
size_t dataLength) {
|
||||
vips_image_set_blob_copy(in, name, data, dataLength);
|
||||
}
|
||||
|
||||
unsigned long image_get_blob(VipsImage *in, const char *name, const void **data,
|
||||
size_t *dataLength) {
|
||||
if (vips_image_get_typeof(in, name) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (vips_image_get_blob(in, name, data, dataLength)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
289
vendor/github.com/davidbyttow/govips/v2/vips/header.go
generated
vendored
Normal file
289
vendor/github.com/davidbyttow/govips/v2/vips/header.go
generated
vendored
Normal file
@@ -0,0 +1,289 @@
|
||||
package vips
|
||||
|
||||
// #include "header.h"
|
||||
import "C"
|
||||
import (
|
||||
"strings"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func vipsHasICCProfile(in *C.VipsImage) bool {
|
||||
return int(C.has_icc_profile(in)) != 0
|
||||
}
|
||||
|
||||
func vipsGetICCProfile(in *C.VipsImage) ([]byte, bool) {
|
||||
var bufPtr unsafe.Pointer
|
||||
var dataLength C.size_t
|
||||
|
||||
if int(C.get_icc_profile(in, &bufPtr, &dataLength)) != 0 {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
buf := C.GoBytes(bufPtr, C.int(dataLength))
|
||||
return buf, true
|
||||
}
|
||||
|
||||
func vipsRemoveICCProfile(in *C.VipsImage) bool {
|
||||
return fromGboolean(C.remove_icc_profile(in))
|
||||
}
|
||||
|
||||
func vipsHasIPTC(in *C.VipsImage) bool {
|
||||
return int(C.has_iptc(in)) != 0
|
||||
}
|
||||
|
||||
func vipsImageGetFields(in *C.VipsImage) (fields []string) {
|
||||
const maxFields = 256
|
||||
|
||||
rawFields := C.image_get_fields(in)
|
||||
defer C.g_strfreev(rawFields)
|
||||
|
||||
cFields := (*[maxFields]*C.char)(unsafe.Pointer(rawFields))[:maxFields:maxFields]
|
||||
|
||||
for _, field := range cFields {
|
||||
if field == nil {
|
||||
break
|
||||
}
|
||||
fields = append(fields, C.GoString(field))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func vipsImageGetExifData(in *C.VipsImage) map[string]string {
|
||||
fields := vipsImageGetFields(in)
|
||||
|
||||
exifData := map[string]string{}
|
||||
for _, field := range fields {
|
||||
if strings.HasPrefix(field, "exif") {
|
||||
exifData[field] = vipsImageGetString(in, field)
|
||||
}
|
||||
}
|
||||
|
||||
return exifData
|
||||
}
|
||||
|
||||
func vipsRemoveMetadata(in *C.VipsImage, keep ...string) {
|
||||
fields := vipsImageGetFields(in)
|
||||
|
||||
retain := append(keep, technicalMetadata...)
|
||||
|
||||
for _, field := range fields {
|
||||
if contains(retain, field) {
|
||||
continue
|
||||
}
|
||||
|
||||
cField := C.CString(field)
|
||||
|
||||
C.remove_field(in, cField)
|
||||
|
||||
C.free(unsafe.Pointer(cField))
|
||||
}
|
||||
}
|
||||
|
||||
var technicalMetadata = []string{
|
||||
C.VIPS_META_ICC_NAME,
|
||||
C.VIPS_META_ORIENTATION,
|
||||
C.VIPS_META_N_PAGES,
|
||||
C.VIPS_META_PAGE_HEIGHT,
|
||||
}
|
||||
|
||||
func contains(a []string, x string) bool {
|
||||
for _, n := range a {
|
||||
if x == n {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func vipsGetMetaOrientation(in *C.VipsImage) int {
|
||||
return int(C.get_meta_orientation(in))
|
||||
}
|
||||
|
||||
func vipsRemoveMetaOrientation(in *C.VipsImage) {
|
||||
C.remove_meta_orientation(in)
|
||||
}
|
||||
|
||||
func vipsSetMetaOrientation(in *C.VipsImage, orientation int) {
|
||||
C.set_meta_orientation(in, C.int(orientation))
|
||||
}
|
||||
|
||||
func vipsGetImageNPages(in *C.VipsImage) int {
|
||||
return int(C.get_image_n_pages(in))
|
||||
}
|
||||
|
||||
func vipsSetImageNPages(in *C.VipsImage, pages int) {
|
||||
C.set_image_n_pages(in, C.int(pages))
|
||||
}
|
||||
|
||||
func vipsGetPageHeight(in *C.VipsImage) int {
|
||||
return int(C.get_page_height(in))
|
||||
}
|
||||
|
||||
func vipsSetPageHeight(in *C.VipsImage, height int) {
|
||||
C.set_page_height(in, C.int(height))
|
||||
}
|
||||
|
||||
func vipsImageGetMetaLoader(in *C.VipsImage) (string, bool) {
|
||||
var out *C.char
|
||||
defer freeCString(out)
|
||||
code := int(C.get_meta_loader(in, &out))
|
||||
return C.GoString(out), code == 0
|
||||
}
|
||||
|
||||
func vipsImageGetDelay(in *C.VipsImage, n int) ([]int, error) {
|
||||
incOpCounter("imageGetDelay")
|
||||
var out *C.int
|
||||
defer gFreePointer(unsafe.Pointer(out))
|
||||
|
||||
if err := C.get_image_delay(in, &out); err != 0 {
|
||||
return nil, handleVipsError()
|
||||
}
|
||||
return fromCArrayInt(out, n), nil
|
||||
}
|
||||
|
||||
func vipsImageSetDelay(in *C.VipsImage, data []C.int) error {
|
||||
incOpCounter("imageSetDelay")
|
||||
if n := len(data); n > 0 {
|
||||
C.set_image_delay(in, &data[0], C.int(n))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// vipsDetermineImageTypeFromMetaLoader determine the image type from vips-loader metadata
|
||||
func vipsDetermineImageTypeFromMetaLoader(in *C.VipsImage) ImageType {
|
||||
vipsLoader, ok := vipsImageGetMetaLoader(in)
|
||||
if vipsLoader == "" || !ok {
|
||||
return ImageTypeUnknown
|
||||
}
|
||||
if strings.HasPrefix(vipsLoader, "jpeg") {
|
||||
return ImageTypeJPEG
|
||||
}
|
||||
if strings.HasPrefix(vipsLoader, "png") {
|
||||
return ImageTypePNG
|
||||
}
|
||||
if strings.HasPrefix(vipsLoader, "gif") {
|
||||
return ImageTypeGIF
|
||||
}
|
||||
if strings.HasPrefix(vipsLoader, "svg") {
|
||||
return ImageTypeSVG
|
||||
}
|
||||
if strings.HasPrefix(vipsLoader, "webp") {
|
||||
return ImageTypeWEBP
|
||||
}
|
||||
if strings.HasPrefix(vipsLoader, "jp2k") {
|
||||
return ImageTypeJP2K
|
||||
}
|
||||
if strings.HasPrefix(vipsLoader, "jxl") {
|
||||
return ImageTypeJXL
|
||||
}
|
||||
if strings.HasPrefix(vipsLoader, "magick") {
|
||||
return ImageTypeMagick
|
||||
}
|
||||
if strings.HasPrefix(vipsLoader, "tiff") {
|
||||
return ImageTypeTIFF
|
||||
}
|
||||
if strings.HasPrefix(vipsLoader, "heif") {
|
||||
return ImageTypeHEIF
|
||||
}
|
||||
if strings.HasPrefix(vipsLoader, "pdf") {
|
||||
return ImageTypePDF
|
||||
}
|
||||
return ImageTypeUnknown
|
||||
}
|
||||
|
||||
func vipsImageSetBlob(in *C.VipsImage, name string, data []byte) {
|
||||
cData := unsafe.Pointer(&data)
|
||||
cDataLength := C.size_t(len(data))
|
||||
|
||||
cField := C.CString(name)
|
||||
defer freeCString(cField)
|
||||
C.image_set_blob(in, cField, cData, cDataLength)
|
||||
}
|
||||
|
||||
func vipsImageGetBlob(in *C.VipsImage, name string) []byte {
|
||||
var bufPtr unsafe.Pointer
|
||||
var dataLength C.size_t
|
||||
|
||||
cField := C.CString(name)
|
||||
defer freeCString(cField)
|
||||
if int(C.image_get_blob(in, cField, &bufPtr, &dataLength)) != 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
buf := C.GoBytes(bufPtr, C.int(dataLength))
|
||||
return buf
|
||||
}
|
||||
|
||||
func vipsImageSetDouble(in *C.VipsImage, name string, f float64) {
|
||||
cField := C.CString(name)
|
||||
defer freeCString(cField)
|
||||
|
||||
cDouble := C.double(f)
|
||||
C.image_set_double(in, cField, cDouble)
|
||||
}
|
||||
|
||||
func vipsImageGetDouble(in *C.VipsImage, name string) float64 {
|
||||
cField := C.CString(name)
|
||||
defer freeCString(cField)
|
||||
|
||||
var cDouble C.double
|
||||
if int(C.image_get_double(in, cField, &cDouble)) == 0 {
|
||||
return float64(cDouble)
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func vipsImageSetInt(in *C.VipsImage, name string, i int) {
|
||||
cField := C.CString(name)
|
||||
defer freeCString(cField)
|
||||
|
||||
cInt := C.int(i)
|
||||
C.image_set_int(in, cField, cInt)
|
||||
}
|
||||
|
||||
func vipsImageGetInt(in *C.VipsImage, name string) int {
|
||||
cField := C.CString(name)
|
||||
defer freeCString(cField)
|
||||
|
||||
var cInt C.int
|
||||
if int(C.image_get_int(in, cField, &cInt)) == 0 {
|
||||
return int(cInt)
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func vipsImageSetString(in *C.VipsImage, name string, str string) {
|
||||
cField := C.CString(name)
|
||||
defer freeCString(cField)
|
||||
|
||||
cStr := C.CString(str)
|
||||
defer freeCString(cStr)
|
||||
|
||||
C.image_set_string(in, cField, cStr)
|
||||
}
|
||||
|
||||
func vipsImageGetString(in *C.VipsImage, name string) string {
|
||||
cField := C.CString(name)
|
||||
defer freeCString(cField)
|
||||
var cFieldValue *C.char
|
||||
defer freeCString(cFieldValue)
|
||||
if int(C.image_get_string(in, cField, &cFieldValue)) == 0 {
|
||||
return C.GoString(cFieldValue)
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func vipsImageGetAsString(in *C.VipsImage, name string) string {
|
||||
cField := C.CString(name)
|
||||
defer freeCString(cField)
|
||||
var cFieldValue *C.char
|
||||
defer freeCString(cFieldValue)
|
||||
if int(C.image_get_as_string(in, cField, &cFieldValue)) == 0 {
|
||||
return C.GoString(cFieldValue)
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
41
vendor/github.com/davidbyttow/govips/v2/vips/header.h
generated
vendored
Normal file
41
vendor/github.com/davidbyttow/govips/v2/vips/header.h
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
// https://libvips.github.io/libvips/API/current/libvips-header.html
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <vips/vips.h>
|
||||
|
||||
unsigned long has_icc_profile(VipsImage *in);
|
||||
unsigned long get_icc_profile(VipsImage *in, const void **data,
|
||||
size_t *dataLength);
|
||||
int remove_icc_profile(VipsImage *in);
|
||||
|
||||
unsigned long has_iptc(VipsImage *in);
|
||||
char **image_get_fields(VipsImage *in);
|
||||
|
||||
void image_set_string(VipsImage *in, const char *name, const char *str);
|
||||
unsigned long image_get_string(VipsImage *in, const char *name,
|
||||
const char **out);
|
||||
unsigned long image_get_as_string(VipsImage *in, const char *name, char **out);
|
||||
|
||||
void remove_field(VipsImage *in, char *field);
|
||||
|
||||
int get_meta_orientation(VipsImage *in);
|
||||
void remove_meta_orientation(VipsImage *in);
|
||||
void set_meta_orientation(VipsImage *in, int orientation);
|
||||
int get_image_n_pages(VipsImage *in);
|
||||
void set_image_n_pages(VipsImage *in, int n_pages);
|
||||
int get_page_height(VipsImage *in);
|
||||
void set_page_height(VipsImage *in, int height);
|
||||
int get_meta_loader(const VipsImage *in, const char **out);
|
||||
int get_image_delay(VipsImage *in, int **out);
|
||||
void set_image_delay(VipsImage *in, const int *array, int n);
|
||||
|
||||
void image_set_blob(VipsImage *in, const char *name, const void *data,
|
||||
size_t dataLength);
|
||||
unsigned long image_get_blob(VipsImage *in, const char *name, const void **data,
|
||||
size_t *dataLength);
|
||||
|
||||
void image_set_double(VipsImage *in, const char *name, double i);
|
||||
unsigned long image_get_double(VipsImage *in, const char *name, double *out);
|
||||
|
||||
void image_set_int(VipsImage *in, const char *name, int i);
|
||||
unsigned long image_get_int(VipsImage *in, const char *name, int *out);
|
||||
675
vendor/github.com/davidbyttow/govips/v2/vips/icc_profiles.go
generated
vendored
Normal file
675
vendor/github.com/davidbyttow/govips/v2/vips/icc_profiles.go
generated
vendored
Normal file
@@ -0,0 +1,675 @@
|
||||
package vips
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
var (
|
||||
// ATTRIBUTION:
|
||||
// The following micro icc profile taken from: https://github.com/saucecontrol/Compact-ICC-Profiles.
|
||||
// Read more (very interesting): https://photosauce.net/blog/post/making-a-minimal-srgb-icc-profile-part-1-trim-the-fat-abuse-the-spec
|
||||
sRGBV2MicroICCProfile = []byte{
|
||||
0x00, 0x00, 0x01, 0xc8, 0x6c, 0x63, 0x6d, 0x73, 0x02, 0x10, 0x00, 0x00,
|
||||
0x6d, 0x6e, 0x74, 0x72, 0x52, 0x47, 0x42, 0x20, 0x58, 0x59, 0x5a, 0x20,
|
||||
0x07, 0xe2, 0x00, 0x03, 0x00, 0x14, 0x00, 0x09, 0x00, 0x0e, 0x00, 0x1d,
|
||||
0x61, 0x63, 0x73, 0x70, 0x4d, 0x53, 0x46, 0x54, 0x00, 0x00, 0x00, 0x00,
|
||||
0x73, 0x61, 0x77, 0x73, 0x63, 0x74, 0x72, 0x6c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xd6,
|
||||
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d, 0x68, 0x61, 0x6e, 0x64,
|
||||
0x9d, 0x91, 0x00, 0x3d, 0x40, 0x80, 0xb0, 0x3d, 0x40, 0x74, 0x2c, 0x81,
|
||||
0x9e, 0xa5, 0x22, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09,
|
||||
0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x5f,
|
||||
0x63, 0x70, 0x72, 0x74, 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x0c,
|
||||
0x77, 0x74, 0x70, 0x74, 0x00, 0x00, 0x01, 0x18, 0x00, 0x00, 0x00, 0x14,
|
||||
0x72, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x01, 0x2c, 0x00, 0x00, 0x00, 0x14,
|
||||
0x67, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x14,
|
||||
0x62, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x01, 0x54, 0x00, 0x00, 0x00, 0x14,
|
||||
0x72, 0x54, 0x52, 0x43, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00, 0x00, 0x60,
|
||||
0x67, 0x54, 0x52, 0x43, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00, 0x00, 0x60,
|
||||
0x62, 0x54, 0x52, 0x43, 0x00, 0x00, 0x01, 0x68, 0x00, 0x00, 0x00, 0x60,
|
||||
0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
|
||||
0x75, 0x52, 0x47, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x74, 0x65, 0x78, 0x74, 0x00, 0x00, 0x00, 0x00,
|
||||
0x43, 0x43, 0x30, 0x00, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xf3, 0x54, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x16, 0xc9,
|
||||
0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6f, 0xa0,
|
||||
0x00, 0x00, 0x38, 0xf2, 0x00, 0x00, 0x03, 0x8f, 0x58, 0x59, 0x5a, 0x20,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x96, 0x00, 0x00, 0xb7, 0x89,
|
||||
0x00, 0x00, 0x18, 0xda, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x24, 0xa0, 0x00, 0x00, 0x0f, 0x85, 0x00, 0x00, 0xb6, 0xc4,
|
||||
0x63, 0x75, 0x72, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a,
|
||||
0x00, 0x00, 0x00, 0x7c, 0x00, 0xf8, 0x01, 0x9c, 0x02, 0x75, 0x03, 0x83,
|
||||
0x04, 0xc9, 0x06, 0x4e, 0x08, 0x12, 0x0a, 0x18, 0x0c, 0x62, 0x0e, 0xf4,
|
||||
0x11, 0xcf, 0x14, 0xf6, 0x18, 0x6a, 0x1c, 0x2e, 0x20, 0x43, 0x24, 0xac,
|
||||
0x29, 0x6a, 0x2e, 0x7e, 0x33, 0xeb, 0x39, 0xb3, 0x3f, 0xd6, 0x46, 0x57,
|
||||
0x4d, 0x36, 0x54, 0x76, 0x5c, 0x17, 0x64, 0x1d, 0x6c, 0x86, 0x75, 0x56,
|
||||
0x7e, 0x8d, 0x88, 0x2c, 0x92, 0x36, 0x9c, 0xab, 0xa7, 0x8c, 0xb2, 0xdb,
|
||||
0xbe, 0x99, 0xca, 0xc7, 0xd7, 0x65, 0xe4, 0x77, 0xf1, 0xf9, 0xff, 0xff,
|
||||
}
|
||||
|
||||
// ATTRIBUTION:
|
||||
// The following micro icc profile taken from: https://github.com/saucecontrol/Compact-ICC-Profiles.
|
||||
// Read more (very interesting): https://photosauce.net/blog/post/making-a-minimal-srgb-icc-profile-part-1-trim-the-fat-abuse-the-spec
|
||||
sGrayV2MicroICCProfile = []byte{
|
||||
0x00, 0x00, 0x01, 0x50, 0x6c, 0x63, 0x6d, 0x73, 0x02, 0x10, 0x00, 0x00,
|
||||
0x6d, 0x6e, 0x74, 0x72, 0x47, 0x52, 0x41, 0x59, 0x58, 0x59, 0x5a, 0x20,
|
||||
0x07, 0xe2, 0x00, 0x03, 0x00, 0x14, 0x00, 0x09, 0x00, 0x0e, 0x00, 0x1d,
|
||||
0x61, 0x63, 0x73, 0x70, 0x4d, 0x53, 0x46, 0x54, 0x00, 0x00, 0x00, 0x00,
|
||||
0x73, 0x61, 0x77, 0x73, 0x63, 0x74, 0x72, 0x6c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xd6,
|
||||
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d, 0x68, 0x61, 0x6e, 0x64,
|
||||
0x05, 0xd2, 0x02, 0xa7, 0xf9, 0xdd, 0x47, 0x94, 0xc7, 0x4f, 0x4c, 0x5f,
|
||||
0x26, 0x82, 0x3a, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
|
||||
0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, 0x5f,
|
||||
0x63, 0x70, 0x72, 0x74, 0x00, 0x00, 0x00, 0xd0, 0x00, 0x00, 0x00, 0x0c,
|
||||
0x77, 0x74, 0x70, 0x74, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, 0x14,
|
||||
0x6b, 0x54, 0x52, 0x43, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x60,
|
||||
0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
|
||||
0x75, 0x47, 0x72, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x74, 0x65, 0x78, 0x74, 0x00, 0x00, 0x00, 0x00,
|
||||
0x43, 0x43, 0x30, 0x00, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xf3, 0x54, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x16, 0xc9,
|
||||
0x63, 0x75, 0x72, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a,
|
||||
0x00, 0x00, 0x00, 0x7c, 0x00, 0xf8, 0x01, 0x9c, 0x02, 0x75, 0x03, 0x83,
|
||||
0x04, 0xc9, 0x06, 0x4e, 0x08, 0x12, 0x0a, 0x18, 0x0c, 0x62, 0x0e, 0xf4,
|
||||
0x11, 0xcf, 0x14, 0xf6, 0x18, 0x6a, 0x1c, 0x2e, 0x20, 0x43, 0x24, 0xac,
|
||||
0x29, 0x6a, 0x2e, 0x7e, 0x33, 0xeb, 0x39, 0xb3, 0x3f, 0xd6, 0x46, 0x57,
|
||||
0x4d, 0x36, 0x54, 0x76, 0x5c, 0x17, 0x64, 0x1d, 0x6c, 0x86, 0x75, 0x56,
|
||||
0x7e, 0x8d, 0x88, 0x2c, 0x92, 0x36, 0x9c, 0xab, 0xa7, 0x8c, 0xb2, 0xdb,
|
||||
0xbe, 0x99, 0xca, 0xc7, 0xd7, 0x65, 0xe4, 0x77, 0xf1, 0xf9, 0xff, 0xff,
|
||||
}
|
||||
|
||||
sRGBIEC6196621ICCProfile = []byte{
|
||||
0x00, 0x00, 0x0b, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||
0x6d, 0x6e, 0x74, 0x72, 0x52, 0x47, 0x42, 0x20, 0x58, 0x59, 0x5a, 0x20,
|
||||
0x07, 0xd9, 0x00, 0x03, 0x00, 0x1b, 0x00, 0x15, 0x00, 0x24, 0x00, 0x1f,
|
||||
0x61, 0x63, 0x73, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xd6,
|
||||
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d, 0x00, 0x00, 0x00, 0x00,
|
||||
0x29, 0xf8, 0x3d, 0xde, 0xaf, 0xf2, 0x55, 0xae, 0x78, 0x42, 0xfa, 0xe4,
|
||||
0xca, 0x83, 0x39, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
|
||||
0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x01, 0x44, 0x00, 0x00, 0x00, 0x79,
|
||||
0x62, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x00, 0x14,
|
||||
0x62, 0x54, 0x52, 0x43, 0x00, 0x00, 0x01, 0xd4, 0x00, 0x00, 0x08, 0x0c,
|
||||
0x64, 0x6d, 0x64, 0x64, 0x00, 0x00, 0x09, 0xe0, 0x00, 0x00, 0x00, 0x88,
|
||||
0x67, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x0a, 0x68, 0x00, 0x00, 0x00, 0x14,
|
||||
0x67, 0x54, 0x52, 0x43, 0x00, 0x00, 0x01, 0xd4, 0x00, 0x00, 0x08, 0x0c,
|
||||
0x6c, 0x75, 0x6d, 0x69, 0x00, 0x00, 0x0a, 0x7c, 0x00, 0x00, 0x00, 0x14,
|
||||
0x6d, 0x65, 0x61, 0x73, 0x00, 0x00, 0x0a, 0x90, 0x00, 0x00, 0x00, 0x24,
|
||||
0x62, 0x6b, 0x70, 0x74, 0x00, 0x00, 0x0a, 0xb4, 0x00, 0x00, 0x00, 0x14,
|
||||
0x72, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x0a, 0xc8, 0x00, 0x00, 0x00, 0x14,
|
||||
0x72, 0x54, 0x52, 0x43, 0x00, 0x00, 0x01, 0xd4, 0x00, 0x00, 0x08, 0x0c,
|
||||
0x74, 0x65, 0x63, 0x68, 0x00, 0x00, 0x0a, 0xdc, 0x00, 0x00, 0x00, 0x0c,
|
||||
0x76, 0x75, 0x65, 0x64, 0x00, 0x00, 0x0a, 0xe8, 0x00, 0x00, 0x00, 0x87,
|
||||
0x77, 0x74, 0x70, 0x74, 0x00, 0x00, 0x0b, 0x70, 0x00, 0x00, 0x00, 0x14,
|
||||
0x63, 0x70, 0x72, 0x74, 0x00, 0x00, 0x0b, 0x84, 0x00, 0x00, 0x00, 0x37,
|
||||
0x63, 0x68, 0x61, 0x64, 0x00, 0x00, 0x0b, 0xbc, 0x00, 0x00, 0x00, 0x2c,
|
||||
0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f,
|
||||
0x73, 0x52, 0x47, 0x42, 0x20, 0x49, 0x45, 0x43, 0x36, 0x31, 0x39, 0x36,
|
||||
0x36, 0x2d, 0x32, 0x2d, 0x31, 0x20, 0x62, 0x6c, 0x61, 0x63, 0x6b, 0x20,
|
||||
0x73, 0x63, 0x61, 0x6c, 0x65, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x24, 0xa0, 0x00, 0x00, 0x0f, 0x84, 0x00, 0x00, 0xb6, 0xcf,
|
||||
0x63, 0x75, 0x72, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
|
||||
0x00, 0x00, 0x00, 0x05, 0x00, 0x0a, 0x00, 0x0f, 0x00, 0x14, 0x00, 0x19,
|
||||
0x00, 0x1e, 0x00, 0x23, 0x00, 0x28, 0x00, 0x2d, 0x00, 0x32, 0x00, 0x37,
|
||||
0x00, 0x3b, 0x00, 0x40, 0x00, 0x45, 0x00, 0x4a, 0x00, 0x4f, 0x00, 0x54,
|
||||
0x00, 0x59, 0x00, 0x5e, 0x00, 0x63, 0x00, 0x68, 0x00, 0x6d, 0x00, 0x72,
|
||||
0x00, 0x77, 0x00, 0x7c, 0x00, 0x81, 0x00, 0x86, 0x00, 0x8b, 0x00, 0x90,
|
||||
0x00, 0x95, 0x00, 0x9a, 0x00, 0x9f, 0x00, 0xa4, 0x00, 0xa9, 0x00, 0xae,
|
||||
0x00, 0xb2, 0x00, 0xb7, 0x00, 0xbc, 0x00, 0xc1, 0x00, 0xc6, 0x00, 0xcb,
|
||||
0x00, 0xd0, 0x00, 0xd5, 0x00, 0xdb, 0x00, 0xe0, 0x00, 0xe5, 0x00, 0xeb,
|
||||
0x00, 0xf0, 0x00, 0xf6, 0x00, 0xfb, 0x01, 0x01, 0x01, 0x07, 0x01, 0x0d,
|
||||
0x01, 0x13, 0x01, 0x19, 0x01, 0x1f, 0x01, 0x25, 0x01, 0x2b, 0x01, 0x32,
|
||||
0x01, 0x38, 0x01, 0x3e, 0x01, 0x45, 0x01, 0x4c, 0x01, 0x52, 0x01, 0x59,
|
||||
0x01, 0x60, 0x01, 0x67, 0x01, 0x6e, 0x01, 0x75, 0x01, 0x7c, 0x01, 0x83,
|
||||
0x01, 0x8b, 0x01, 0x92, 0x01, 0x9a, 0x01, 0xa1, 0x01, 0xa9, 0x01, 0xb1,
|
||||
0x01, 0xb9, 0x01, 0xc1, 0x01, 0xc9, 0x01, 0xd1, 0x01, 0xd9, 0x01, 0xe1,
|
||||
0x01, 0xe9, 0x01, 0xf2, 0x01, 0xfa, 0x02, 0x03, 0x02, 0x0c, 0x02, 0x14,
|
||||
0x02, 0x1d, 0x02, 0x26, 0x02, 0x2f, 0x02, 0x38, 0x02, 0x41, 0x02, 0x4b,
|
||||
0x02, 0x54, 0x02, 0x5d, 0x02, 0x67, 0x02, 0x71, 0x02, 0x7a, 0x02, 0x84,
|
||||
0x02, 0x8e, 0x02, 0x98, 0x02, 0xa2, 0x02, 0xac, 0x02, 0xb6, 0x02, 0xc1,
|
||||
0x02, 0xcb, 0x02, 0xd5, 0x02, 0xe0, 0x02, 0xeb, 0x02, 0xf5, 0x03, 0x00,
|
||||
0x03, 0x0b, 0x03, 0x16, 0x03, 0x21, 0x03, 0x2d, 0x03, 0x38, 0x03, 0x43,
|
||||
0x03, 0x4f, 0x03, 0x5a, 0x03, 0x66, 0x03, 0x72, 0x03, 0x7e, 0x03, 0x8a,
|
||||
0x03, 0x96, 0x03, 0xa2, 0x03, 0xae, 0x03, 0xba, 0x03, 0xc7, 0x03, 0xd3,
|
||||
0x03, 0xe0, 0x03, 0xec, 0x03, 0xf9, 0x04, 0x06, 0x04, 0x13, 0x04, 0x20,
|
||||
0x04, 0x2d, 0x04, 0x3b, 0x04, 0x48, 0x04, 0x55, 0x04, 0x63, 0x04, 0x71,
|
||||
0x04, 0x7e, 0x04, 0x8c, 0x04, 0x9a, 0x04, 0xa8, 0x04, 0xb6, 0x04, 0xc4,
|
||||
0x04, 0xd3, 0x04, 0xe1, 0x04, 0xf0, 0x04, 0xfe, 0x05, 0x0d, 0x05, 0x1c,
|
||||
0x05, 0x2b, 0x05, 0x3a, 0x05, 0x49, 0x05, 0x58, 0x05, 0x67, 0x05, 0x77,
|
||||
0x05, 0x86, 0x05, 0x96, 0x05, 0xa6, 0x05, 0xb5, 0x05, 0xc5, 0x05, 0xd5,
|
||||
0x05, 0xe5, 0x05, 0xf6, 0x06, 0x06, 0x06, 0x16, 0x06, 0x27, 0x06, 0x37,
|
||||
0x06, 0x48, 0x06, 0x59, 0x06, 0x6a, 0x06, 0x7b, 0x06, 0x8c, 0x06, 0x9d,
|
||||
0x06, 0xaf, 0x06, 0xc0, 0x06, 0xd1, 0x06, 0xe3, 0x06, 0xf5, 0x07, 0x07,
|
||||
0x07, 0x19, 0x07, 0x2b, 0x07, 0x3d, 0x07, 0x4f, 0x07, 0x61, 0x07, 0x74,
|
||||
0x07, 0x86, 0x07, 0x99, 0x07, 0xac, 0x07, 0xbf, 0x07, 0xd2, 0x07, 0xe5,
|
||||
0x07, 0xf8, 0x08, 0x0b, 0x08, 0x1f, 0x08, 0x32, 0x08, 0x46, 0x08, 0x5a,
|
||||
0x08, 0x6e, 0x08, 0x82, 0x08, 0x96, 0x08, 0xaa, 0x08, 0xbe, 0x08, 0xd2,
|
||||
0x08, 0xe7, 0x08, 0xfb, 0x09, 0x10, 0x09, 0x25, 0x09, 0x3a, 0x09, 0x4f,
|
||||
0x09, 0x64, 0x09, 0x79, 0x09, 0x8f, 0x09, 0xa4, 0x09, 0xba, 0x09, 0xcf,
|
||||
0x09, 0xe5, 0x09, 0xfb, 0x0a, 0x11, 0x0a, 0x27, 0x0a, 0x3d, 0x0a, 0x54,
|
||||
0x0a, 0x6a, 0x0a, 0x81, 0x0a, 0x98, 0x0a, 0xae, 0x0a, 0xc5, 0x0a, 0xdc,
|
||||
0x0a, 0xf3, 0x0b, 0x0b, 0x0b, 0x22, 0x0b, 0x39, 0x0b, 0x51, 0x0b, 0x69,
|
||||
0x0b, 0x80, 0x0b, 0x98, 0x0b, 0xb0, 0x0b, 0xc8, 0x0b, 0xe1, 0x0b, 0xf9,
|
||||
0x0c, 0x12, 0x0c, 0x2a, 0x0c, 0x43, 0x0c, 0x5c, 0x0c, 0x75, 0x0c, 0x8e,
|
||||
0x0c, 0xa7, 0x0c, 0xc0, 0x0c, 0xd9, 0x0c, 0xf3, 0x0d, 0x0d, 0x0d, 0x26,
|
||||
0x0d, 0x40, 0x0d, 0x5a, 0x0d, 0x74, 0x0d, 0x8e, 0x0d, 0xa9, 0x0d, 0xc3,
|
||||
0x0d, 0xde, 0x0d, 0xf8, 0x0e, 0x13, 0x0e, 0x2e, 0x0e, 0x49, 0x0e, 0x64,
|
||||
0x0e, 0x7f, 0x0e, 0x9b, 0x0e, 0xb6, 0x0e, 0xd2, 0x0e, 0xee, 0x0f, 0x09,
|
||||
0x0f, 0x25, 0x0f, 0x41, 0x0f, 0x5e, 0x0f, 0x7a, 0x0f, 0x96, 0x0f, 0xb3,
|
||||
0x0f, 0xcf, 0x0f, 0xec, 0x10, 0x09, 0x10, 0x26, 0x10, 0x43, 0x10, 0x61,
|
||||
0x10, 0x7e, 0x10, 0x9b, 0x10, 0xb9, 0x10, 0xd7, 0x10, 0xf5, 0x11, 0x13,
|
||||
0x11, 0x31, 0x11, 0x4f, 0x11, 0x6d, 0x11, 0x8c, 0x11, 0xaa, 0x11, 0xc9,
|
||||
0x11, 0xe8, 0x12, 0x07, 0x12, 0x26, 0x12, 0x45, 0x12, 0x64, 0x12, 0x84,
|
||||
0x12, 0xa3, 0x12, 0xc3, 0x12, 0xe3, 0x13, 0x03, 0x13, 0x23, 0x13, 0x43,
|
||||
0x13, 0x63, 0x13, 0x83, 0x13, 0xa4, 0x13, 0xc5, 0x13, 0xe5, 0x14, 0x06,
|
||||
0x14, 0x27, 0x14, 0x49, 0x14, 0x6a, 0x14, 0x8b, 0x14, 0xad, 0x14, 0xce,
|
||||
0x14, 0xf0, 0x15, 0x12, 0x15, 0x34, 0x15, 0x56, 0x15, 0x78, 0x15, 0x9b,
|
||||
0x15, 0xbd, 0x15, 0xe0, 0x16, 0x03, 0x16, 0x26, 0x16, 0x49, 0x16, 0x6c,
|
||||
0x16, 0x8f, 0x16, 0xb2, 0x16, 0xd6, 0x16, 0xfa, 0x17, 0x1d, 0x17, 0x41,
|
||||
0x17, 0x65, 0x17, 0x89, 0x17, 0xae, 0x17, 0xd2, 0x17, 0xf7, 0x18, 0x1b,
|
||||
0x18, 0x40, 0x18, 0x65, 0x18, 0x8a, 0x18, 0xaf, 0x18, 0xd5, 0x18, 0xfa,
|
||||
0x19, 0x20, 0x19, 0x45, 0x19, 0x6b, 0x19, 0x91, 0x19, 0xb7, 0x19, 0xdd,
|
||||
0x1a, 0x04, 0x1a, 0x2a, 0x1a, 0x51, 0x1a, 0x77, 0x1a, 0x9e, 0x1a, 0xc5,
|
||||
0x1a, 0xec, 0x1b, 0x14, 0x1b, 0x3b, 0x1b, 0x63, 0x1b, 0x8a, 0x1b, 0xb2,
|
||||
0x1b, 0xda, 0x1c, 0x02, 0x1c, 0x2a, 0x1c, 0x52, 0x1c, 0x7b, 0x1c, 0xa3,
|
||||
0x1c, 0xcc, 0x1c, 0xf5, 0x1d, 0x1e, 0x1d, 0x47, 0x1d, 0x70, 0x1d, 0x99,
|
||||
0x1d, 0xc3, 0x1d, 0xec, 0x1e, 0x16, 0x1e, 0x40, 0x1e, 0x6a, 0x1e, 0x94,
|
||||
0x1e, 0xbe, 0x1e, 0xe9, 0x1f, 0x13, 0x1f, 0x3e, 0x1f, 0x69, 0x1f, 0x94,
|
||||
0x1f, 0xbf, 0x1f, 0xea, 0x20, 0x15, 0x20, 0x41, 0x20, 0x6c, 0x20, 0x98,
|
||||
0x20, 0xc4, 0x20, 0xf0, 0x21, 0x1c, 0x21, 0x48, 0x21, 0x75, 0x21, 0xa1,
|
||||
0x21, 0xce, 0x21, 0xfb, 0x22, 0x27, 0x22, 0x55, 0x22, 0x82, 0x22, 0xaf,
|
||||
0x22, 0xdd, 0x23, 0x0a, 0x23, 0x38, 0x23, 0x66, 0x23, 0x94, 0x23, 0xc2,
|
||||
0x23, 0xf0, 0x24, 0x1f, 0x24, 0x4d, 0x24, 0x7c, 0x24, 0xab, 0x24, 0xda,
|
||||
0x25, 0x09, 0x25, 0x38, 0x25, 0x68, 0x25, 0x97, 0x25, 0xc7, 0x25, 0xf7,
|
||||
0x26, 0x27, 0x26, 0x57, 0x26, 0x87, 0x26, 0xb7, 0x26, 0xe8, 0x27, 0x18,
|
||||
0x27, 0x49, 0x27, 0x7a, 0x27, 0xab, 0x27, 0xdc, 0x28, 0x0d, 0x28, 0x3f,
|
||||
0x28, 0x71, 0x28, 0xa2, 0x28, 0xd4, 0x29, 0x06, 0x29, 0x38, 0x29, 0x6b,
|
||||
0x29, 0x9d, 0x29, 0xd0, 0x2a, 0x02, 0x2a, 0x35, 0x2a, 0x68, 0x2a, 0x9b,
|
||||
0x2a, 0xcf, 0x2b, 0x02, 0x2b, 0x36, 0x2b, 0x69, 0x2b, 0x9d, 0x2b, 0xd1,
|
||||
0x2c, 0x05, 0x2c, 0x39, 0x2c, 0x6e, 0x2c, 0xa2, 0x2c, 0xd7, 0x2d, 0x0c,
|
||||
0x2d, 0x41, 0x2d, 0x76, 0x2d, 0xab, 0x2d, 0xe1, 0x2e, 0x16, 0x2e, 0x4c,
|
||||
0x2e, 0x82, 0x2e, 0xb7, 0x2e, 0xee, 0x2f, 0x24, 0x2f, 0x5a, 0x2f, 0x91,
|
||||
0x2f, 0xc7, 0x2f, 0xfe, 0x30, 0x35, 0x30, 0x6c, 0x30, 0xa4, 0x30, 0xdb,
|
||||
0x31, 0x12, 0x31, 0x4a, 0x31, 0x82, 0x31, 0xba, 0x31, 0xf2, 0x32, 0x2a,
|
||||
0x32, 0x63, 0x32, 0x9b, 0x32, 0xd4, 0x33, 0x0d, 0x33, 0x46, 0x33, 0x7f,
|
||||
0x33, 0xb8, 0x33, 0xf1, 0x34, 0x2b, 0x34, 0x65, 0x34, 0x9e, 0x34, 0xd8,
|
||||
0x35, 0x13, 0x35, 0x4d, 0x35, 0x87, 0x35, 0xc2, 0x35, 0xfd, 0x36, 0x37,
|
||||
0x36, 0x72, 0x36, 0xae, 0x36, 0xe9, 0x37, 0x24, 0x37, 0x60, 0x37, 0x9c,
|
||||
0x37, 0xd7, 0x38, 0x14, 0x38, 0x50, 0x38, 0x8c, 0x38, 0xc8, 0x39, 0x05,
|
||||
0x39, 0x42, 0x39, 0x7f, 0x39, 0xbc, 0x39, 0xf9, 0x3a, 0x36, 0x3a, 0x74,
|
||||
0x3a, 0xb2, 0x3a, 0xef, 0x3b, 0x2d, 0x3b, 0x6b, 0x3b, 0xaa, 0x3b, 0xe8,
|
||||
0x3c, 0x27, 0x3c, 0x65, 0x3c, 0xa4, 0x3c, 0xe3, 0x3d, 0x22, 0x3d, 0x61,
|
||||
0x3d, 0xa1, 0x3d, 0xe0, 0x3e, 0x20, 0x3e, 0x60, 0x3e, 0xa0, 0x3e, 0xe0,
|
||||
0x3f, 0x21, 0x3f, 0x61, 0x3f, 0xa2, 0x3f, 0xe2, 0x40, 0x23, 0x40, 0x64,
|
||||
0x40, 0xa6, 0x40, 0xe7, 0x41, 0x29, 0x41, 0x6a, 0x41, 0xac, 0x41, 0xee,
|
||||
0x42, 0x30, 0x42, 0x72, 0x42, 0xb5, 0x42, 0xf7, 0x43, 0x3a, 0x43, 0x7d,
|
||||
0x43, 0xc0, 0x44, 0x03, 0x44, 0x47, 0x44, 0x8a, 0x44, 0xce, 0x45, 0x12,
|
||||
0x45, 0x55, 0x45, 0x9a, 0x45, 0xde, 0x46, 0x22, 0x46, 0x67, 0x46, 0xab,
|
||||
0x46, 0xf0, 0x47, 0x35, 0x47, 0x7b, 0x47, 0xc0, 0x48, 0x05, 0x48, 0x4b,
|
||||
0x48, 0x91, 0x48, 0xd7, 0x49, 0x1d, 0x49, 0x63, 0x49, 0xa9, 0x49, 0xf0,
|
||||
0x4a, 0x37, 0x4a, 0x7d, 0x4a, 0xc4, 0x4b, 0x0c, 0x4b, 0x53, 0x4b, 0x9a,
|
||||
0x4b, 0xe2, 0x4c, 0x2a, 0x4c, 0x72, 0x4c, 0xba, 0x4d, 0x02, 0x4d, 0x4a,
|
||||
0x4d, 0x93, 0x4d, 0xdc, 0x4e, 0x25, 0x4e, 0x6e, 0x4e, 0xb7, 0x4f, 0x00,
|
||||
0x4f, 0x49, 0x4f, 0x93, 0x4f, 0xdd, 0x50, 0x27, 0x50, 0x71, 0x50, 0xbb,
|
||||
0x51, 0x06, 0x51, 0x50, 0x51, 0x9b, 0x51, 0xe6, 0x52, 0x31, 0x52, 0x7c,
|
||||
0x52, 0xc7, 0x53, 0x13, 0x53, 0x5f, 0x53, 0xaa, 0x53, 0xf6, 0x54, 0x42,
|
||||
0x54, 0x8f, 0x54, 0xdb, 0x55, 0x28, 0x55, 0x75, 0x55, 0xc2, 0x56, 0x0f,
|
||||
0x56, 0x5c, 0x56, 0xa9, 0x56, 0xf7, 0x57, 0x44, 0x57, 0x92, 0x57, 0xe0,
|
||||
0x58, 0x2f, 0x58, 0x7d, 0x58, 0xcb, 0x59, 0x1a, 0x59, 0x69, 0x59, 0xb8,
|
||||
0x5a, 0x07, 0x5a, 0x56, 0x5a, 0xa6, 0x5a, 0xf5, 0x5b, 0x45, 0x5b, 0x95,
|
||||
0x5b, 0xe5, 0x5c, 0x35, 0x5c, 0x86, 0x5c, 0xd6, 0x5d, 0x27, 0x5d, 0x78,
|
||||
0x5d, 0xc9, 0x5e, 0x1a, 0x5e, 0x6c, 0x5e, 0xbd, 0x5f, 0x0f, 0x5f, 0x61,
|
||||
0x5f, 0xb3, 0x60, 0x05, 0x60, 0x57, 0x60, 0xaa, 0x60, 0xfc, 0x61, 0x4f,
|
||||
0x61, 0xa2, 0x61, 0xf5, 0x62, 0x49, 0x62, 0x9c, 0x62, 0xf0, 0x63, 0x43,
|
||||
0x63, 0x97, 0x63, 0xeb, 0x64, 0x40, 0x64, 0x94, 0x64, 0xe9, 0x65, 0x3d,
|
||||
0x65, 0x92, 0x65, 0xe7, 0x66, 0x3d, 0x66, 0x92, 0x66, 0xe8, 0x67, 0x3d,
|
||||
0x67, 0x93, 0x67, 0xe9, 0x68, 0x3f, 0x68, 0x96, 0x68, 0xec, 0x69, 0x43,
|
||||
0x69, 0x9a, 0x69, 0xf1, 0x6a, 0x48, 0x6a, 0x9f, 0x6a, 0xf7, 0x6b, 0x4f,
|
||||
0x6b, 0xa7, 0x6b, 0xff, 0x6c, 0x57, 0x6c, 0xaf, 0x6d, 0x08, 0x6d, 0x60,
|
||||
0x6d, 0xb9, 0x6e, 0x12, 0x6e, 0x6b, 0x6e, 0xc4, 0x6f, 0x1e, 0x6f, 0x78,
|
||||
0x6f, 0xd1, 0x70, 0x2b, 0x70, 0x86, 0x70, 0xe0, 0x71, 0x3a, 0x71, 0x95,
|
||||
0x71, 0xf0, 0x72, 0x4b, 0x72, 0xa6, 0x73, 0x01, 0x73, 0x5d, 0x73, 0xb8,
|
||||
0x74, 0x14, 0x74, 0x70, 0x74, 0xcc, 0x75, 0x28, 0x75, 0x85, 0x75, 0xe1,
|
||||
0x76, 0x3e, 0x76, 0x9b, 0x76, 0xf8, 0x77, 0x56, 0x77, 0xb3, 0x78, 0x11,
|
||||
0x78, 0x6e, 0x78, 0xcc, 0x79, 0x2a, 0x79, 0x89, 0x79, 0xe7, 0x7a, 0x46,
|
||||
0x7a, 0xa5, 0x7b, 0x04, 0x7b, 0x63, 0x7b, 0xc2, 0x7c, 0x21, 0x7c, 0x81,
|
||||
0x7c, 0xe1, 0x7d, 0x41, 0x7d, 0xa1, 0x7e, 0x01, 0x7e, 0x62, 0x7e, 0xc2,
|
||||
0x7f, 0x23, 0x7f, 0x84, 0x7f, 0xe5, 0x80, 0x47, 0x80, 0xa8, 0x81, 0x0a,
|
||||
0x81, 0x6b, 0x81, 0xcd, 0x82, 0x30, 0x82, 0x92, 0x82, 0xf4, 0x83, 0x57,
|
||||
0x83, 0xba, 0x84, 0x1d, 0x84, 0x80, 0x84, 0xe3, 0x85, 0x47, 0x85, 0xab,
|
||||
0x86, 0x0e, 0x86, 0x72, 0x86, 0xd7, 0x87, 0x3b, 0x87, 0x9f, 0x88, 0x04,
|
||||
0x88, 0x69, 0x88, 0xce, 0x89, 0x33, 0x89, 0x99, 0x89, 0xfe, 0x8a, 0x64,
|
||||
0x8a, 0xca, 0x8b, 0x30, 0x8b, 0x96, 0x8b, 0xfc, 0x8c, 0x63, 0x8c, 0xca,
|
||||
0x8d, 0x31, 0x8d, 0x98, 0x8d, 0xff, 0x8e, 0x66, 0x8e, 0xce, 0x8f, 0x36,
|
||||
0x8f, 0x9e, 0x90, 0x06, 0x90, 0x6e, 0x90, 0xd6, 0x91, 0x3f, 0x91, 0xa8,
|
||||
0x92, 0x11, 0x92, 0x7a, 0x92, 0xe3, 0x93, 0x4d, 0x93, 0xb6, 0x94, 0x20,
|
||||
0x94, 0x8a, 0x94, 0xf4, 0x95, 0x5f, 0x95, 0xc9, 0x96, 0x34, 0x96, 0x9f,
|
||||
0x97, 0x0a, 0x97, 0x75, 0x97, 0xe0, 0x98, 0x4c, 0x98, 0xb8, 0x99, 0x24,
|
||||
0x99, 0x90, 0x99, 0xfc, 0x9a, 0x68, 0x9a, 0xd5, 0x9b, 0x42, 0x9b, 0xaf,
|
||||
0x9c, 0x1c, 0x9c, 0x89, 0x9c, 0xf7, 0x9d, 0x64, 0x9d, 0xd2, 0x9e, 0x40,
|
||||
0x9e, 0xae, 0x9f, 0x1d, 0x9f, 0x8b, 0x9f, 0xfa, 0xa0, 0x69, 0xa0, 0xd8,
|
||||
0xa1, 0x47, 0xa1, 0xb6, 0xa2, 0x26, 0xa2, 0x96, 0xa3, 0x06, 0xa3, 0x76,
|
||||
0xa3, 0xe6, 0xa4, 0x56, 0xa4, 0xc7, 0xa5, 0x38, 0xa5, 0xa9, 0xa6, 0x1a,
|
||||
0xa6, 0x8b, 0xa6, 0xfd, 0xa7, 0x6e, 0xa7, 0xe0, 0xa8, 0x52, 0xa8, 0xc4,
|
||||
0xa9, 0x37, 0xa9, 0xa9, 0xaa, 0x1c, 0xaa, 0x8f, 0xab, 0x02, 0xab, 0x75,
|
||||
0xab, 0xe9, 0xac, 0x5c, 0xac, 0xd0, 0xad, 0x44, 0xad, 0xb8, 0xae, 0x2d,
|
||||
0xae, 0xa1, 0xaf, 0x16, 0xaf, 0x8b, 0xb0, 0x00, 0xb0, 0x75, 0xb0, 0xea,
|
||||
0xb1, 0x60, 0xb1, 0xd6, 0xb2, 0x4b, 0xb2, 0xc2, 0xb3, 0x38, 0xb3, 0xae,
|
||||
0xb4, 0x25, 0xb4, 0x9c, 0xb5, 0x13, 0xb5, 0x8a, 0xb6, 0x01, 0xb6, 0x79,
|
||||
0xb6, 0xf0, 0xb7, 0x68, 0xb7, 0xe0, 0xb8, 0x59, 0xb8, 0xd1, 0xb9, 0x4a,
|
||||
0xb9, 0xc2, 0xba, 0x3b, 0xba, 0xb5, 0xbb, 0x2e, 0xbb, 0xa7, 0xbc, 0x21,
|
||||
0xbc, 0x9b, 0xbd, 0x15, 0xbd, 0x8f, 0xbe, 0x0a, 0xbe, 0x84, 0xbe, 0xff,
|
||||
0xbf, 0x7a, 0xbf, 0xf5, 0xc0, 0x70, 0xc0, 0xec, 0xc1, 0x67, 0xc1, 0xe3,
|
||||
0xc2, 0x5f, 0xc2, 0xdb, 0xc3, 0x58, 0xc3, 0xd4, 0xc4, 0x51, 0xc4, 0xce,
|
||||
0xc5, 0x4b, 0xc5, 0xc8, 0xc6, 0x46, 0xc6, 0xc3, 0xc7, 0x41, 0xc7, 0xbf,
|
||||
0xc8, 0x3d, 0xc8, 0xbc, 0xc9, 0x3a, 0xc9, 0xb9, 0xca, 0x38, 0xca, 0xb7,
|
||||
0xcb, 0x36, 0xcb, 0xb6, 0xcc, 0x35, 0xcc, 0xb5, 0xcd, 0x35, 0xcd, 0xb5,
|
||||
0xce, 0x36, 0xce, 0xb6, 0xcf, 0x37, 0xcf, 0xb8, 0xd0, 0x39, 0xd0, 0xba,
|
||||
0xd1, 0x3c, 0xd1, 0xbe, 0xd2, 0x3f, 0xd2, 0xc1, 0xd3, 0x44, 0xd3, 0xc6,
|
||||
0xd4, 0x49, 0xd4, 0xcb, 0xd5, 0x4e, 0xd5, 0xd1, 0xd6, 0x55, 0xd6, 0xd8,
|
||||
0xd7, 0x5c, 0xd7, 0xe0, 0xd8, 0x64, 0xd8, 0xe8, 0xd9, 0x6c, 0xd9, 0xf1,
|
||||
0xda, 0x76, 0xda, 0xfb, 0xdb, 0x80, 0xdc, 0x05, 0xdc, 0x8a, 0xdd, 0x10,
|
||||
0xdd, 0x96, 0xde, 0x1c, 0xde, 0xa2, 0xdf, 0x29, 0xdf, 0xaf, 0xe0, 0x36,
|
||||
0xe0, 0xbd, 0xe1, 0x44, 0xe1, 0xcc, 0xe2, 0x53, 0xe2, 0xdb, 0xe3, 0x63,
|
||||
0xe3, 0xeb, 0xe4, 0x73, 0xe4, 0xfc, 0xe5, 0x84, 0xe6, 0x0d, 0xe6, 0x96,
|
||||
0xe7, 0x1f, 0xe7, 0xa9, 0xe8, 0x32, 0xe8, 0xbc, 0xe9, 0x46, 0xe9, 0xd0,
|
||||
0xea, 0x5b, 0xea, 0xe5, 0xeb, 0x70, 0xeb, 0xfb, 0xec, 0x86, 0xed, 0x11,
|
||||
0xed, 0x9c, 0xee, 0x28, 0xee, 0xb4, 0xef, 0x40, 0xef, 0xcc, 0xf0, 0x58,
|
||||
0xf0, 0xe5, 0xf1, 0x72, 0xf1, 0xff, 0xf2, 0x8c, 0xf3, 0x19, 0xf3, 0xa7,
|
||||
0xf4, 0x34, 0xf4, 0xc2, 0xf5, 0x50, 0xf5, 0xde, 0xf6, 0x6d, 0xf6, 0xfb,
|
||||
0xf7, 0x8a, 0xf8, 0x19, 0xf8, 0xa8, 0xf9, 0x38, 0xf9, 0xc7, 0xfa, 0x57,
|
||||
0xfa, 0xe7, 0xfb, 0x77, 0xfc, 0x07, 0xfc, 0x98, 0xfd, 0x29, 0xfd, 0xba,
|
||||
0xfe, 0x4b, 0xfe, 0xdc, 0xff, 0x6d, 0xff, 0xff, 0x64, 0x65, 0x73, 0x63,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x49, 0x45, 0x43, 0x20,
|
||||
0x36, 0x31, 0x39, 0x36, 0x36, 0x2d, 0x32, 0x2d, 0x31, 0x20, 0x44, 0x65,
|
||||
0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x52, 0x47, 0x42, 0x20, 0x43, 0x6f,
|
||||
0x6c, 0x6f, 0x75, 0x72, 0x20, 0x53, 0x70, 0x61, 0x63, 0x65, 0x20, 0x2d,
|
||||
0x20, 0x73, 0x52, 0x47, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x99,
|
||||
0x00, 0x00, 0xb7, 0x85, 0x00, 0x00, 0x18, 0xda, 0x58, 0x59, 0x5a, 0x20,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x6d, 0x65, 0x61, 0x73, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x02, 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x03, 0x16, 0x00, 0x00, 0x03, 0x33, 0x00, 0x00, 0x02, 0xa4,
|
||||
0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6f, 0xa2,
|
||||
0x00, 0x00, 0x38, 0xf5, 0x00, 0x00, 0x03, 0x90, 0x73, 0x69, 0x67, 0x20,
|
||||
0x00, 0x00, 0x00, 0x00, 0x43, 0x52, 0x54, 0x20, 0x64, 0x65, 0x73, 0x63,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x52, 0x65, 0x66, 0x65,
|
||||
0x72, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x56, 0x69, 0x65, 0x77, 0x69, 0x6e,
|
||||
0x67, 0x20, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20,
|
||||
0x69, 0x6e, 0x20, 0x49, 0x45, 0x43, 0x20, 0x36, 0x31, 0x39, 0x36, 0x36,
|
||||
0x2d, 0x32, 0x2d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xd6,
|
||||
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d, 0x74, 0x65, 0x78, 0x74,
|
||||
0x00, 0x00, 0x00, 0x00, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68,
|
||||
0x74, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x61, 0x6c, 0x20, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x43, 0x6f,
|
||||
0x6e, 0x73, 0x6f, 0x72, 0x74, 0x69, 0x75, 0x6d, 0x2c, 0x20, 0x32, 0x30,
|
||||
0x30, 0x39, 0x00, 0x00, 0x73, 0x66, 0x33, 0x32, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01, 0x0c, 0x44, 0x00, 0x00, 0x05, 0xdf, 0xff, 0xff, 0xf3, 0x26,
|
||||
0x00, 0x00, 0x07, 0x94, 0x00, 0x00, 0xfd, 0x8f, 0xff, 0xff, 0xfb, 0xa1,
|
||||
0xff, 0xff, 0xfd, 0xa2, 0x00, 0x00, 0x03, 0xdb, 0x00, 0x00, 0xc0, 0x75,
|
||||
}
|
||||
|
||||
genericGrayGamma22ICCProfile = []byte{
|
||||
0x00, 0x00, 0x0e, 0x04, 0x61, 0x70, 0x70, 0x6c, 0x02, 0x00, 0x00, 0x00,
|
||||
0x6d, 0x6e, 0x74, 0x72, 0x47, 0x52, 0x41, 0x59, 0x58, 0x59, 0x5a, 0x20,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x61, 0x63, 0x73, 0x70, 0x41, 0x50, 0x50, 0x4c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x6e, 0x6f, 0x6e, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xd6,
|
||||
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d, 0x61, 0x70, 0x70, 0x6c,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
|
||||
0x6b, 0x54, 0x52, 0x43, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x08, 0x0c,
|
||||
0x77, 0x74, 0x70, 0x74, 0x00, 0x00, 0x08, 0xcc, 0x00, 0x00, 0x00, 0x14,
|
||||
0x63, 0x70, 0x72, 0x74, 0x00, 0x00, 0x08, 0xe0, 0x00, 0x00, 0x00, 0x23,
|
||||
0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 0x00, 0x79,
|
||||
0x64, 0x73, 0x63, 0x6d, 0x00, 0x00, 0x09, 0x80, 0x00, 0x00, 0x04, 0x82,
|
||||
0x63, 0x75, 0x72, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
|
||||
0x00, 0x00, 0x00, 0x05, 0x00, 0x0a, 0x00, 0x0f, 0x00, 0x14, 0x00, 0x19,
|
||||
0x00, 0x1e, 0x00, 0x23, 0x00, 0x28, 0x00, 0x2d, 0x00, 0x32, 0x00, 0x37,
|
||||
0x00, 0x3b, 0x00, 0x40, 0x00, 0x45, 0x00, 0x4a, 0x00, 0x4f, 0x00, 0x54,
|
||||
0x00, 0x59, 0x00, 0x5e, 0x00, 0x63, 0x00, 0x68, 0x00, 0x6d, 0x00, 0x72,
|
||||
0x00, 0x77, 0x00, 0x7c, 0x00, 0x81, 0x00, 0x86, 0x00, 0x8b, 0x00, 0x90,
|
||||
0x00, 0x95, 0x00, 0x9a, 0x00, 0x9f, 0x00, 0xa4, 0x00, 0xa9, 0x00, 0xae,
|
||||
0x00, 0xb2, 0x00, 0xb7, 0x00, 0xbc, 0x00, 0xc1, 0x00, 0xc6, 0x00, 0xcb,
|
||||
0x00, 0xd0, 0x00, 0xd5, 0x00, 0xdb, 0x00, 0xe0, 0x00, 0xe5, 0x00, 0xeb,
|
||||
0x00, 0xf0, 0x00, 0xf6, 0x00, 0xfb, 0x01, 0x01, 0x01, 0x07, 0x01, 0x0d,
|
||||
0x01, 0x13, 0x01, 0x19, 0x01, 0x1f, 0x01, 0x25, 0x01, 0x2b, 0x01, 0x32,
|
||||
0x01, 0x38, 0x01, 0x3e, 0x01, 0x45, 0x01, 0x4c, 0x01, 0x52, 0x01, 0x59,
|
||||
0x01, 0x60, 0x01, 0x67, 0x01, 0x6e, 0x01, 0x75, 0x01, 0x7c, 0x01, 0x83,
|
||||
0x01, 0x8b, 0x01, 0x92, 0x01, 0x9a, 0x01, 0xa1, 0x01, 0xa9, 0x01, 0xb1,
|
||||
0x01, 0xb9, 0x01, 0xc1, 0x01, 0xc9, 0x01, 0xd1, 0x01, 0xd9, 0x01, 0xe1,
|
||||
0x01, 0xe9, 0x01, 0xf2, 0x01, 0xfa, 0x02, 0x03, 0x02, 0x0c, 0x02, 0x14,
|
||||
0x02, 0x1d, 0x02, 0x26, 0x02, 0x2f, 0x02, 0x38, 0x02, 0x41, 0x02, 0x4b,
|
||||
0x02, 0x54, 0x02, 0x5d, 0x02, 0x67, 0x02, 0x71, 0x02, 0x7a, 0x02, 0x84,
|
||||
0x02, 0x8e, 0x02, 0x98, 0x02, 0xa2, 0x02, 0xac, 0x02, 0xb6, 0x02, 0xc1,
|
||||
0x02, 0xcb, 0x02, 0xd5, 0x02, 0xe0, 0x02, 0xeb, 0x02, 0xf5, 0x03, 0x00,
|
||||
0x03, 0x0b, 0x03, 0x16, 0x03, 0x21, 0x03, 0x2d, 0x03, 0x38, 0x03, 0x43,
|
||||
0x03, 0x4f, 0x03, 0x5a, 0x03, 0x66, 0x03, 0x72, 0x03, 0x7e, 0x03, 0x8a,
|
||||
0x03, 0x96, 0x03, 0xa2, 0x03, 0xae, 0x03, 0xba, 0x03, 0xc7, 0x03, 0xd3,
|
||||
0x03, 0xe0, 0x03, 0xec, 0x03, 0xf9, 0x04, 0x06, 0x04, 0x13, 0x04, 0x20,
|
||||
0x04, 0x2d, 0x04, 0x3b, 0x04, 0x48, 0x04, 0x55, 0x04, 0x63, 0x04, 0x71,
|
||||
0x04, 0x7e, 0x04, 0x8c, 0x04, 0x9a, 0x04, 0xa8, 0x04, 0xb6, 0x04, 0xc4,
|
||||
0x04, 0xd3, 0x04, 0xe1, 0x04, 0xf0, 0x04, 0xfe, 0x05, 0x0d, 0x05, 0x1c,
|
||||
0x05, 0x2b, 0x05, 0x3a, 0x05, 0x49, 0x05, 0x58, 0x05, 0x67, 0x05, 0x77,
|
||||
0x05, 0x86, 0x05, 0x96, 0x05, 0xa6, 0x05, 0xb5, 0x05, 0xc5, 0x05, 0xd5,
|
||||
0x05, 0xe5, 0x05, 0xf6, 0x06, 0x06, 0x06, 0x16, 0x06, 0x27, 0x06, 0x37,
|
||||
0x06, 0x48, 0x06, 0x59, 0x06, 0x6a, 0x06, 0x7b, 0x06, 0x8c, 0x06, 0x9d,
|
||||
0x06, 0xaf, 0x06, 0xc0, 0x06, 0xd1, 0x06, 0xe3, 0x06, 0xf5, 0x07, 0x07,
|
||||
0x07, 0x19, 0x07, 0x2b, 0x07, 0x3d, 0x07, 0x4f, 0x07, 0x61, 0x07, 0x74,
|
||||
0x07, 0x86, 0x07, 0x99, 0x07, 0xac, 0x07, 0xbf, 0x07, 0xd2, 0x07, 0xe5,
|
||||
0x07, 0xf8, 0x08, 0x0b, 0x08, 0x1f, 0x08, 0x32, 0x08, 0x46, 0x08, 0x5a,
|
||||
0x08, 0x6e, 0x08, 0x82, 0x08, 0x96, 0x08, 0xaa, 0x08, 0xbe, 0x08, 0xd2,
|
||||
0x08, 0xe7, 0x08, 0xfb, 0x09, 0x10, 0x09, 0x25, 0x09, 0x3a, 0x09, 0x4f,
|
||||
0x09, 0x64, 0x09, 0x79, 0x09, 0x8f, 0x09, 0xa4, 0x09, 0xba, 0x09, 0xcf,
|
||||
0x09, 0xe5, 0x09, 0xfb, 0x0a, 0x11, 0x0a, 0x27, 0x0a, 0x3d, 0x0a, 0x54,
|
||||
0x0a, 0x6a, 0x0a, 0x81, 0x0a, 0x98, 0x0a, 0xae, 0x0a, 0xc5, 0x0a, 0xdc,
|
||||
0x0a, 0xf3, 0x0b, 0x0b, 0x0b, 0x22, 0x0b, 0x39, 0x0b, 0x51, 0x0b, 0x69,
|
||||
0x0b, 0x80, 0x0b, 0x98, 0x0b, 0xb0, 0x0b, 0xc8, 0x0b, 0xe1, 0x0b, 0xf9,
|
||||
0x0c, 0x12, 0x0c, 0x2a, 0x0c, 0x43, 0x0c, 0x5c, 0x0c, 0x75, 0x0c, 0x8e,
|
||||
0x0c, 0xa7, 0x0c, 0xc0, 0x0c, 0xd9, 0x0c, 0xf3, 0x0d, 0x0d, 0x0d, 0x26,
|
||||
0x0d, 0x40, 0x0d, 0x5a, 0x0d, 0x74, 0x0d, 0x8e, 0x0d, 0xa9, 0x0d, 0xc3,
|
||||
0x0d, 0xde, 0x0d, 0xf8, 0x0e, 0x13, 0x0e, 0x2e, 0x0e, 0x49, 0x0e, 0x64,
|
||||
0x0e, 0x7f, 0x0e, 0x9b, 0x0e, 0xb6, 0x0e, 0xd2, 0x0e, 0xee, 0x0f, 0x09,
|
||||
0x0f, 0x25, 0x0f, 0x41, 0x0f, 0x5e, 0x0f, 0x7a, 0x0f, 0x96, 0x0f, 0xb3,
|
||||
0x0f, 0xcf, 0x0f, 0xec, 0x10, 0x09, 0x10, 0x26, 0x10, 0x43, 0x10, 0x61,
|
||||
0x10, 0x7e, 0x10, 0x9b, 0x10, 0xb9, 0x10, 0xd7, 0x10, 0xf5, 0x11, 0x13,
|
||||
0x11, 0x31, 0x11, 0x4f, 0x11, 0x6d, 0x11, 0x8c, 0x11, 0xaa, 0x11, 0xc9,
|
||||
0x11, 0xe8, 0x12, 0x07, 0x12, 0x26, 0x12, 0x45, 0x12, 0x64, 0x12, 0x84,
|
||||
0x12, 0xa3, 0x12, 0xc3, 0x12, 0xe3, 0x13, 0x03, 0x13, 0x23, 0x13, 0x43,
|
||||
0x13, 0x63, 0x13, 0x83, 0x13, 0xa4, 0x13, 0xc5, 0x13, 0xe5, 0x14, 0x06,
|
||||
0x14, 0x27, 0x14, 0x49, 0x14, 0x6a, 0x14, 0x8b, 0x14, 0xad, 0x14, 0xce,
|
||||
0x14, 0xf0, 0x15, 0x12, 0x15, 0x34, 0x15, 0x56, 0x15, 0x78, 0x15, 0x9b,
|
||||
0x15, 0xbd, 0x15, 0xe0, 0x16, 0x03, 0x16, 0x26, 0x16, 0x49, 0x16, 0x6c,
|
||||
0x16, 0x8f, 0x16, 0xb2, 0x16, 0xd6, 0x16, 0xfa, 0x17, 0x1d, 0x17, 0x41,
|
||||
0x17, 0x65, 0x17, 0x89, 0x17, 0xae, 0x17, 0xd2, 0x17, 0xf7, 0x18, 0x1b,
|
||||
0x18, 0x40, 0x18, 0x65, 0x18, 0x8a, 0x18, 0xaf, 0x18, 0xd5, 0x18, 0xfa,
|
||||
0x19, 0x20, 0x19, 0x45, 0x19, 0x6b, 0x19, 0x91, 0x19, 0xb7, 0x19, 0xdd,
|
||||
0x1a, 0x04, 0x1a, 0x2a, 0x1a, 0x51, 0x1a, 0x77, 0x1a, 0x9e, 0x1a, 0xc5,
|
||||
0x1a, 0xec, 0x1b, 0x14, 0x1b, 0x3b, 0x1b, 0x63, 0x1b, 0x8a, 0x1b, 0xb2,
|
||||
0x1b, 0xda, 0x1c, 0x02, 0x1c, 0x2a, 0x1c, 0x52, 0x1c, 0x7b, 0x1c, 0xa3,
|
||||
0x1c, 0xcc, 0x1c, 0xf5, 0x1d, 0x1e, 0x1d, 0x47, 0x1d, 0x70, 0x1d, 0x99,
|
||||
0x1d, 0xc3, 0x1d, 0xec, 0x1e, 0x16, 0x1e, 0x40, 0x1e, 0x6a, 0x1e, 0x94,
|
||||
0x1e, 0xbe, 0x1e, 0xe9, 0x1f, 0x13, 0x1f, 0x3e, 0x1f, 0x69, 0x1f, 0x94,
|
||||
0x1f, 0xbf, 0x1f, 0xea, 0x20, 0x15, 0x20, 0x41, 0x20, 0x6c, 0x20, 0x98,
|
||||
0x20, 0xc4, 0x20, 0xf0, 0x21, 0x1c, 0x21, 0x48, 0x21, 0x75, 0x21, 0xa1,
|
||||
0x21, 0xce, 0x21, 0xfb, 0x22, 0x27, 0x22, 0x55, 0x22, 0x82, 0x22, 0xaf,
|
||||
0x22, 0xdd, 0x23, 0x0a, 0x23, 0x38, 0x23, 0x66, 0x23, 0x94, 0x23, 0xc2,
|
||||
0x23, 0xf0, 0x24, 0x1f, 0x24, 0x4d, 0x24, 0x7c, 0x24, 0xab, 0x24, 0xda,
|
||||
0x25, 0x09, 0x25, 0x38, 0x25, 0x68, 0x25, 0x97, 0x25, 0xc7, 0x25, 0xf7,
|
||||
0x26, 0x27, 0x26, 0x57, 0x26, 0x87, 0x26, 0xb7, 0x26, 0xe8, 0x27, 0x18,
|
||||
0x27, 0x49, 0x27, 0x7a, 0x27, 0xab, 0x27, 0xdc, 0x28, 0x0d, 0x28, 0x3f,
|
||||
0x28, 0x71, 0x28, 0xa2, 0x28, 0xd4, 0x29, 0x06, 0x29, 0x38, 0x29, 0x6b,
|
||||
0x29, 0x9d, 0x29, 0xd0, 0x2a, 0x02, 0x2a, 0x35, 0x2a, 0x68, 0x2a, 0x9b,
|
||||
0x2a, 0xcf, 0x2b, 0x02, 0x2b, 0x36, 0x2b, 0x69, 0x2b, 0x9d, 0x2b, 0xd1,
|
||||
0x2c, 0x05, 0x2c, 0x39, 0x2c, 0x6e, 0x2c, 0xa2, 0x2c, 0xd7, 0x2d, 0x0c,
|
||||
0x2d, 0x41, 0x2d, 0x76, 0x2d, 0xab, 0x2d, 0xe1, 0x2e, 0x16, 0x2e, 0x4c,
|
||||
0x2e, 0x82, 0x2e, 0xb7, 0x2e, 0xee, 0x2f, 0x24, 0x2f, 0x5a, 0x2f, 0x91,
|
||||
0x2f, 0xc7, 0x2f, 0xfe, 0x30, 0x35, 0x30, 0x6c, 0x30, 0xa4, 0x30, 0xdb,
|
||||
0x31, 0x12, 0x31, 0x4a, 0x31, 0x82, 0x31, 0xba, 0x31, 0xf2, 0x32, 0x2a,
|
||||
0x32, 0x63, 0x32, 0x9b, 0x32, 0xd4, 0x33, 0x0d, 0x33, 0x46, 0x33, 0x7f,
|
||||
0x33, 0xb8, 0x33, 0xf1, 0x34, 0x2b, 0x34, 0x65, 0x34, 0x9e, 0x34, 0xd8,
|
||||
0x35, 0x13, 0x35, 0x4d, 0x35, 0x87, 0x35, 0xc2, 0x35, 0xfd, 0x36, 0x37,
|
||||
0x36, 0x72, 0x36, 0xae, 0x36, 0xe9, 0x37, 0x24, 0x37, 0x60, 0x37, 0x9c,
|
||||
0x37, 0xd7, 0x38, 0x14, 0x38, 0x50, 0x38, 0x8c, 0x38, 0xc8, 0x39, 0x05,
|
||||
0x39, 0x42, 0x39, 0x7f, 0x39, 0xbc, 0x39, 0xf9, 0x3a, 0x36, 0x3a, 0x74,
|
||||
0x3a, 0xb2, 0x3a, 0xef, 0x3b, 0x2d, 0x3b, 0x6b, 0x3b, 0xaa, 0x3b, 0xe8,
|
||||
0x3c, 0x27, 0x3c, 0x65, 0x3c, 0xa4, 0x3c, 0xe3, 0x3d, 0x22, 0x3d, 0x61,
|
||||
0x3d, 0xa1, 0x3d, 0xe0, 0x3e, 0x20, 0x3e, 0x60, 0x3e, 0xa0, 0x3e, 0xe0,
|
||||
0x3f, 0x21, 0x3f, 0x61, 0x3f, 0xa2, 0x3f, 0xe2, 0x40, 0x23, 0x40, 0x64,
|
||||
0x40, 0xa6, 0x40, 0xe7, 0x41, 0x29, 0x41, 0x6a, 0x41, 0xac, 0x41, 0xee,
|
||||
0x42, 0x30, 0x42, 0x72, 0x42, 0xb5, 0x42, 0xf7, 0x43, 0x3a, 0x43, 0x7d,
|
||||
0x43, 0xc0, 0x44, 0x03, 0x44, 0x47, 0x44, 0x8a, 0x44, 0xce, 0x45, 0x12,
|
||||
0x45, 0x55, 0x45, 0x9a, 0x45, 0xde, 0x46, 0x22, 0x46, 0x67, 0x46, 0xab,
|
||||
0x46, 0xf0, 0x47, 0x35, 0x47, 0x7b, 0x47, 0xc0, 0x48, 0x05, 0x48, 0x4b,
|
||||
0x48, 0x91, 0x48, 0xd7, 0x49, 0x1d, 0x49, 0x63, 0x49, 0xa9, 0x49, 0xf0,
|
||||
0x4a, 0x37, 0x4a, 0x7d, 0x4a, 0xc4, 0x4b, 0x0c, 0x4b, 0x53, 0x4b, 0x9a,
|
||||
0x4b, 0xe2, 0x4c, 0x2a, 0x4c, 0x72, 0x4c, 0xba, 0x4d, 0x02, 0x4d, 0x4a,
|
||||
0x4d, 0x93, 0x4d, 0xdc, 0x4e, 0x25, 0x4e, 0x6e, 0x4e, 0xb7, 0x4f, 0x00,
|
||||
0x4f, 0x49, 0x4f, 0x93, 0x4f, 0xdd, 0x50, 0x27, 0x50, 0x71, 0x50, 0xbb,
|
||||
0x51, 0x06, 0x51, 0x50, 0x51, 0x9b, 0x51, 0xe6, 0x52, 0x31, 0x52, 0x7c,
|
||||
0x52, 0xc7, 0x53, 0x13, 0x53, 0x5f, 0x53, 0xaa, 0x53, 0xf6, 0x54, 0x42,
|
||||
0x54, 0x8f, 0x54, 0xdb, 0x55, 0x28, 0x55, 0x75, 0x55, 0xc2, 0x56, 0x0f,
|
||||
0x56, 0x5c, 0x56, 0xa9, 0x56, 0xf7, 0x57, 0x44, 0x57, 0x92, 0x57, 0xe0,
|
||||
0x58, 0x2f, 0x58, 0x7d, 0x58, 0xcb, 0x59, 0x1a, 0x59, 0x69, 0x59, 0xb8,
|
||||
0x5a, 0x07, 0x5a, 0x56, 0x5a, 0xa6, 0x5a, 0xf5, 0x5b, 0x45, 0x5b, 0x95,
|
||||
0x5b, 0xe5, 0x5c, 0x35, 0x5c, 0x86, 0x5c, 0xd6, 0x5d, 0x27, 0x5d, 0x78,
|
||||
0x5d, 0xc9, 0x5e, 0x1a, 0x5e, 0x6c, 0x5e, 0xbd, 0x5f, 0x0f, 0x5f, 0x61,
|
||||
0x5f, 0xb3, 0x60, 0x05, 0x60, 0x57, 0x60, 0xaa, 0x60, 0xfc, 0x61, 0x4f,
|
||||
0x61, 0xa2, 0x61, 0xf5, 0x62, 0x49, 0x62, 0x9c, 0x62, 0xf0, 0x63, 0x43,
|
||||
0x63, 0x97, 0x63, 0xeb, 0x64, 0x40, 0x64, 0x94, 0x64, 0xe9, 0x65, 0x3d,
|
||||
0x65, 0x92, 0x65, 0xe7, 0x66, 0x3d, 0x66, 0x92, 0x66, 0xe8, 0x67, 0x3d,
|
||||
0x67, 0x93, 0x67, 0xe9, 0x68, 0x3f, 0x68, 0x96, 0x68, 0xec, 0x69, 0x43,
|
||||
0x69, 0x9a, 0x69, 0xf1, 0x6a, 0x48, 0x6a, 0x9f, 0x6a, 0xf7, 0x6b, 0x4f,
|
||||
0x6b, 0xa7, 0x6b, 0xff, 0x6c, 0x57, 0x6c, 0xaf, 0x6d, 0x08, 0x6d, 0x60,
|
||||
0x6d, 0xb9, 0x6e, 0x12, 0x6e, 0x6b, 0x6e, 0xc4, 0x6f, 0x1e, 0x6f, 0x78,
|
||||
0x6f, 0xd1, 0x70, 0x2b, 0x70, 0x86, 0x70, 0xe0, 0x71, 0x3a, 0x71, 0x95,
|
||||
0x71, 0xf0, 0x72, 0x4b, 0x72, 0xa6, 0x73, 0x01, 0x73, 0x5d, 0x73, 0xb8,
|
||||
0x74, 0x14, 0x74, 0x70, 0x74, 0xcc, 0x75, 0x28, 0x75, 0x85, 0x75, 0xe1,
|
||||
0x76, 0x3e, 0x76, 0x9b, 0x76, 0xf8, 0x77, 0x56, 0x77, 0xb3, 0x78, 0x11,
|
||||
0x78, 0x6e, 0x78, 0xcc, 0x79, 0x2a, 0x79, 0x89, 0x79, 0xe7, 0x7a, 0x46,
|
||||
0x7a, 0xa5, 0x7b, 0x04, 0x7b, 0x63, 0x7b, 0xc2, 0x7c, 0x21, 0x7c, 0x81,
|
||||
0x7c, 0xe1, 0x7d, 0x41, 0x7d, 0xa1, 0x7e, 0x01, 0x7e, 0x62, 0x7e, 0xc2,
|
||||
0x7f, 0x23, 0x7f, 0x84, 0x7f, 0xe5, 0x80, 0x47, 0x80, 0xa8, 0x81, 0x0a,
|
||||
0x81, 0x6b, 0x81, 0xcd, 0x82, 0x30, 0x82, 0x92, 0x82, 0xf4, 0x83, 0x57,
|
||||
0x83, 0xba, 0x84, 0x1d, 0x84, 0x80, 0x84, 0xe3, 0x85, 0x47, 0x85, 0xab,
|
||||
0x86, 0x0e, 0x86, 0x72, 0x86, 0xd7, 0x87, 0x3b, 0x87, 0x9f, 0x88, 0x04,
|
||||
0x88, 0x69, 0x88, 0xce, 0x89, 0x33, 0x89, 0x99, 0x89, 0xfe, 0x8a, 0x64,
|
||||
0x8a, 0xca, 0x8b, 0x30, 0x8b, 0x96, 0x8b, 0xfc, 0x8c, 0x63, 0x8c, 0xca,
|
||||
0x8d, 0x31, 0x8d, 0x98, 0x8d, 0xff, 0x8e, 0x66, 0x8e, 0xce, 0x8f, 0x36,
|
||||
0x8f, 0x9e, 0x90, 0x06, 0x90, 0x6e, 0x90, 0xd6, 0x91, 0x3f, 0x91, 0xa8,
|
||||
0x92, 0x11, 0x92, 0x7a, 0x92, 0xe3, 0x93, 0x4d, 0x93, 0xb6, 0x94, 0x20,
|
||||
0x94, 0x8a, 0x94, 0xf4, 0x95, 0x5f, 0x95, 0xc9, 0x96, 0x34, 0x96, 0x9f,
|
||||
0x97, 0x0a, 0x97, 0x75, 0x97, 0xe0, 0x98, 0x4c, 0x98, 0xb8, 0x99, 0x24,
|
||||
0x99, 0x90, 0x99, 0xfc, 0x9a, 0x68, 0x9a, 0xd5, 0x9b, 0x42, 0x9b, 0xaf,
|
||||
0x9c, 0x1c, 0x9c, 0x89, 0x9c, 0xf7, 0x9d, 0x64, 0x9d, 0xd2, 0x9e, 0x40,
|
||||
0x9e, 0xae, 0x9f, 0x1d, 0x9f, 0x8b, 0x9f, 0xfa, 0xa0, 0x69, 0xa0, 0xd8,
|
||||
0xa1, 0x47, 0xa1, 0xb6, 0xa2, 0x26, 0xa2, 0x96, 0xa3, 0x06, 0xa3, 0x76,
|
||||
0xa3, 0xe6, 0xa4, 0x56, 0xa4, 0xc7, 0xa5, 0x38, 0xa5, 0xa9, 0xa6, 0x1a,
|
||||
0xa6, 0x8b, 0xa6, 0xfd, 0xa7, 0x6e, 0xa7, 0xe0, 0xa8, 0x52, 0xa8, 0xc4,
|
||||
0xa9, 0x37, 0xa9, 0xa9, 0xaa, 0x1c, 0xaa, 0x8f, 0xab, 0x02, 0xab, 0x75,
|
||||
0xab, 0xe9, 0xac, 0x5c, 0xac, 0xd0, 0xad, 0x44, 0xad, 0xb8, 0xae, 0x2d,
|
||||
0xae, 0xa1, 0xaf, 0x16, 0xaf, 0x8b, 0xb0, 0x00, 0xb0, 0x75, 0xb0, 0xea,
|
||||
0xb1, 0x60, 0xb1, 0xd6, 0xb2, 0x4b, 0xb2, 0xc2, 0xb3, 0x38, 0xb3, 0xae,
|
||||
0xb4, 0x25, 0xb4, 0x9c, 0xb5, 0x13, 0xb5, 0x8a, 0xb6, 0x01, 0xb6, 0x79,
|
||||
0xb6, 0xf0, 0xb7, 0x68, 0xb7, 0xe0, 0xb8, 0x59, 0xb8, 0xd1, 0xb9, 0x4a,
|
||||
0xb9, 0xc2, 0xba, 0x3b, 0xba, 0xb5, 0xbb, 0x2e, 0xbb, 0xa7, 0xbc, 0x21,
|
||||
0xbc, 0x9b, 0xbd, 0x15, 0xbd, 0x8f, 0xbe, 0x0a, 0xbe, 0x84, 0xbe, 0xff,
|
||||
0xbf, 0x7a, 0xbf, 0xf5, 0xc0, 0x70, 0xc0, 0xec, 0xc1, 0x67, 0xc1, 0xe3,
|
||||
0xc2, 0x5f, 0xc2, 0xdb, 0xc3, 0x58, 0xc3, 0xd4, 0xc4, 0x51, 0xc4, 0xce,
|
||||
0xc5, 0x4b, 0xc5, 0xc8, 0xc6, 0x46, 0xc6, 0xc3, 0xc7, 0x41, 0xc7, 0xbf,
|
||||
0xc8, 0x3d, 0xc8, 0xbc, 0xc9, 0x3a, 0xc9, 0xb9, 0xca, 0x38, 0xca, 0xb7,
|
||||
0xcb, 0x36, 0xcb, 0xb6, 0xcc, 0x35, 0xcc, 0xb5, 0xcd, 0x35, 0xcd, 0xb5,
|
||||
0xce, 0x36, 0xce, 0xb6, 0xcf, 0x37, 0xcf, 0xb8, 0xd0, 0x39, 0xd0, 0xba,
|
||||
0xd1, 0x3c, 0xd1, 0xbe, 0xd2, 0x3f, 0xd2, 0xc1, 0xd3, 0x44, 0xd3, 0xc6,
|
||||
0xd4, 0x49, 0xd4, 0xcb, 0xd5, 0x4e, 0xd5, 0xd1, 0xd6, 0x55, 0xd6, 0xd8,
|
||||
0xd7, 0x5c, 0xd7, 0xe0, 0xd8, 0x64, 0xd8, 0xe8, 0xd9, 0x6c, 0xd9, 0xf1,
|
||||
0xda, 0x76, 0xda, 0xfb, 0xdb, 0x80, 0xdc, 0x05, 0xdc, 0x8a, 0xdd, 0x10,
|
||||
0xdd, 0x96, 0xde, 0x1c, 0xde, 0xa2, 0xdf, 0x29, 0xdf, 0xaf, 0xe0, 0x36,
|
||||
0xe0, 0xbd, 0xe1, 0x44, 0xe1, 0xcc, 0xe2, 0x53, 0xe2, 0xdb, 0xe3, 0x63,
|
||||
0xe3, 0xeb, 0xe4, 0x73, 0xe4, 0xfc, 0xe5, 0x84, 0xe6, 0x0d, 0xe6, 0x96,
|
||||
0xe7, 0x1f, 0xe7, 0xa9, 0xe8, 0x32, 0xe8, 0xbc, 0xe9, 0x46, 0xe9, 0xd0,
|
||||
0xea, 0x5b, 0xea, 0xe5, 0xeb, 0x70, 0xeb, 0xfb, 0xec, 0x86, 0xed, 0x11,
|
||||
0xed, 0x9c, 0xee, 0x28, 0xee, 0xb4, 0xef, 0x40, 0xef, 0xcc, 0xf0, 0x58,
|
||||
0xf0, 0xe5, 0xf1, 0x72, 0xf1, 0xff, 0xf2, 0x8c, 0xf3, 0x19, 0xf3, 0xa7,
|
||||
0xf4, 0x34, 0xf4, 0xc2, 0xf5, 0x50, 0xf5, 0xde, 0xf6, 0x6d, 0xf6, 0xfb,
|
||||
0xf7, 0x8a, 0xf8, 0x19, 0xf8, 0xa8, 0xf9, 0x38, 0xf9, 0xc7, 0xfa, 0x57,
|
||||
0xfa, 0xe7, 0xfb, 0x77, 0xfc, 0x07, 0xfc, 0x98, 0xfd, 0x29, 0xfd, 0xba,
|
||||
0xfe, 0x4b, 0xfe, 0xdc, 0xff, 0x6d, 0xff, 0xff, 0x58, 0x59, 0x5a, 0x20,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x51, 0x00, 0x01, 0x00, 0x00,
|
||||
0x00, 0x01, 0x16, 0xcc, 0x74, 0x65, 0x78, 0x74, 0x00, 0x00, 0x00, 0x00,
|
||||
0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x41, 0x70,
|
||||
0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x2c, 0x20, 0x32, 0x30,
|
||||
0x30, 0x38, 0x00, 0x00, 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x1f, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x20,
|
||||
0x47, 0x72, 0x61, 0x79, 0x20, 0x47, 0x61, 0x6d, 0x6d, 0x61, 0x20, 0x32,
|
||||
0x2e, 0x32, 0x20, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6d, 0x6c, 0x75, 0x63,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0c,
|
||||
0x65, 0x6e, 0x55, 0x53, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0xdc,
|
||||
0x65, 0x73, 0x45, 0x53, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x01, 0x18,
|
||||
0x64, 0x61, 0x44, 0x4b, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x02, 0x2a,
|
||||
0x64, 0x65, 0x44, 0x45, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x01, 0xde,
|
||||
0x66, 0x69, 0x46, 0x49, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x02, 0xa0,
|
||||
0x66, 0x72, 0x46, 0x55, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x02, 0x62,
|
||||
0x69, 0x74, 0x49, 0x54, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x03, 0x70,
|
||||
0x6e, 0x6c, 0x4e, 0x4c, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x01, 0x64,
|
||||
0x6e, 0x62, 0x4e, 0x4f, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x03, 0xc4,
|
||||
0x70, 0x74, 0x42, 0x52, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x03, 0x26,
|
||||
0x73, 0x76, 0x53, 0x45, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x02, 0x2a,
|
||||
0x6a, 0x61, 0x4a, 0x50, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x03, 0xfe,
|
||||
0x6b, 0x6f, 0x4b, 0x52, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x04, 0x24,
|
||||
0x7a, 0x68, 0x54, 0x57, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x04, 0x46,
|
||||
0x7a, 0x68, 0x43, 0x4e, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x04, 0x64,
|
||||
0x72, 0x75, 0x52, 0x55, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x01, 0xa4,
|
||||
0x70, 0x6c, 0x50, 0x4c, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x02, 0xe6,
|
||||
0x00, 0x47, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x72, 0x00, 0x69,
|
||||
0x00, 0x63, 0x00, 0x20, 0x00, 0x47, 0x00, 0x72, 0x00, 0x61, 0x00, 0x79,
|
||||
0x00, 0x20, 0x00, 0x47, 0x00, 0x61, 0x00, 0x6d, 0x00, 0x6d, 0x00, 0x61,
|
||||
0x00, 0x20, 0x00, 0x32, 0x00, 0x2e, 0x00, 0x32, 0x00, 0x20, 0x00, 0x50,
|
||||
0x00, 0x72, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x69, 0x00, 0x6c, 0x00, 0x65,
|
||||
0x00, 0x50, 0x00, 0x65, 0x00, 0x72, 0x00, 0x66, 0x00, 0x69, 0x00, 0x6c,
|
||||
0x00, 0x20, 0x00, 0x67, 0x00, 0x65, 0x00, 0x6e, 0x00, 0xe9, 0x00, 0x72,
|
||||
0x00, 0x69, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x20, 0x00, 0x64, 0x00, 0x65,
|
||||
0x00, 0x20, 0x00, 0x67, 0x00, 0x61, 0x00, 0x6d, 0x00, 0x6d, 0x00, 0x61,
|
||||
0x00, 0x20, 0x00, 0x64, 0x00, 0x65, 0x00, 0x20, 0x00, 0x67, 0x00, 0x72,
|
||||
0x00, 0x69, 0x00, 0x73, 0x00, 0x65, 0x00, 0x73, 0x00, 0x20, 0x00, 0x32,
|
||||
0x00, 0x2c, 0x00, 0x32, 0x00, 0x41, 0x00, 0x6c, 0x00, 0x67, 0x00, 0x65,
|
||||
0x00, 0x6d, 0x00, 0x65, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x67,
|
||||
0x00, 0x72, 0x00, 0x69, 0x00, 0x6a, 0x00, 0x73, 0x00, 0x20, 0x00, 0x67,
|
||||
0x00, 0x61, 0x00, 0x6d, 0x00, 0x6d, 0x00, 0x61, 0x00, 0x20, 0x00, 0x32,
|
||||
0x00, 0x2c, 0x00, 0x32, 0x00, 0x2d, 0x00, 0x70, 0x00, 0x72, 0x00, 0x6f,
|
||||
0x00, 0x66, 0x00, 0x69, 0x00, 0x65, 0x00, 0x6c, 0x04, 0x1e, 0x04, 0x31,
|
||||
0x04, 0x49, 0x04, 0x30, 0x04, 0x4f, 0x00, 0x20, 0x04, 0x41, 0x04, 0x35,
|
||||
0x04, 0x40, 0x04, 0x30, 0x04, 0x4f, 0x00, 0x20, 0x04, 0x33, 0x04, 0x30,
|
||||
0x04, 0x3c, 0x04, 0x3c, 0x04, 0x30, 0x00, 0x20, 0x00, 0x32, 0x00, 0x2c,
|
||||
0x00, 0x32, 0x00, 0x2d, 0x04, 0x3f, 0x04, 0x40, 0x04, 0x3e, 0x04, 0x44,
|
||||
0x04, 0x38, 0x04, 0x3b, 0x04, 0x4c, 0x00, 0x41, 0x00, 0x6c, 0x00, 0x6c,
|
||||
0x00, 0x67, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x69, 0x00, 0x6e,
|
||||
0x00, 0x65, 0x00, 0x73, 0x00, 0x20, 0x00, 0x47, 0x00, 0x72, 0x00, 0x61,
|
||||
0x00, 0x75, 0x00, 0x73, 0x00, 0x74, 0x00, 0x75, 0x00, 0x66, 0x00, 0x65,
|
||||
0x00, 0x6e, 0x00, 0x70, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x69,
|
||||
0x00, 0x6c, 0x00, 0x20, 0x00, 0x47, 0x00, 0x61, 0x00, 0x6d, 0x00, 0x6d,
|
||||
0x00, 0x61, 0x00, 0x20, 0x00, 0x32, 0x00, 0x2c, 0x00, 0x32, 0x00, 0x47,
|
||||
0x00, 0x65, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x72, 0x00, 0x69, 0x00, 0x73,
|
||||
0x00, 0x6b, 0x00, 0x20, 0x00, 0x67, 0x00, 0x72, 0x00, 0xe5, 0x00, 0x20,
|
||||
0x00, 0x32, 0x00, 0x2c, 0x00, 0x32, 0x00, 0x20, 0x00, 0x67, 0x00, 0x61,
|
||||
0x00, 0x6d, 0x00, 0x6d, 0x00, 0x61, 0x00, 0x70, 0x00, 0x72, 0x00, 0x6f,
|
||||
0x00, 0x66, 0x00, 0x69, 0x00, 0x6c, 0x00, 0x50, 0x00, 0x72, 0x00, 0x6f,
|
||||
0x00, 0x66, 0x00, 0x69, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x67, 0x00, 0xe9,
|
||||
0x00, 0x6e, 0x00, 0xe9, 0x00, 0x72, 0x00, 0x69, 0x00, 0x71, 0x00, 0x75,
|
||||
0x00, 0x65, 0x00, 0x20, 0x00, 0x67, 0x00, 0x72, 0x00, 0x69, 0x00, 0x73,
|
||||
0x00, 0x20, 0x00, 0x67, 0x00, 0x61, 0x00, 0x6d, 0x00, 0x6d, 0x00, 0x61,
|
||||
0x00, 0x20, 0x00, 0x32, 0x00, 0x2c, 0x00, 0x32, 0x00, 0x59, 0x00, 0x6c,
|
||||
0x00, 0x65, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x20,
|
||||
0x00, 0x68, 0x00, 0x61, 0x00, 0x72, 0x00, 0x6d, 0x00, 0x61, 0x00, 0x61,
|
||||
0x00, 0x6e, 0x00, 0x20, 0x00, 0x67, 0x00, 0x61, 0x00, 0x6d, 0x00, 0x6d,
|
||||
0x00, 0x61, 0x00, 0x20, 0x00, 0x32, 0x00, 0x2c, 0x00, 0x32, 0x00, 0x20,
|
||||
0x00, 0x2d, 0x00, 0x70, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x69,
|
||||
0x00, 0x69, 0x00, 0x6c, 0x00, 0x69, 0x00, 0x4f, 0x00, 0x67, 0x00, 0xf3,
|
||||
0x00, 0x6c, 0x00, 0x6e, 0x00, 0x79, 0x00, 0x20, 0x00, 0x70, 0x00, 0x72,
|
||||
0x00, 0x6f, 0x00, 0x66, 0x00, 0x69, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x73,
|
||||
0x00, 0x7a, 0x00, 0x61, 0x00, 0x72, 0x00, 0x6f, 0x01, 0x5b, 0x00, 0x63,
|
||||
0x00, 0x69, 0x00, 0x20, 0x00, 0x67, 0x00, 0x61, 0x00, 0x6d, 0x00, 0x6d,
|
||||
0x00, 0x61, 0x00, 0x20, 0x00, 0x32, 0x00, 0x2c, 0x00, 0x32, 0x00, 0x50,
|
||||
0x00, 0x65, 0x00, 0x72, 0x00, 0x66, 0x00, 0x69, 0x00, 0x6c, 0x00, 0x20,
|
||||
0x00, 0x47, 0x00, 0x65, 0x00, 0x6e, 0x00, 0xe9, 0x00, 0x72, 0x00, 0x69,
|
||||
0x00, 0x63, 0x00, 0x6f, 0x00, 0x20, 0x00, 0x64, 0x00, 0x61, 0x00, 0x20,
|
||||
0x00, 0x47, 0x00, 0x61, 0x00, 0x6d, 0x00, 0x61, 0x00, 0x20, 0x00, 0x64,
|
||||
0x00, 0x65, 0x00, 0x20, 0x00, 0x43, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x7a,
|
||||
0x00, 0x61, 0x00, 0x73, 0x00, 0x20, 0x00, 0x32, 0x00, 0x2c, 0x00, 0x32,
|
||||
0x00, 0x50, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x69, 0x00, 0x6c,
|
||||
0x00, 0x6f, 0x00, 0x20, 0x00, 0x67, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x65,
|
||||
0x00, 0x72, 0x00, 0x69, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x20, 0x00, 0x64,
|
||||
0x00, 0x65, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x61, 0x00, 0x20, 0x00, 0x67,
|
||||
0x00, 0x61, 0x00, 0x6d, 0x00, 0x6d, 0x00, 0x61, 0x00, 0x20, 0x00, 0x64,
|
||||
0x00, 0x65, 0x00, 0x69, 0x00, 0x20, 0x00, 0x67, 0x00, 0x72, 0x00, 0x69,
|
||||
0x00, 0x67, 0x00, 0x69, 0x00, 0x20, 0x00, 0x32, 0x00, 0x2c, 0x00, 0x32,
|
||||
0x00, 0x47, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x72, 0x00, 0x69,
|
||||
0x00, 0x73, 0x00, 0x6b, 0x00, 0x20, 0x00, 0x67, 0x00, 0x72, 0x00, 0xe5,
|
||||
0x00, 0x20, 0x00, 0x67, 0x00, 0x61, 0x00, 0x6d, 0x00, 0x6d, 0x00, 0x61,
|
||||
0x00, 0x20, 0x00, 0x32, 0x00, 0x2c, 0x00, 0x32, 0x00, 0x2d, 0x00, 0x70,
|
||||
0x00, 0x72, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x69, 0x00, 0x6c, 0x4e, 0x00,
|
||||
0x82, 0x2c, 0x30, 0xb0, 0x30, 0xec, 0x30, 0xa4, 0x30, 0xac, 0x30, 0xf3,
|
||||
0x30, 0xde, 0x00, 0x20, 0x00, 0x32, 0x00, 0x2e, 0x00, 0x32, 0x00, 0x20,
|
||||
0x30, 0xd7, 0x30, 0xed, 0x30, 0xd5, 0x30, 0xa1, 0x30, 0xa4, 0x30, 0xeb,
|
||||
0xc7, 0x7c, 0xbc, 0x18, 0x00, 0x20, 0xd6, 0x8c, 0xc0, 0xc9, 0x00, 0x20,
|
||||
0xac, 0x10, 0xb9, 0xc8, 0x00, 0x20, 0x00, 0x32, 0x00, 0x2e, 0x00, 0x32,
|
||||
0x00, 0x20, 0xd5, 0x04, 0xb8, 0x5c, 0xd3, 0x0c, 0xc7, 0x7c, 0x90, 0x1a,
|
||||
0x75, 0x28, 0x70, 0x70, 0x96, 0x8e, 0x51, 0x49, 0x5e, 0xa6, 0x00, 0x20,
|
||||
0x00, 0x32, 0x00, 0x2e, 0x00, 0x32, 0x00, 0x20, 0x82, 0x72, 0x5f, 0x69,
|
||||
0x63, 0xcf, 0x8f, 0xf0, 0x90, 0x1a, 0x75, 0x28, 0x70, 0x70, 0x5e, 0xa6,
|
||||
0x7c, 0xfb, 0x65, 0x70, 0x00, 0x20, 0x00, 0x32, 0x00, 0x2e, 0x00, 0x32,
|
||||
0x00, 0x20, 0x63, 0xcf, 0x8f, 0xf0, 0x65, 0x87, 0x4e, 0xf6, 0x00, 0x00,
|
||||
}
|
||||
|
||||
temporaryDirectory = temporaryDirectoryOrPanic()
|
||||
SRGBV2MicroICCProfilePath = filepath.Join(temporaryDirectory, "srgb_v2_micro.icc")
|
||||
SGrayV2MicroICCProfilePath = filepath.Join(temporaryDirectory, "sgray_v2_micro.icc")
|
||||
SRGBIEC6196621ICCProfilePath = filepath.Join(temporaryDirectory, "srgb_iec61966_2_1.icc")
|
||||
GenericGrayGamma22ICCProfilePath = filepath.Join(temporaryDirectory, "generic_gray_gamma_2_2.icc")
|
||||
)
|
||||
|
||||
func initializeICCProfiles() {
|
||||
storeIccProfile(SRGBV2MicroICCProfilePath, sRGBV2MicroICCProfile)
|
||||
storeIccProfile(SGrayV2MicroICCProfilePath, sGrayV2MicroICCProfile)
|
||||
storeIccProfile(SRGBIEC6196621ICCProfilePath, sRGBIEC6196621ICCProfile)
|
||||
storeIccProfile(GenericGrayGamma22ICCProfilePath, genericGrayGamma22ICCProfile)
|
||||
}
|
||||
|
||||
func storeIccProfile(path string, data []byte) {
|
||||
err := os.WriteFile(path, data, 0600)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("Couldn't store temporary file for ICC profile in '%v': %v", path, err.Error()))
|
||||
}
|
||||
}
|
||||
|
||||
func temporaryDirectoryOrPanic() string {
|
||||
temporaryDirectory, err := os.MkdirTemp("", "govips-")
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("Couldn't create temporary directory: %v", err.Error()))
|
||||
}
|
||||
|
||||
return temporaryDirectory
|
||||
}
|
||||
9
vendor/github.com/davidbyttow/govips/v2/vips/image.c
generated
vendored
Normal file
9
vendor/github.com/davidbyttow/govips/v2/vips/image.c
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
#include "image.h"
|
||||
|
||||
int has_alpha_channel(VipsImage *image) { return vips_image_hasalpha(image); }
|
||||
|
||||
void clear_image(VipsImage **image) {
|
||||
// Reference-counting in libvips: https://www.libvips.org/API/current/using-from-c.html#using-C-ref
|
||||
// https://docs.gtk.org/gobject/method.Object.unref.html
|
||||
if (G_IS_OBJECT(*image)) g_object_unref(*image);
|
||||
}
|
||||
2162
vendor/github.com/davidbyttow/govips/v2/vips/image.go
generated
vendored
Normal file
2162
vendor/github.com/davidbyttow/govips/v2/vips/image.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
8
vendor/github.com/davidbyttow/govips/v2/vips/image.h
generated
vendored
Normal file
8
vendor/github.com/davidbyttow/govips/v2/vips/image.h
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
// https://libvips.github.io/libvips/API/current/VipsImage.html
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <vips/vips.h>
|
||||
|
||||
int has_alpha_channel(VipsImage *image);
|
||||
|
||||
void clear_image(VipsImage **image);
|
||||
37
vendor/github.com/davidbyttow/govips/v2/vips/label.c
generated
vendored
Normal file
37
vendor/github.com/davidbyttow/govips/v2/vips/label.c
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
#include "label.h"
|
||||
|
||||
int text(VipsImage **out, const char *text, const char *font, int width,
|
||||
int height, VipsAlign align, int dpi) {
|
||||
return vips_text(out, text, "font", font, "width", width, "height", height,
|
||||
"align", align, "dpi", dpi, NULL);
|
||||
}
|
||||
|
||||
int label(VipsImage *in, VipsImage **out, LabelOptions *o) {
|
||||
double ones[3] = {1, 1, 1};
|
||||
VipsImage *base = vips_image_new();
|
||||
VipsImage **t = (VipsImage **)vips_object_local_array(VIPS_OBJECT(base), 9);
|
||||
if (vips_text(&t[0], o->Text, "font", o->Font, "width", o->Width, "height",
|
||||
o->Height, "align", o->Align, NULL) ||
|
||||
vips_linear1(t[0], &t[1], o->Opacity, 0.0, NULL) ||
|
||||
vips_cast(t[1], &t[2], VIPS_FORMAT_UCHAR, NULL) ||
|
||||
vips_embed(t[2], &t[3], o->OffsetX, o->OffsetY, t[2]->Xsize + o->OffsetX,
|
||||
t[2]->Ysize + o->OffsetY, NULL)) {
|
||||
g_object_unref(base);
|
||||
return 1;
|
||||
}
|
||||
if (vips_black(&t[4], 1, 1, NULL) ||
|
||||
vips_linear(t[4], &t[5], ones, o->Color, 3, NULL) ||
|
||||
vips_cast(t[5], &t[6], VIPS_FORMAT_UCHAR, NULL) ||
|
||||
vips_copy(t[6], &t[7], "interpretation", in->Type, NULL) ||
|
||||
vips_embed(t[7], &t[8], 0, 0, in->Xsize, in->Ysize, "extend",
|
||||
VIPS_EXTEND_COPY, NULL)) {
|
||||
g_object_unref(base);
|
||||
return 1;
|
||||
}
|
||||
if (vips_ifthenelse(t[3], t[8], in, out, "blend", TRUE, NULL)) {
|
||||
g_object_unref(base);
|
||||
return 1;
|
||||
}
|
||||
g_object_unref(base);
|
||||
return 0;
|
||||
}
|
||||
84
vendor/github.com/davidbyttow/govips/v2/vips/label.go
generated
vendored
Normal file
84
vendor/github.com/davidbyttow/govips/v2/vips/label.go
generated
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
package vips
|
||||
|
||||
// #include "label.h"
|
||||
import "C"
|
||||
import "unsafe"
|
||||
|
||||
// Align represents VIPS_ALIGN
|
||||
type Align int
|
||||
|
||||
// Direction enum
|
||||
const (
|
||||
AlignLow Align = C.VIPS_ALIGN_LOW
|
||||
AlignCenter Align = C.VIPS_ALIGN_CENTRE
|
||||
AlignHigh Align = C.VIPS_ALIGN_HIGH
|
||||
)
|
||||
|
||||
// DefaultFont is the default font to be used for label texts created by govips
|
||||
const DefaultFont = "sans 10"
|
||||
|
||||
// LabelParams represents a text-based label
|
||||
type LabelParams struct {
|
||||
Text string
|
||||
Font string
|
||||
Width Scalar
|
||||
Height Scalar
|
||||
OffsetX Scalar
|
||||
OffsetY Scalar
|
||||
Opacity float32
|
||||
Color Color
|
||||
Alignment Align
|
||||
}
|
||||
|
||||
type vipsLabelOptions struct {
|
||||
Text *C.char
|
||||
Font *C.char
|
||||
Width C.int
|
||||
Height C.int
|
||||
OffsetX C.int
|
||||
OffsetY C.int
|
||||
Alignment C.VipsAlign
|
||||
DPI C.int
|
||||
Margin C.int
|
||||
Opacity C.float
|
||||
Color [3]C.double
|
||||
}
|
||||
|
||||
func labelImage(in *C.VipsImage, params *LabelParams) (*C.VipsImage, error) {
|
||||
incOpCounter("label")
|
||||
var out *C.VipsImage
|
||||
|
||||
text := C.CString(params.Text)
|
||||
defer freeCString(text)
|
||||
|
||||
font := C.CString(params.Font)
|
||||
defer freeCString(font)
|
||||
|
||||
// todo: release color?
|
||||
color := [3]C.double{C.double(params.Color.R), C.double(params.Color.G), C.double(params.Color.B)}
|
||||
|
||||
w := params.Width.GetRounded(int(in.Xsize))
|
||||
h := params.Height.GetRounded(int(in.Ysize))
|
||||
offsetX := params.OffsetX.GetRounded(int(in.Xsize))
|
||||
offsetY := params.OffsetY.GetRounded(int(in.Ysize))
|
||||
|
||||
opts := vipsLabelOptions{
|
||||
Text: text,
|
||||
Font: font,
|
||||
Width: C.int(w),
|
||||
Height: C.int(h),
|
||||
OffsetX: C.int(offsetX),
|
||||
OffsetY: C.int(offsetY),
|
||||
Alignment: C.VipsAlign(params.Alignment),
|
||||
Opacity: C.float(params.Opacity),
|
||||
Color: color,
|
||||
}
|
||||
|
||||
// todo: release inline pointer?
|
||||
err := C.label(in, &out, (*C.LabelOptions)(unsafe.Pointer(&opts)))
|
||||
if err != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
21
vendor/github.com/davidbyttow/govips/v2/vips/label.h
generated
vendored
Normal file
21
vendor/github.com/davidbyttow/govips/v2/vips/label.h
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
#include <stdlib.h>
|
||||
#include <vips/vips.h>
|
||||
|
||||
typedef struct {
|
||||
const char *Text;
|
||||
const char *Font;
|
||||
int Width;
|
||||
int Height;
|
||||
int OffsetX;
|
||||
int OffsetY;
|
||||
VipsAlign Align;
|
||||
int DPI;
|
||||
int Margin;
|
||||
float Opacity;
|
||||
double Color[3];
|
||||
} LabelOptions;
|
||||
|
||||
int label(VipsImage *in, VipsImage **out, LabelOptions *o);
|
||||
|
||||
int text(VipsImage **out, const char *text, const char *font, int width,
|
||||
int height, VipsAlign align, int dpi);
|
||||
49
vendor/github.com/davidbyttow/govips/v2/vips/lang.go
generated
vendored
Normal file
49
vendor/github.com/davidbyttow/govips/v2/vips/lang.go
generated
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
package vips
|
||||
|
||||
// #include <vips/vips.h>
|
||||
// #include <stdlib.h>
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func freeCString(s *C.char) {
|
||||
C.free(unsafe.Pointer(s))
|
||||
}
|
||||
|
||||
func gFreePointer(ref unsafe.Pointer) {
|
||||
C.g_free(C.gpointer(ref))
|
||||
}
|
||||
|
||||
func boolToInt(b bool) int {
|
||||
if b {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func toGboolean(b bool) C.gboolean {
|
||||
if b {
|
||||
return C.gboolean(1)
|
||||
}
|
||||
return C.gboolean(0)
|
||||
}
|
||||
|
||||
func fromGboolean(b C.gboolean) bool {
|
||||
return b != 0
|
||||
}
|
||||
|
||||
func fromCArrayInt(out *C.int, n int) []int {
|
||||
var result = make([]int, n)
|
||||
var data []C.int
|
||||
sh := (*reflect.SliceHeader)(unsafe.Pointer(&data))
|
||||
sh.Data = uintptr(unsafe.Pointer(out))
|
||||
sh.Len = n
|
||||
sh.Cap = n
|
||||
for i := range data {
|
||||
result[i] = int(data[i])
|
||||
}
|
||||
return result
|
||||
}
|
||||
4
vendor/github.com/davidbyttow/govips/v2/vips/lang.h
generated
vendored
Normal file
4
vendor/github.com/davidbyttow/govips/v2/vips/lang.h
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
#include <stdlib.h>
|
||||
#include <vips/vips.h>
|
||||
|
||||
#define INT_TO_GBOOLEAN(bool) (bool > 0 ? TRUE : FALSE)
|
||||
98
vendor/github.com/davidbyttow/govips/v2/vips/logging.go
generated
vendored
Normal file
98
vendor/github.com/davidbyttow/govips/v2/vips/logging.go
generated
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
package vips
|
||||
|
||||
// #include <glib.h>
|
||||
import "C"
|
||||
import (
|
||||
"log"
|
||||
)
|
||||
|
||||
// LogLevel is the enum controlling logging message verbosity.
|
||||
type LogLevel int
|
||||
|
||||
// The logging verbosity levels classify and filter logging messages.
|
||||
// From most to least verbose, they are debug, info, message, warning, critical and error.
|
||||
const (
|
||||
LogLevelError LogLevel = C.G_LOG_LEVEL_ERROR
|
||||
LogLevelCritical LogLevel = C.G_LOG_LEVEL_CRITICAL
|
||||
LogLevelWarning LogLevel = C.G_LOG_LEVEL_WARNING
|
||||
LogLevelMessage LogLevel = C.G_LOG_LEVEL_MESSAGE
|
||||
LogLevelInfo LogLevel = C.G_LOG_LEVEL_INFO
|
||||
LogLevelDebug LogLevel = C.G_LOG_LEVEL_DEBUG
|
||||
)
|
||||
|
||||
// Three global variables which keep state of the current logging handler
|
||||
// function, desired verbosity for logging and whether defaults have been
|
||||
// overridden. Set by LoggingSettings()
|
||||
var (
|
||||
currentLoggingHandlerFunction LoggingHandlerFunction
|
||||
currentLoggingVerbosity LogLevel
|
||||
currentLoggingOverridden bool
|
||||
)
|
||||
|
||||
// govipsLoggingHandler is the private bridge function exported to the C library
|
||||
// and called by glib and libvips for each logging message. It will call govipsLog
|
||||
// which in turn will filter based on verbosity and direct the messages to the
|
||||
// currently chosen LoggingHandlerFunction.
|
||||
//
|
||||
//export govipsLoggingHandler
|
||||
func govipsLoggingHandler(messageDomain *C.char, messageLevel C.int, message *C.char) {
|
||||
govipsLog(C.GoString(messageDomain), LogLevel(messageLevel), C.GoString(message))
|
||||
}
|
||||
|
||||
// LoggingHandlerFunction is a function which will be called for each log message.
|
||||
// By default, govips sends logging messages to os.Stderr. If you want to log elsewhere
|
||||
// such as to a file or to a state variable which you inspect yourself, define a new
|
||||
// logging handler function and set it via LoggingSettings().
|
||||
type LoggingHandlerFunction func(messageDomain string, messageLevel LogLevel, message string)
|
||||
|
||||
// LoggingSettings sets the logging handler and logging verbosity for govips.
|
||||
// The handler function is the function which will be called for each log message.
|
||||
// You can define one yourself to log somewhere else besides the default (stderr).
|
||||
// Use nil as handler to use standard logging handler.
|
||||
// Verbosity is the minimum logLevel you want to log. Default is logLevelInfo
|
||||
// due to backwards compatibility but it's quite verbose for a library.
|
||||
// Suggest setting it to at least logLevelWarning. Use logLevelDebug for debugging.
|
||||
func LoggingSettings(handler LoggingHandlerFunction, verbosity LogLevel) {
|
||||
currentLoggingOverridden = true
|
||||
govipsLoggingSettings(handler, verbosity)
|
||||
}
|
||||
|
||||
func govipsLoggingSettings(handler LoggingHandlerFunction, verbosity LogLevel) {
|
||||
if handler == nil {
|
||||
currentLoggingHandlerFunction = defaultLoggingHandlerFunction
|
||||
} else {
|
||||
currentLoggingHandlerFunction = handler
|
||||
}
|
||||
|
||||
currentLoggingVerbosity = verbosity
|
||||
// TODO turn on debugging in libvips and redirect to handler when setting verbosity to debug
|
||||
// This way debugging information would go to the same channel as all other logging
|
||||
}
|
||||
|
||||
func defaultLoggingHandlerFunction(messageDomain string, messageLevel LogLevel, message string) {
|
||||
var messageLevelDescription string
|
||||
switch messageLevel {
|
||||
case LogLevelError:
|
||||
messageLevelDescription = "error"
|
||||
case LogLevelCritical:
|
||||
messageLevelDescription = "critical"
|
||||
case LogLevelWarning:
|
||||
messageLevelDescription = "warning"
|
||||
case LogLevelMessage:
|
||||
messageLevelDescription = "message"
|
||||
case LogLevelInfo:
|
||||
messageLevelDescription = "info"
|
||||
case LogLevelDebug:
|
||||
messageLevelDescription = "debug"
|
||||
}
|
||||
|
||||
log.Printf("[%v.%v] %v", messageDomain, messageLevelDescription, message)
|
||||
}
|
||||
|
||||
// govipsLog is the default function used to log debug or error messages internally in govips.
|
||||
// It's used by all govips functionality directly, as well as by glib and libvips via the C bridge.
|
||||
func govipsLog(messageDomain string, messageLevel LogLevel, message string) {
|
||||
if messageLevel <= currentLoggingVerbosity {
|
||||
currentLoggingHandlerFunction(messageDomain, messageLevel, message)
|
||||
}
|
||||
}
|
||||
57
vendor/github.com/davidbyttow/govips/v2/vips/math.go
generated
vendored
Normal file
57
vendor/github.com/davidbyttow/govips/v2/vips/math.go
generated
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
package vips
|
||||
|
||||
import "math"
|
||||
|
||||
// Scalar is the basic scalar measurement of an image's height, width or offset coordinate.
|
||||
type Scalar struct {
|
||||
Value float64
|
||||
Relative bool
|
||||
}
|
||||
|
||||
// ValueOf takes a floating point value and returns a corresponding Scalar struct
|
||||
func ValueOf(value float64) Scalar {
|
||||
return Scalar{value, false}
|
||||
}
|
||||
|
||||
// IsZero checkes whether the associated Scalar's value is zero.
|
||||
func (s *Scalar) IsZero() bool {
|
||||
return s.Value == 0 && !s.Relative
|
||||
}
|
||||
|
||||
// SetInt sets an integer value for the associated Scalar.
|
||||
func (s *Scalar) SetInt(value int) {
|
||||
s.Set(float64(value))
|
||||
}
|
||||
|
||||
// Set sets a float value for the associated Scalar.
|
||||
func (s *Scalar) Set(value float64) {
|
||||
s.Value = value
|
||||
s.Relative = false
|
||||
}
|
||||
|
||||
// SetScale sets a float value for the associated Scalar and makes it relative.
|
||||
func (s *Scalar) SetScale(f float64) {
|
||||
s.Value = f
|
||||
s.Relative = true
|
||||
}
|
||||
|
||||
// Get returns the value of the scalar. Either absolute, or if relative, multiplied by the base given as parameter.
|
||||
func (s *Scalar) Get(base int) float64 {
|
||||
if s.Relative {
|
||||
return s.Value * float64(base)
|
||||
}
|
||||
return s.Value
|
||||
}
|
||||
|
||||
// GetRounded returns the value of the associated Scalar, rounded to the nearest integer, if absolute.
|
||||
// If the Scalar is relative, it will be multiplied by the supplied base parameter.
|
||||
func (s *Scalar) GetRounded(base int) int {
|
||||
return roundFloat(s.Get(base))
|
||||
}
|
||||
|
||||
func roundFloat(f float64) int {
|
||||
if f < 0 {
|
||||
return int(math.Ceil(f - 0.5))
|
||||
}
|
||||
return int(math.Floor(f + 0.5))
|
||||
}
|
||||
6
vendor/github.com/davidbyttow/govips/v2/vips/morphology.c
generated
vendored
Normal file
6
vendor/github.com/davidbyttow/govips/v2/vips/morphology.c
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
#include "morphology.h"
|
||||
|
||||
int rank(VipsImage *in, VipsImage **out, int width, int height, int index) {
|
||||
return vips_rank(in, out, width, height, index, NULL);
|
||||
}
|
||||
|
||||
17
vendor/github.com/davidbyttow/govips/v2/vips/morphology.go
generated
vendored
Normal file
17
vendor/github.com/davidbyttow/govips/v2/vips/morphology.go
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
package vips
|
||||
|
||||
// #include "morphology.h"
|
||||
import "C"
|
||||
|
||||
// https://libvips.github.io/libvips/API/current/libvips-morphology.html#vips-rank
|
||||
func vipsRank(in *C.VipsImage, width int, height int, index int) (*C.VipsImage, error) {
|
||||
incOpCounter("rank")
|
||||
var out *C.VipsImage
|
||||
|
||||
err := C.rank(in, &out, C.int(width), C.int(height), C.int(index))
|
||||
if int(err) != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
6
vendor/github.com/davidbyttow/govips/v2/vips/morphology.h
generated
vendored
Normal file
6
vendor/github.com/davidbyttow/govips/v2/vips/morphology.h
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
// https://libvips.github.io/libvips/API/current/libvips-morphology.html
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <vips/vips.h>
|
||||
|
||||
int rank(VipsImage *in, VipsImage **out, int width, int height, int index);
|
||||
61
vendor/github.com/davidbyttow/govips/v2/vips/resample.c
generated
vendored
Normal file
61
vendor/github.com/davidbyttow/govips/v2/vips/resample.c
generated
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
#include "resample.h"
|
||||
|
||||
int shrink_image(VipsImage *in, VipsImage **out, double xshrink,
|
||||
double yshrink) {
|
||||
return vips_shrink(in, out, xshrink, yshrink, NULL);
|
||||
}
|
||||
|
||||
int reduce_image(VipsImage *in, VipsImage **out, double xshrink,
|
||||
double yshrink) {
|
||||
return vips_reduce(in, out, xshrink, yshrink, NULL);
|
||||
}
|
||||
|
||||
int affine_image(VipsImage *in, VipsImage **out, double a, double b, double c,
|
||||
double d, VipsInterpolate *interpolator) {
|
||||
return vips_affine(in, out, a, b, c, d, "interpolate", interpolator, NULL);
|
||||
}
|
||||
|
||||
int resize_image(VipsImage *in, VipsImage **out, double scale, gdouble vscale,
|
||||
int kernel) {
|
||||
if (vscale > 0) {
|
||||
return vips_resize(in, out, scale, "vscale", vscale, "kernel", kernel,
|
||||
NULL);
|
||||
}
|
||||
|
||||
return vips_resize(in, out, scale, "kernel", kernel, NULL);
|
||||
}
|
||||
|
||||
int thumbnail(const char *filename, VipsImage **out,
|
||||
int width, int height, int crop, int size) {
|
||||
return vips_thumbnail(filename, out, width, "height", height,
|
||||
"crop", crop, "size", size, NULL);
|
||||
}
|
||||
|
||||
int thumbnail_image(VipsImage *in, VipsImage **out, int width, int height,
|
||||
int crop, int size) {
|
||||
return vips_thumbnail_image(in, out, width, "height", height, "crop", crop,
|
||||
"size", size, NULL);
|
||||
}
|
||||
|
||||
int thumbnail_buffer_with_option(void *buf, size_t len, VipsImage **out,
|
||||
int width, int height, int crop, int size,
|
||||
const char *option_string) {
|
||||
return vips_thumbnail_buffer(buf, len, out, width, "height", height,
|
||||
"crop", crop, "size", size,
|
||||
"option_string", option_string, NULL);
|
||||
}
|
||||
|
||||
int thumbnail_buffer(void *buf, size_t len, VipsImage **out,
|
||||
int width, int height, int crop, int size) {
|
||||
return vips_thumbnail_buffer(buf, len, out, width, "height", height,
|
||||
"crop", crop, "size", size, NULL);
|
||||
}
|
||||
|
||||
int mapim(VipsImage *in, VipsImage **out, VipsImage *index) {
|
||||
return vips_mapim(in, out, index, NULL);
|
||||
}
|
||||
|
||||
int maplut(VipsImage *in, VipsImage **out, VipsImage *lut) {
|
||||
return vips_maplut(in, out, lut, NULL);
|
||||
}
|
||||
|
||||
146
vendor/github.com/davidbyttow/govips/v2/vips/resample.go
generated
vendored
Normal file
146
vendor/github.com/davidbyttow/govips/v2/vips/resample.go
generated
vendored
Normal file
@@ -0,0 +1,146 @@
|
||||
package vips
|
||||
|
||||
// #include "resample.h"
|
||||
import "C"
|
||||
import (
|
||||
"os"
|
||||
"runtime"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// Kernel represents VipsKernel type
|
||||
type Kernel int
|
||||
|
||||
// Kernel enum
|
||||
const (
|
||||
KernelAuto Kernel = -1
|
||||
KernelNearest Kernel = C.VIPS_KERNEL_NEAREST
|
||||
KernelLinear Kernel = C.VIPS_KERNEL_LINEAR
|
||||
KernelCubic Kernel = C.VIPS_KERNEL_CUBIC
|
||||
KernelLanczos2 Kernel = C.VIPS_KERNEL_LANCZOS2
|
||||
KernelLanczos3 Kernel = C.VIPS_KERNEL_LANCZOS3
|
||||
KernelMitchell Kernel = C.VIPS_KERNEL_MITCHELL
|
||||
)
|
||||
|
||||
// Size represents VipsSize type
|
||||
type Size int
|
||||
|
||||
const (
|
||||
SizeBoth Size = C.VIPS_SIZE_BOTH
|
||||
SizeUp Size = C.VIPS_SIZE_UP
|
||||
SizeDown Size = C.VIPS_SIZE_DOWN
|
||||
SizeForce Size = C.VIPS_SIZE_FORCE
|
||||
SizeLast Size = C.VIPS_SIZE_LAST
|
||||
)
|
||||
|
||||
// https://libvips.github.io/libvips/API/current/libvips-resample.html#vips-resize
|
||||
func vipsResizeWithVScale(in *C.VipsImage, hscale, vscale float64, kernel Kernel) (*C.VipsImage, error) {
|
||||
incOpCounter("resize")
|
||||
var out *C.VipsImage
|
||||
|
||||
// libvips recommends Lanczos3 as the default kernel
|
||||
if kernel == KernelAuto {
|
||||
kernel = KernelLanczos3
|
||||
}
|
||||
|
||||
if err := C.resize_image(in, &out, C.double(hscale), C.double(vscale), C.int(kernel)); err != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func vipsThumbnail(in *C.VipsImage, width, height int, crop Interesting, size Size) (*C.VipsImage, error) {
|
||||
incOpCounter("thumbnail")
|
||||
var out *C.VipsImage
|
||||
|
||||
if err := C.thumbnail_image(in, &out, C.int(width), C.int(height), C.int(crop), C.int(size)); err != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// https://www.libvips.org/API/current/libvips-resample.html#vips-thumbnail
|
||||
func vipsThumbnailFromFile(filename string, width, height int, crop Interesting, size Size, params *ImportParams) (*C.VipsImage, ImageType, error) {
|
||||
var out *C.VipsImage
|
||||
|
||||
filenameOption := filename
|
||||
if params != nil {
|
||||
filenameOption += "[" + params.OptionString() + "]"
|
||||
}
|
||||
|
||||
cFileName := C.CString(filenameOption)
|
||||
defer freeCString(cFileName)
|
||||
|
||||
if err := C.thumbnail(cFileName, &out, C.int(width), C.int(height), C.int(crop), C.int(size)); err != 0 {
|
||||
err := handleImageError(out)
|
||||
if src, err2 := os.ReadFile(filename); err2 == nil {
|
||||
if isBMP(src) {
|
||||
if src2, err3 := bmpToPNG(src); err3 == nil {
|
||||
return vipsThumbnailFromBuffer(src2, width, height, crop, size, params)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil, ImageTypeUnknown, err
|
||||
}
|
||||
|
||||
imageType := vipsDetermineImageTypeFromMetaLoader(out)
|
||||
return out, imageType, nil
|
||||
}
|
||||
|
||||
// https://www.libvips.org/API/current/libvips-resample.html#vips-thumbnail-buffer
|
||||
func vipsThumbnailFromBuffer(buf []byte, width, height int, crop Interesting, size Size, params *ImportParams) (*C.VipsImage, ImageType, error) {
|
||||
src := buf
|
||||
// Reference src here so it's not garbage collected during image initialization.
|
||||
defer runtime.KeepAlive(src)
|
||||
|
||||
var out *C.VipsImage
|
||||
|
||||
var err C.int
|
||||
|
||||
if params == nil {
|
||||
err = C.thumbnail_buffer(unsafe.Pointer(&src[0]), C.size_t(len(src)), &out, C.int(width), C.int(height), C.int(crop), C.int(size))
|
||||
} else {
|
||||
cOptionString := C.CString(params.OptionString())
|
||||
defer freeCString(cOptionString)
|
||||
|
||||
err = C.thumbnail_buffer_with_option(unsafe.Pointer(&src[0]), C.size_t(len(src)), &out, C.int(width), C.int(height), C.int(crop), C.int(size), cOptionString)
|
||||
}
|
||||
if err != 0 {
|
||||
err := handleImageError(out)
|
||||
if isBMP(src) {
|
||||
if src2, err2 := bmpToPNG(src); err2 == nil {
|
||||
return vipsThumbnailFromBuffer(src2, width, height, crop, size, params)
|
||||
}
|
||||
}
|
||||
return nil, ImageTypeUnknown, err
|
||||
}
|
||||
|
||||
imageType := vipsDetermineImageTypeFromMetaLoader(out)
|
||||
return out, imageType, nil
|
||||
}
|
||||
|
||||
// https://libvips.github.io/libvips/API/current/libvips-resample.html#vips-mapim
|
||||
func vipsMapim(in *C.VipsImage, index *C.VipsImage) (*C.VipsImage, error) {
|
||||
incOpCounter("mapim")
|
||||
var out *C.VipsImage
|
||||
|
||||
if err := C.mapim(in, &out, index); err != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// https://libvips.github.io/libvips/API/current/libvips-histogram.html#vips-maplut
|
||||
func vipsMaplut(in *C.VipsImage, lut *C.VipsImage) (*C.VipsImage, error) {
|
||||
incOpCounter("maplut")
|
||||
var out *C.VipsImage
|
||||
|
||||
if err := C.maplut(in, &out, lut); err != 0 {
|
||||
return nil, handleImageError(out)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
24
vendor/github.com/davidbyttow/govips/v2/vips/resample.h
generated
vendored
Normal file
24
vendor/github.com/davidbyttow/govips/v2/vips/resample.h
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
// https://libvips.github.io/libvips/API/current/libvips-resample.html
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <vips/vips.h>
|
||||
|
||||
int shrink_image(VipsImage *in, VipsImage **out, double xshrink,
|
||||
double yshrink);
|
||||
int reduce_image(VipsImage *in, VipsImage **out, double xshrink,
|
||||
double yshrink);
|
||||
int affine_image(VipsImage *in, VipsImage **out, double a, double b, double c,
|
||||
double d, VipsInterpolate *interpolator);
|
||||
int resize_image(VipsImage *in, VipsImage **out, double scale, gdouble vscale,
|
||||
int kernel);
|
||||
int thumbnail(const char *filename, VipsImage **out, int width, int height,
|
||||
int crop, int size);
|
||||
int thumbnail_image(VipsImage *in, VipsImage **out, int width, int height,
|
||||
int crop, int size);
|
||||
int thumbnail_buffer(void *buf, size_t len, VipsImage **out, int width, int height,
|
||||
int crop, int size);
|
||||
int thumbnail_buffer_with_option(void *buf, size_t len, VipsImage **out,
|
||||
int width, int height, int crop, int size,
|
||||
const char *option_string);
|
||||
int mapim(VipsImage *in, VipsImage **out, VipsImage *index);
|
||||
int maplut(VipsImage *in, VipsImage **out, VipsImage *lut);
|
||||
56
vendor/github.com/davidbyttow/govips/v2/vips/stats.go
generated
vendored
Normal file
56
vendor/github.com/davidbyttow/govips/v2/vips/stats.go
generated
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
package vips
|
||||
|
||||
import "sync"
|
||||
|
||||
// RuntimeStats is a data structure to house a map of govips operation counts
|
||||
type RuntimeStats struct {
|
||||
OperationCounts map[string]int64
|
||||
}
|
||||
|
||||
var (
|
||||
operationCounter chan string
|
||||
runtimeStats *RuntimeStats
|
||||
statLock sync.RWMutex
|
||||
)
|
||||
|
||||
func incOpCounter(op string) {
|
||||
if operationCounter != nil {
|
||||
operationCounter <- op
|
||||
}
|
||||
}
|
||||
|
||||
func collectStats() chan struct{} {
|
||||
operationCounter = make(chan string, 100)
|
||||
done := make(chan struct{})
|
||||
exit := false
|
||||
go func() {
|
||||
for !exit {
|
||||
select {
|
||||
case op := <-operationCounter:
|
||||
statLock.Lock()
|
||||
runtimeStats.OperationCounts[op] = runtimeStats.OperationCounts[op] + 1
|
||||
statLock.Unlock()
|
||||
case <-done:
|
||||
exit = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}()
|
||||
return done
|
||||
}
|
||||
|
||||
// ReadRuntimeStats returns operation counts for govips
|
||||
func ReadRuntimeStats(stats *RuntimeStats) {
|
||||
statLock.RLock()
|
||||
defer statLock.RUnlock()
|
||||
stats.OperationCounts = make(map[string]int64)
|
||||
for k, v := range runtimeStats.OperationCounts {
|
||||
stats.OperationCounts[k] = v
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
runtimeStats = &RuntimeStats{
|
||||
OperationCounts: make(map[string]int64),
|
||||
}
|
||||
}
|
||||
6
vendor/github.com/davidbyttow/govips/v2/vips/test_resources.go
generated
vendored
Normal file
6
vendor/github.com/davidbyttow/govips/v2/vips/test_resources.go
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
package vips
|
||||
|
||||
// relative to "/vips/.."
|
||||
const (
|
||||
resources = "../resources/"
|
||||
)
|
||||
3
vendor/modules.txt
vendored
3
vendor/modules.txt
vendored
@@ -745,6 +745,9 @@ github.com/cyphar/filepath-securejoin
|
||||
# github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc
|
||||
## explicit
|
||||
github.com/davecgh/go-spew/spew
|
||||
# github.com/davidbyttow/govips/v2 v2.15.0
|
||||
## explicit; go 1.15
|
||||
github.com/davidbyttow/govips/v2/vips
|
||||
# github.com/deckarep/golang-set v1.8.0
|
||||
## explicit; go 1.17
|
||||
github.com/deckarep/golang-set
|
||||
|
||||
Reference in New Issue
Block a user