diff --git a/go.mod b/go.mod index dd594a2faa..76c2ba5f2a 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/cenkalti/backoff v2.2.1+incompatible github.com/coreos/go-oidc/v3 v3.17.0 github.com/cs3org/go-cs3apis v0.0.0-20250908152307-4ca807afe54e - github.com/davidbyttow/govips/v2 v2.16.0 + github.com/davidbyttow/govips/v2 v2.17.0 github.com/dhowden/tag v0.0.0-20240417053706-3d75831295e8 github.com/dutchcoders/go-clamd v0.0.0-20170520113014-b970184f4d9e github.com/gabriel-vasile/mimetype v1.4.13 diff --git a/go.sum b/go.sum index 9d4f326166..108af2b341 100644 --- a/go.sum +++ b/go.sum @@ -278,8 +278,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.16.0 h1:1nH/Rbx8qZP1hd+oYL9fYQjAnm1+KorX9s07ZGseQmo= -github.com/davidbyttow/govips/v2 v2.16.0/go.mod h1:clH5/IDVmG5eVyc23qYpyi7kmOT0B/1QNTKtci4RkyM= +github.com/davidbyttow/govips/v2 v2.17.0 h1:TFAjcaEqYpumRoIz2m1Ptr9Fhdg3H0R3FKixKS+4Jo8= +github.com/davidbyttow/govips/v2 v2.17.0/go.mod h1:HF7B5oTeNolUjdBAYVIZQ8S5nhQd1CfDf0rMlYSMJv8= 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/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc= @@ -566,7 +566,6 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/go-github/v32 v32.1.0/go.mod h1:rIEpZD9CTDQwDK9GDrtMTycQNA4JU3qBsCizh3q2WCI= @@ -923,7 +922,6 @@ github.com/nats-io/nkeys v0.4.12/go.mod h1:MT59A1HYcjIcyQDJStTfaOY6vhy9XTUjOFo+S 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= @@ -1371,11 +1369,9 @@ golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= -golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1392,7 +1388,6 @@ golang.org/x/exp v0.0.0-20250210185358-939b2ce775ac h1:l5+whBCLH3iH2ZNHYLbAe58bo golang.org/x/exp v0.0.0-20250210185358-939b2ce775ac/go.mod h1:hH+7mtFmImwwcMvScyxUhjuVHR3HGaDPMn9rMSUUbxo= 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.18.0/go.mod h1:4yyo5vMFQjVjUcVk4jEQcU9MGy/rulF5WvUILseCM2E= golang.org/x/image v0.36.0 h1:Iknbfm1afbgtwPTmHnS2gTM/6PPZfH+z2EFuOkSbqwc= golang.org/x/image v0.36.0/go.mod h1:YsWD2TyyGKiIX1kZlu9QfKIsQ4nAAK9bdgdrIsE7xy4= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1416,9 +1411,6 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.32.0 h1:9F4d3PHLljb6x//jOyokMv3eX+YDeepZSEo3mFJy93c= golang.org/x/mod v0.32.0/go.mod h1:SgipZ/3h2Ci89DlEtEXWUk/HteuRin+HHhN+WbNhguU= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1469,10 +1461,8 @@ golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= -golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1498,9 +1488,6 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20180622082034-63fc586f45fe/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1584,21 +1571,17 @@ golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= -golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/term v0.40.0 h1:36e4zGLqU4yhjlmxEaagx2KuYbJq3EwY8K943ZsHcvg= golang.org/x/term v0.40.0/go.mod h1:w2P8uVp06p2iyKKuvXIm7N/y0UCRt3UfJTfZ7oOpglM= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1613,8 +1596,6 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= 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.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1677,8 +1658,6 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210112230658-8b4aab62c064/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= -golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc= golang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg= golang.org/x/tools/godoc v0.1.0-deprecated h1:o+aZ1BOj6Hsx/GBdJO/s815sqftjSnrZZwyYTHODvtk= @@ -1789,7 +1768,6 @@ 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= diff --git a/vendor/github.com/davidbyttow/govips/v2/vips/arithmetic.c b/vendor/github.com/davidbyttow/govips/v2/vips/arithmetic.c deleted file mode 100644 index 557f613cbd..0000000000 --- a/vendor/github.com/davidbyttow/govips/v2/vips/arithmetic.c +++ /dev/null @@ -1,71 +0,0 @@ -#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); -} diff --git a/vendor/github.com/davidbyttow/govips/v2/vips/arithmetic.go b/vendor/github.com/davidbyttow/govips/v2/vips/arithmetic.go deleted file mode 100644 index 3bdf5baa1d..0000000000 --- a/vendor/github.com/davidbyttow/govips/v2/vips/arithmetic.go +++ /dev/null @@ -1,176 +0,0 @@ -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 -} diff --git a/vendor/github.com/davidbyttow/govips/v2/vips/arithmetic.h b/vendor/github.com/davidbyttow/govips/v2/vips/arithmetic.h deleted file mode 100644 index 693b4fdde8..0000000000 --- a/vendor/github.com/davidbyttow/govips/v2/vips/arithmetic.h +++ /dev/null @@ -1,20 +0,0 @@ -// https://libvips.github.io/libvips/API/current/libvips-arithmetic.html - -#include -#include - -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); diff --git a/vendor/github.com/davidbyttow/govips/v2/vips/color.c b/vendor/github.com/davidbyttow/govips/v2/vips/color.c deleted file mode 100644 index 202440ee1b..0000000000 --- a/vendor/github.com/davidbyttow/govips/v2/vips/color.c +++ /dev/null @@ -1,22 +0,0 @@ -#include "color.h" -#include - -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); -} diff --git a/vendor/github.com/davidbyttow/govips/v2/vips/color.go b/vendor/github.com/davidbyttow/govips/v2/vips/color.go deleted file mode 100644 index df5aed529a..0000000000 --- a/vendor/github.com/davidbyttow/govips/v2/vips/color.go +++ /dev/null @@ -1,96 +0,0 @@ -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 -} diff --git a/vendor/github.com/davidbyttow/govips/v2/vips/color.h b/vendor/github.com/davidbyttow/govips/v2/vips/color.h deleted file mode 100644 index 0f68796a6b..0000000000 --- a/vendor/github.com/davidbyttow/govips/v2/vips/color.h +++ /dev/null @@ -1,10 +0,0 @@ -// https://libvips.github.io/libvips/API/current/libvips-colour.html - -#include -#include - -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); diff --git a/vendor/github.com/davidbyttow/govips/v2/vips/composite.go b/vendor/github.com/davidbyttow/govips/v2/vips/composite.go deleted file mode 100644 index 209870928c..0000000000 --- a/vendor/github.com/davidbyttow/govips/v2/vips/composite.go +++ /dev/null @@ -1,27 +0,0 @@ -package vips - -// #include -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 -} diff --git a/vendor/github.com/davidbyttow/govips/v2/vips/conversion.c b/vendor/github.com/davidbyttow/govips/v2/vips/conversion.c deleted file mode 100644 index 878e80818c..0000000000 --- a/vendor/github.com/davidbyttow/govips/v2/vips/conversion.c +++ /dev/null @@ -1,380 +0,0 @@ -#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); -} diff --git a/vendor/github.com/davidbyttow/govips/v2/vips/conversion.go b/vendor/github.com/davidbyttow/govips/v2/vips/conversion.go deleted file mode 100644 index 0738727d9c..0000000000 --- a/vendor/github.com/davidbyttow/govips/v2/vips/conversion.go +++ /dev/null @@ -1,520 +0,0 @@ -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 -} diff --git a/vendor/github.com/davidbyttow/govips/v2/vips/conversion.h b/vendor/github.com/davidbyttow/govips/v2/vips/conversion.h deleted file mode 100644 index ac92c5965c..0000000000 --- a/vendor/github.com/davidbyttow/govips/v2/vips/conversion.h +++ /dev/null @@ -1,70 +0,0 @@ -// https://libvips.github.io/libvips/API/current/libvips-conversion.html - -#include -#include - -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); diff --git a/vendor/github.com/davidbyttow/govips/v2/vips/convolution.c b/vendor/github.com/davidbyttow/govips/v2/vips/convolution.c deleted file mode 100644 index 48a9472bb7..0000000000 --- a/vendor/github.com/davidbyttow/govips/v2/vips/convolution.c +++ /dev/null @@ -1,14 +0,0 @@ -#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); -} diff --git a/vendor/github.com/davidbyttow/govips/v2/vips/convolution.go b/vendor/github.com/davidbyttow/govips/v2/vips/convolution.go deleted file mode 100644 index 23622767fc..0000000000 --- a/vendor/github.com/davidbyttow/govips/v2/vips/convolution.go +++ /dev/null @@ -1,40 +0,0 @@ -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 -} diff --git a/vendor/github.com/davidbyttow/govips/v2/vips/convolution.h b/vendor/github.com/davidbyttow/govips/v2/vips/convolution.h deleted file mode 100644 index 30a525ee82..0000000000 --- a/vendor/github.com/davidbyttow/govips/v2/vips/convolution.h +++ /dev/null @@ -1,9 +0,0 @@ -// https://libvips.github.io/libvips/API/current/libvips-convolution.html - -#include -#include - -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); diff --git a/vendor/github.com/davidbyttow/govips/v2/vips/create.c b/vendor/github.com/davidbyttow/govips/v2/vips/create.c deleted file mode 100644 index 1ffb7a34c1..0000000000 --- a/vendor/github.com/davidbyttow/govips/v2/vips/create.c +++ /dev/null @@ -1,24 +0,0 @@ -// 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); - } -} diff --git a/vendor/github.com/davidbyttow/govips/v2/vips/create.go b/vendor/github.com/davidbyttow/govips/v2/vips/create.go deleted file mode 100644 index 3532cf535e..0000000000 --- a/vendor/github.com/davidbyttow/govips/v2/vips/create.go +++ /dev/null @@ -1,37 +0,0 @@ -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 -} diff --git a/vendor/github.com/davidbyttow/govips/v2/vips/create.h b/vendor/github.com/davidbyttow/govips/v2/vips/create.h deleted file mode 100644 index 245d11fbaf..0000000000 --- a/vendor/github.com/davidbyttow/govips/v2/vips/create.h +++ /dev/null @@ -1,12 +0,0 @@ -// https://libvips.github.io/libvips/API/current/libvips-create.html - -// clang-format off -// include order matters -#include -#include -#include -// 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); diff --git a/vendor/github.com/davidbyttow/govips/v2/vips/draw.c b/vendor/github.com/davidbyttow/govips/v2/vips/draw.c deleted file mode 100644 index 024e18c1c0..0000000000 --- a/vendor/github.com/davidbyttow/govips/v2/vips/draw.c +++ /dev/null @@ -1,24 +0,0 @@ -#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); - } -} diff --git a/vendor/github.com/davidbyttow/govips/v2/vips/draw.go b/vendor/github.com/davidbyttow/govips/v2/vips/draw.go deleted file mode 100644 index d2ab2ad9ee..0000000000 --- a/vendor/github.com/davidbyttow/govips/v2/vips/draw.go +++ /dev/null @@ -1,21 +0,0 @@ -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 -} diff --git a/vendor/github.com/davidbyttow/govips/v2/vips/draw.h b/vendor/github.com/davidbyttow/govips/v2/vips/draw.h deleted file mode 100644 index a1c5b6f964..0000000000 --- a/vendor/github.com/davidbyttow/govips/v2/vips/draw.h +++ /dev/null @@ -1,7 +0,0 @@ -// https://libvips.github.io/libvips/API/current/libvips-draw.html - -#include -#include - -int draw_rect(VipsImage *in, double r, double g, double b, double a, int left, - int top, int width, int height, int fill); diff --git a/vendor/github.com/davidbyttow/govips/v2/vips/foreign.c b/vendor/github.com/davidbyttow/govips/v2/vips/foreign.c index 10b6b883af..0d60b664c3 100644 --- a/vendor/github.com/davidbyttow/govips/v2/vips/foreign.c +++ b/vendor/github.com/davidbyttow/govips/v2/vips/foreign.c @@ -29,50 +29,50 @@ int load_image_buffer(LoadParams *params, void *buf, size_t len, // shrink: int, fail: bool, autorotate: bool code = vips_jpegload_buffer(buf, len, out, "fail", params->fail, "autorotate", params->autorotate, "shrink", - params->jpegShrink, NULL); + params->jpegShrink, "access", params->access, NULL); } else if (imageType == PNG) { - code = vips_pngload_buffer(buf, len, out, NULL); + code = vips_pngload_buffer(buf, len, out, "access", params->access, 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); + params->n, "access", params->access, 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); + params->n, "autorotate", params->autorotate, "access", params->access, 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); + params->n, "access", params->access, 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); + params->n, "dpi", params->dpi, "access", params->access, 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); + params->svgUnlimited, "access", params->access, 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); + "autorotate", TRUE, "access", params->access, 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); + params->n, "access", params->access, 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); + "autorotate", params->autorotate, "access", params->access, 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); + code = vips_jp2kload_buffer(buf, len, out, "page", params->page, "access", params->access, NULL); } #endif @@ -100,17 +100,20 @@ 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"); + MAYBE_SET_INT(operation, params->access, "access"); return 0; } int set_pngload_options(VipsOperation *operation, LoadParams *params) { MAYBE_SET_BOOL(operation, params->fail, "fail"); + MAYBE_SET_INT(operation, params->access, "access"); return 0; } int set_webpload_options(VipsOperation *operation, LoadParams *params) { MAYBE_SET_INT(operation, params->page, "page"); MAYBE_SET_INT(operation, params->n, "n"); + MAYBE_SET_INT(operation, params->access, "access"); return 0; } @@ -118,12 +121,14 @@ 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"); + MAYBE_SET_INT(operation, params->access, "access"); return 0; } int set_gifload_options(VipsOperation *operation, LoadParams *params) { MAYBE_SET_INT(operation, params->page, "page"); MAYBE_SET_INT(operation, params->n, "n"); + MAYBE_SET_INT(operation, params->access, "access"); return 0; } @@ -131,12 +136,14 @@ 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"); + MAYBE_SET_INT(operation, params->access, "access"); return 0; } int set_svgload_options(VipsOperation *operation, LoadParams *params) { MAYBE_SET_BOOL(operation, params->svgUnlimited, "unlimited"); MAYBE_SET_DOUBLE(operation, params->dpi, "dpi"); + MAYBE_SET_INT(operation, params->access, "access"); return 0; } @@ -145,11 +152,13 @@ int set_heifload_options(VipsOperation *operation, LoadParams *params) { MAYBE_SET_BOOL(operation, params->heifThumbnail, "thumbnail"); MAYBE_SET_INT(operation, params->page, "page"); MAYBE_SET_INT(operation, params->n, "n"); + MAYBE_SET_INT(operation, params->access, "access"); return 0; } int set_jp2kload_options(VipsOperation *operation, LoadParams *params) { MAYBE_SET_INT(operation, params->page, "page"); + MAYBE_SET_INT(operation, params->access, "access"); return 0; } @@ -161,6 +170,7 @@ int set_jxlload_options(VipsOperation *operation, LoadParams *params) { int set_magickload_options(VipsOperation *operation, LoadParams *params) { MAYBE_SET_INT(operation, params->page, "page"); MAYBE_SET_INT(operation, params->n, "n"); + MAYBE_SET_INT(operation, params->access, "access"); return 0; } @@ -319,7 +329,10 @@ int set_tiffsave_options(VipsOperation *operation, SaveParams *params) { // 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); + int ret = vips_object_set(VIPS_OBJECT(operation), "format", params->magickFormat, + "optimize_gif_frames", params->magickOptimizeGifFrames, + "optimize_gif_transparency", params->magickOptimizeGifTransparency, + "bitdepth", params->magickBitDepth, NULL); if (!ret && params->quality) { ret = vips_object_set(VIPS_OBJECT(operation), "quality", params->quality, @@ -481,6 +494,11 @@ int save_to_buffer(SaveParams *params) { #if (VIPS_MAJOR_VERSION >= 8) && (VIPS_MINOR_VERSION >= 12) return save_buffer("gifsave_buffer", params, set_gifsave_options); #else + // Gif save through ImageMagick below Vips Version 8.12 + params->magickFormat="GIF"; + params->magickOptimizeGifFrames=FALSE; + params->magickOptimizeGifTransparency=FALSE; + params->magickBitDepth=params->gifBitdepth; return save_buffer("magicksave_buffer", params, set_magicksave_options); #endif case AVIF: @@ -489,6 +507,8 @@ int save_to_buffer(SaveParams *params) { return save_buffer("jp2ksave_buffer", params, set_jp2ksave_options); case JXL: return save_buffer("jxlsave_buffer", params, set_jxlsave_options); + case MAGICK: + return save_buffer("magicksave_buffer", params, set_magicksave_options); default: g_warning("Unsupported output type given: %d", params->outputFormat); } @@ -509,6 +529,7 @@ LoadParams create_load_params(ImageType inputFormat) { .jpegShrink = defaultParam, .heifThumbnail = defaultParam, .svgUnlimited = defaultParam, + .access = defaultParam, }; return p; } diff --git a/vendor/github.com/davidbyttow/govips/v2/vips/foreign.go b/vendor/github.com/davidbyttow/govips/v2/vips/foreign.go index cfa4ddddeb..08762af2f5 100644 --- a/vendor/github.com/davidbyttow/govips/v2/vips/foreign.go +++ b/vendor/github.com/davidbyttow/govips/v2/vips/foreign.go @@ -5,13 +5,13 @@ import "C" import ( "bytes" "encoding/xml" + "errors" "fmt" - "golang.org/x/image/bmp" - "golang.org/x/net/html/charset" - "image/png" "math" "runtime" "unsafe" + + "golang.org/x/net/html/charset" ) // SubsampleMode correlates to a libvips subsample mode @@ -44,8 +44,15 @@ const ( ImageTypeAVIF ImageType = C.AVIF ImageTypeJP2K ImageType = C.JP2K ImageTypeJXL ImageType = C.JXL + ImageTypePSD ImageType = C.PSD ) +// Types which should be deligated to ImageMagick loader +var imageMagickTypes = map[ImageType]bool{ + ImageTypeBMP: true, + ImageTypePSD: true, +} + var imageTypeExtensionMap = map[ImageType]string{ ImageTypeGIF: ".gif", ImageTypeJPEG: ".jpeg", @@ -60,6 +67,7 @@ var imageTypeExtensionMap = map[ImageType]string{ ImageTypeAVIF: ".avif", ImageTypeJP2K: ".jp2", ImageTypeJXL: ".jxl", + ImageTypePSD: ".psd", } // ImageTypes defines the various image types supported by govips @@ -77,6 +85,7 @@ var ImageTypes = map[ImageType]string{ ImageTypeAVIF: "heif", ImageTypeJP2K: "jp2k", ImageTypeJXL: "jxl", + ImageTypePSD: "psd", } // TiffCompression represents method for compressing a tiff at export @@ -118,6 +127,15 @@ const ( PngFilterAll PngFilter = C.VIPS_FOREIGN_PNG_FILTER_ALL ) +// Access represents how libvips opens files. +// See https://www.libvips.org/API/current/How-it-opens-files.html +const ( + AccessRandom int = C.VIPS_ACCESS_RANDOM + AccessSequential int = C.VIPS_ACCESS_SEQUENTIAL + AccessSequentialUnbuffered int = C.VIPS_ACCESS_SEQUENTIAL_UNBUFFERED + AccessLast int = C.VIPS_ACCESS_LAST +) + // FileExt returns the canonical extension for the ImageType func (i ImageType) FileExt() string { if ext, ok := imageTypeExtensionMap[i]; ok { @@ -130,6 +148,11 @@ func (i ImageType) FileExt() string { func IsTypeSupported(imageType ImageType) bool { startupIfNeeded() + // BMP is supported via the magick loader + if imageType == ImageTypeBMP { + return supportedImageTypes[ImageTypeMagick] + } + return supportedImageTypes[imageType] } @@ -161,6 +184,10 @@ func DetermineImageType(buf []byte) ImageType { return ImageTypeJXL } else if isPDF(buf) { return ImageTypePDF + } else if isICO(buf) { + return ImageTypeMagick + } else if isPSD(buf) { + return ImageTypePSD } else { return ImageTypeUnknown } @@ -200,12 +227,18 @@ func isWEBP(buf []byte) bool { // https://github.com/strukturag/libheif/blob/master/libheif/heif.cc var ftyp = []byte("ftyp") var heic = []byte("heic") +var heix = []byte("heix") +var heim = []byte("heim") +var heis = []byte("heis") 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], heix) || + bytes.Equal(buf[8:12], heim) || + bytes.Equal(buf[8:12], heis) || bytes.Equal(buf[8:12], mif1) || bytes.Equal(buf[8:12], msf1)) || isAVIF(buf) @@ -266,7 +299,29 @@ var jxlHeader = []byte("\xff\x0a") var jxlHeaderISOBMFF = []byte("\x00\x00\x00\x0C\x4A\x58\x4C\x20\x0D\x0A\x87\x0A") func isJXL(buf []byte) bool { - return bytes.HasPrefix(buf, jxlHeader) || bytes.HasPrefix(buf, jxlHeaderISOBMFF) + if len(buf) >= 2 && buf[0] == 0xFF && buf[1] == 0x0A { + return true + } + if len(buf) >= 8 && bytes.Equal(buf[4:8], []byte("JXL ")) { + return true + } + return false +} + +var icoHeader = []byte("\x00\x00\x01\x00") + +func isICO(buf []byte) bool { + return bytes.HasPrefix(buf, icoHeader) +} + +var psdHeader = []byte("\x38\x42\x50\x53") + +func isPSD(buf []byte) bool { + return bytes.HasPrefix(buf, psdHeader) +} + +func isNeedToChangeLoaderToMagick(t ImageType) bool { + return imageMagickTypes[t] } func vipsLoadFromBuffer(buf []byte, params *ImportParams) (*C.VipsImage, ImageType, ImageType, error) { @@ -274,18 +329,12 @@ func vipsLoadFromBuffer(buf []byte, params *ImportParams) (*C.VipsImage, ImageTy // 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 + // Map image types which are not supported by libvips itself to ImageMagick + if isNeedToChangeLoaderToMagick(originalType) { + currentType = ImageTypeMagick } if !IsTypeSupported(currentType) { @@ -302,24 +351,6 @@ func vipsLoadFromBuffer(buf []byte, params *ImportParams) (*C.VipsImage, ImageTy 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())) @@ -342,6 +373,7 @@ func createImportParams(format ImageType, params *ImportParams) C.LoadParams { maybeSetIntParam(params.JpegShrinkFactor, &p.jpegShrink) maybeSetBoolParam(params.HeifThumbnail, &p.heifThumbnail) maybeSetBoolParam(params.SvgUnlimited, &p.svgUnlimited) + maybeSetIntParam(params.Access, &p.access) if params.Density.IsSet() { C.set_double_param(&p.dpi, C.gdouble(params.Density.Get())) @@ -416,8 +448,16 @@ func vipsSaveTIFFToBuffer(in *C.VipsImage, params TiffExportParams) ([]byte, err p.tiffCompression = C.VipsForeignTiffCompression(params.Compression) p.tiffPyramid = C.int(boolToInt(params.Pyramid)) p.tiffTile = C.int(boolToInt(params.Tile)) - p.tiffTileHeight = C.int(params.TileHeight) - p.tiffTileWidth = C.int(params.TileWidth) + tileHeight := params.TileHeight + tileWidth := params.TileWidth + if tileHeight <= 0 { + tileHeight = 256 + } + if tileWidth <= 0 { + tileWidth = 256 + } + p.tiffTileHeight = C.int(tileHeight) + p.tiffTileWidth = C.int(tileWidth) return vipsSaveToBuffer(p) } @@ -500,6 +540,24 @@ func vipsSaveJxlToBuffer(in *C.VipsImage, params JxlExportParams) ([]byte, error return vipsSaveToBuffer(p) } +func vipsSaveMagickToBuffer(in *C.VipsImage, params MagickExportParams) ([]byte, error) { + incOpCounter("save_magick_buffer") + + if params.Format == "" { + return nil, errors.New("magick format required") + } + p := C.create_save_params(C.MAGICK) + p.inputImage = in + p.outputFormat = C.MAGICK + p.quality = C.int(params.Quality) + p.magickFormat = C.CString(params.Format) + p.magickOptimizeGifFrames = C.int(boolToInt(params.OptimizeGifFrames)) + p.magickOptimizeGifTransparency = C.int(boolToInt(params.OptimizeGifTransparency)) + p.magickBitDepth = C.int(params.BitDepth) + + 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) diff --git a/vendor/github.com/davidbyttow/govips/v2/vips/foreign.h b/vendor/github.com/davidbyttow/govips/v2/vips/foreign.h index e54b946ceb..64da424343 100644 --- a/vendor/github.com/davidbyttow/govips/v2/vips/foreign.h +++ b/vendor/github.com/davidbyttow/govips/v2/vips/foreign.h @@ -26,7 +26,8 @@ typedef enum types { BMP, AVIF, JP2K, - JXL + JXL, + PSD, } ImageType; typedef enum ParamType { @@ -66,6 +67,7 @@ typedef struct LoadParams { Param jpegShrink; Param heifThumbnail; Param svgUnlimited; + Param access; } LoadParams; @@ -134,6 +136,12 @@ typedef struct SaveParams { double jxlDistance; int jxlEffort; BOOL jxlLossless; + + // MAGICK + char *magickFormat; + BOOL magickOptimizeGifFrames; + BOOL magickOptimizeGifTransparency; + int magickBitDepth; } SaveParams; SaveParams create_save_params(ImageType outputFormat); diff --git a/vendor/github.com/davidbyttow/govips/v2/vips/gen_enum_extras.go b/vendor/github.com/davidbyttow/govips/v2/vips/gen_enum_extras.go new file mode 100644 index 0000000000..2e739a82fd --- /dev/null +++ b/vendor/github.com/davidbyttow/govips/v2/vips/gen_enum_extras.go @@ -0,0 +1,139 @@ +// Code generated by vipsgen. DO NOT EDIT. +// +// Enum types needed by generated code that are not yet defined in the +// hand-written codebase. These will move to gen_enums.go in Phase 4. + +package vips + +// #include +import "C" + +// Precision represents VipsPrecision for controlling computation precision. +type Precision int + +const ( + PrecisionInteger Precision = C.VIPS_PRECISION_INTEGER + PrecisionFloat Precision = C.VIPS_PRECISION_FLOAT + PrecisionApproximate Precision = C.VIPS_PRECISION_APPROXIMATE +) + +// Combine represents VipsCombine for combining operations. +type Combine int + +const ( + CombineMax Combine = C.VIPS_COMBINE_MAX + CombineSum Combine = C.VIPS_COMBINE_SUM + CombineMin Combine = C.VIPS_COMBINE_MIN +) + +// CombineMode represents VipsCombineMode for draw combine operations. +type CombineMode int + +const ( + CombineModeSet CombineMode = C.VIPS_COMBINE_MODE_SET + CombineModeAdd CombineMode = C.VIPS_COMBINE_MODE_ADD +) + +// OperationBoolean represents VipsOperationBoolean for boolean operations. +type OperationBoolean int + +const ( + OperationBooleanAnd OperationBoolean = C.VIPS_OPERATION_BOOLEAN_AND + OperationBooleanOr OperationBoolean = C.VIPS_OPERATION_BOOLEAN_OR + OperationBooleanEor OperationBoolean = C.VIPS_OPERATION_BOOLEAN_EOR + OperationBooleanLshift OperationBoolean = C.VIPS_OPERATION_BOOLEAN_LSHIFT + OperationBooleanRshift OperationBoolean = C.VIPS_OPERATION_BOOLEAN_RSHIFT +) + +// OperationComplex represents VipsOperationComplex for complex operations. +type OperationComplex int + +const ( + OperationComplexPolar OperationComplex = C.VIPS_OPERATION_COMPLEX_POLAR + OperationComplexRect OperationComplex = C.VIPS_OPERATION_COMPLEX_RECT + OperationComplexConj OperationComplex = C.VIPS_OPERATION_COMPLEX_CONJ +) + +// OperationComplex2 represents VipsOperationComplex2 for binary complex operations. +type OperationComplex2 int + +const ( + OperationComplex2CrossPhase OperationComplex2 = C.VIPS_OPERATION_COMPLEX2_CROSS_PHASE +) + +// OperationComplexget represents VipsOperationComplexget for getting complex components. +type OperationComplexget int + +const ( + OperationComplexgetReal OperationComplexget = C.VIPS_OPERATION_COMPLEXGET_REAL + OperationComplexgetImag OperationComplexget = C.VIPS_OPERATION_COMPLEXGET_IMAG +) + +// OperationMath represents VipsOperationMath for math operations. +type OperationMath int + +const ( + OperationMathSin OperationMath = C.VIPS_OPERATION_MATH_SIN + OperationMathCos OperationMath = C.VIPS_OPERATION_MATH_COS + OperationMathTan OperationMath = C.VIPS_OPERATION_MATH_TAN + OperationMathAsin OperationMath = C.VIPS_OPERATION_MATH_ASIN + OperationMathAcos OperationMath = C.VIPS_OPERATION_MATH_ACOS + OperationMathAtan OperationMath = C.VIPS_OPERATION_MATH_ATAN + OperationMathLog OperationMath = C.VIPS_OPERATION_MATH_LOG + OperationMathLog10 OperationMath = C.VIPS_OPERATION_MATH_LOG10 + OperationMathExp OperationMath = C.VIPS_OPERATION_MATH_EXP + OperationMathExp10 OperationMath = C.VIPS_OPERATION_MATH_EXP10 +) + +// OperationMath2 represents VipsOperationMath2 for binary math operations. +type OperationMath2 int + +const ( + OperationMath2Pow OperationMath2 = C.VIPS_OPERATION_MATH2_POW + OperationMath2Wop OperationMath2 = C.VIPS_OPERATION_MATH2_WOP + OperationMath2Atan2 OperationMath2 = C.VIPS_OPERATION_MATH2_ATAN2 +) + +// OperationRelational represents VipsOperationRelational for relational operations. +type OperationRelational int + +const ( + OperationRelationalEqual OperationRelational = C.VIPS_OPERATION_RELATIONAL_EQUAL + OperationRelationalNoteq OperationRelational = C.VIPS_OPERATION_RELATIONAL_NOTEQ + OperationRelationalLess OperationRelational = C.VIPS_OPERATION_RELATIONAL_LESS + OperationRelationalLesseq OperationRelational = C.VIPS_OPERATION_RELATIONAL_LESSEQ + OperationRelationalMore OperationRelational = C.VIPS_OPERATION_RELATIONAL_MORE + OperationRelationalMoreeq OperationRelational = C.VIPS_OPERATION_RELATIONAL_MOREEQ +) + +// OperationRound represents VipsOperationRound for rounding operations. +type OperationRound int + +const ( + OperationRoundRint OperationRound = C.VIPS_OPERATION_ROUND_RINT + OperationRoundCeil OperationRound = C.VIPS_OPERATION_ROUND_CEIL + OperationRoundFloor OperationRound = C.VIPS_OPERATION_ROUND_FLOOR +) + +// OperationMorphology represents VipsOperationMorphology for morphological operations. +type OperationMorphology int + +const ( + OperationMorphologyErode OperationMorphology = C.VIPS_OPERATION_MORPHOLOGY_ERODE + OperationMorphologyDilate OperationMorphology = C.VIPS_OPERATION_MORPHOLOGY_DILATE +) + +// FailOn represents VipsFailOn for controlling error handling on load. +type FailOn int + +const ( + FailOnNone FailOn = C.VIPS_FAIL_ON_NONE + FailOnTruncated FailOn = C.VIPS_FAIL_ON_TRUNCATED + FailOnError FailOn = C.VIPS_FAIL_ON_ERROR + FailOnWarning FailOn = C.VIPS_FAIL_ON_WARNING +) + +// ForeignKeep represents VipsForeignKeep flags for controlling metadata retention. +type ForeignKeep int + +// Note: ForeignKeep is a flags (bitmask) type. Values combined with |. diff --git a/vendor/github.com/davidbyttow/govips/v2/vips/generate.go b/vendor/github.com/davidbyttow/govips/v2/vips/generate.go new file mode 100644 index 0000000000..52c946aae9 --- /dev/null +++ b/vendor/github.com/davidbyttow/govips/v2/vips/generate.go @@ -0,0 +1,3 @@ +package vips + +//go:generate go run ../cmd/vipsgen --generate --output=. diff --git a/vendor/github.com/davidbyttow/govips/v2/vips/generated.c b/vendor/github.com/davidbyttow/govips/v2/vips/generated.c new file mode 100644 index 0000000000..c981daa4c2 --- /dev/null +++ b/vendor/github.com/davidbyttow/govips/v2/vips/generated.c @@ -0,0 +1,5228 @@ +// Code generated by vipsgen. DO NOT EDIT. +#include "generated.h" + +int gen_vips_CMC2LCh(VipsImage * input, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("CMC2LCh"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_CMYK2XYZ(VipsImage * input, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("CMYK2XYZ"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_HSV2sRGB(VipsImage * input, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("HSV2sRGB"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_LCh2CMC(VipsImage * input, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("LCh2CMC"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_LCh2Lab(VipsImage * input, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("LCh2Lab"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_Lab2LCh(VipsImage * input, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("Lab2LCh"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_Lab2LabQ(VipsImage * input, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("Lab2LabQ"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_Lab2LabS(VipsImage * input, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("Lab2LabS"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_Lab2XYZ(VipsImage * input, VipsImage ** out_out, GenLab2XYZOpts *opts) { + VipsOperation *op = vips_operation_new("Lab2XYZ"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (opts) { + if (opts->has_temp) { + { + VipsArrayDouble *arr = vips_array_double_new(opts->temp, opts->temp_n); + vips_object_set(VIPS_OBJECT(op), "temp", arr, NULL); + vips_area_unref(VIPS_AREA(arr)); + } + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_LabQ2Lab(VipsImage * input, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("LabQ2Lab"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_LabQ2LabS(VipsImage * input, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("LabQ2LabS"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_LabQ2sRGB(VipsImage * input, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("LabQ2sRGB"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_LabS2Lab(VipsImage * input, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("LabS2Lab"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_LabS2LabQ(VipsImage * input, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("LabS2LabQ"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_Oklab2Oklch(VipsImage * input, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("Oklab2Oklch"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_Oklab2XYZ(VipsImage * input, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("Oklab2XYZ"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_Oklch2Oklab(VipsImage * input, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("Oklch2Oklab"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_XYZ2CMYK(VipsImage * input, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("XYZ2CMYK"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_XYZ2Lab(VipsImage * input, VipsImage ** out_out, GenXYZ2LabOpts *opts) { + VipsOperation *op = vips_operation_new("XYZ2Lab"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (opts) { + if (opts->has_temp) { + { + VipsArrayDouble *arr = vips_array_double_new(opts->temp, opts->temp_n); + vips_object_set(VIPS_OBJECT(op), "temp", arr, NULL); + vips_area_unref(VIPS_AREA(arr)); + } + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_XYZ2Oklab(VipsImage * input, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("XYZ2Oklab"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_XYZ2Yxy(VipsImage * input, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("XYZ2Yxy"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_XYZ2scRGB(VipsImage * input, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("XYZ2scRGB"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_Yxy2XYZ(VipsImage * input, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("Yxy2XYZ"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_abs(VipsImage * input, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("abs"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_add(VipsImage * left, VipsImage * right, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("add"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "left", left, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "right", right, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_affine(VipsImage * input, double * matrix, int matrix_n, VipsImage ** out_out, GenAffineOpts *opts) { + VipsOperation *op = vips_operation_new("affine"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + { + VipsArrayDouble *arr = vips_array_double_new(matrix, matrix_n); + int ret = vips_object_set(VIPS_OBJECT(op), "matrix", arr, NULL); + vips_area_unref(VIPS_AREA(arr)); + if (ret) goto error; + } + + if (opts) { + if (opts->has_interpolate) { + vips_object_set(VIPS_OBJECT(op), "interpolate", opts->interpolate, NULL); + } + if (opts->has_oarea) { + { + VipsArrayInt *arr = vips_array_int_new(opts->oarea, opts->oarea_n); + vips_object_set(VIPS_OBJECT(op), "oarea", arr, NULL); + vips_area_unref(VIPS_AREA(arr)); + } + } + if (opts->has_odx) { + vips_object_set(VIPS_OBJECT(op), "odx", opts->odx, NULL); + } + if (opts->has_ody) { + vips_object_set(VIPS_OBJECT(op), "ody", opts->ody, NULL); + } + if (opts->has_idx) { + vips_object_set(VIPS_OBJECT(op), "idx", opts->idx, NULL); + } + if (opts->has_idy) { + vips_object_set(VIPS_OBJECT(op), "idy", opts->idy, NULL); + } + if (opts->has_background) { + { + VipsArrayDouble *arr = vips_array_double_new(opts->background, opts->background_n); + vips_object_set(VIPS_OBJECT(op), "background", arr, NULL); + vips_area_unref(VIPS_AREA(arr)); + } + } + if (opts->has_premultiplied) { + vips_object_set(VIPS_OBJECT(op), "premultiplied", (gboolean)opts->premultiplied, NULL); + } + if (opts->has_extend) { + vips_object_set(VIPS_OBJECT(op), "extend", (int)opts->extend, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_arrayjoin(VipsImage **input, int input_n, VipsImage ** out_out, GenArrayjoinOpts *opts) { + VipsOperation *op = vips_operation_new("arrayjoin"); + if (!op) return -1; + + { + VipsArrayImage *arr = vips_array_image_new(input, input_n); + int ret = vips_object_set(VIPS_OBJECT(op), "in", arr, NULL); + vips_area_unref(VIPS_AREA(arr)); + if (ret) goto error; + } + + if (opts) { + if (opts->has_across) { + vips_object_set(VIPS_OBJECT(op), "across", opts->across, NULL); + } + if (opts->has_shim) { + vips_object_set(VIPS_OBJECT(op), "shim", opts->shim, NULL); + } + if (opts->has_background) { + { + VipsArrayDouble *arr = vips_array_double_new(opts->background, opts->background_n); + vips_object_set(VIPS_OBJECT(op), "background", arr, NULL); + vips_area_unref(VIPS_AREA(arr)); + } + } + if (opts->has_halign) { + vips_object_set(VIPS_OBJECT(op), "halign", (int)opts->halign, NULL); + } + if (opts->has_valign) { + vips_object_set(VIPS_OBJECT(op), "valign", (int)opts->valign, NULL); + } + if (opts->has_hspacing) { + vips_object_set(VIPS_OBJECT(op), "hspacing", opts->hspacing, NULL); + } + if (opts->has_vspacing) { + vips_object_set(VIPS_OBJECT(op), "vspacing", opts->vspacing, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_autorot(VipsImage * input, VipsImage ** out_out, int * out_angle, int * out_flip) { + VipsOperation *op = vips_operation_new("autorot"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + g_object_get(VIPS_OBJECT(op), "angle", out_angle, NULL); + g_object_get(VIPS_OBJECT(op), "flip", out_flip, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_avg(VipsImage * input, double * out_out) { + VipsOperation *op = vips_operation_new("avg"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_bandbool(VipsImage * input, VipsOperationBoolean boolean, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("bandbool"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "boolean", (int)boolean, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_bandfold(VipsImage * input, VipsImage ** out_out, GenBandfoldOpts *opts) { + VipsOperation *op = vips_operation_new("bandfold"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (opts) { + if (opts->has_factor) { + vips_object_set(VIPS_OBJECT(op), "factor", opts->factor, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_bandjoin(VipsImage **input, int input_n, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("bandjoin"); + if (!op) return -1; + + { + VipsArrayImage *arr = vips_array_image_new(input, input_n); + int ret = vips_object_set(VIPS_OBJECT(op), "in", arr, NULL); + vips_area_unref(VIPS_AREA(arr)); + if (ret) goto error; + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_bandjoin_const(VipsImage * input, double * c, int c_n, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("bandjoin_const"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + { + VipsArrayDouble *arr = vips_array_double_new(c, c_n); + int ret = vips_object_set(VIPS_OBJECT(op), "c", arr, NULL); + vips_area_unref(VIPS_AREA(arr)); + if (ret) goto error; + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_bandmean(VipsImage * input, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("bandmean"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_bandrank(VipsImage **input, int input_n, VipsImage ** out_out, GenBandrankOpts *opts) { + VipsOperation *op = vips_operation_new("bandrank"); + if (!op) return -1; + + { + VipsArrayImage *arr = vips_array_image_new(input, input_n); + int ret = vips_object_set(VIPS_OBJECT(op), "in", arr, NULL); + vips_area_unref(VIPS_AREA(arr)); + if (ret) goto error; + } + + if (opts) { + if (opts->has_index) { + vips_object_set(VIPS_OBJECT(op), "index", opts->index, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_bandunfold(VipsImage * input, VipsImage ** out_out, GenBandunfoldOpts *opts) { + VipsOperation *op = vips_operation_new("bandunfold"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (opts) { + if (opts->has_factor) { + vips_object_set(VIPS_OBJECT(op), "factor", opts->factor, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_black(int width, int height, VipsImage ** out_out, GenBlackOpts *opts) { + VipsOperation *op = vips_operation_new("black"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "width", width, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "height", height, NULL)) goto error; + + if (opts) { + if (opts->has_bands) { + vips_object_set(VIPS_OBJECT(op), "bands", opts->bands, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_boolean(VipsImage * left, VipsImage * right, VipsOperationBoolean boolean, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("boolean"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "left", left, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "right", right, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "boolean", (int)boolean, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_boolean_const(VipsImage * input, VipsOperationBoolean boolean, double * c, int c_n, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("boolean_const"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "boolean", (int)boolean, NULL)) goto error; + { + VipsArrayDouble *arr = vips_array_double_new(c, c_n); + int ret = vips_object_set(VIPS_OBJECT(op), "c", arr, NULL); + vips_area_unref(VIPS_AREA(arr)); + if (ret) goto error; + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_buildlut(VipsImage * input, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("buildlut"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_byteswap(VipsImage * input, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("byteswap"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_cache(VipsImage * input, VipsImage ** out_out, GenCacheOpts *opts) { + VipsOperation *op = vips_operation_new("cache"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (opts) { + if (opts->has_maxTiles) { + vips_object_set(VIPS_OBJECT(op), "max-tiles", opts->maxTiles, NULL); + } + if (opts->has_tileHeight) { + vips_object_set(VIPS_OBJECT(op), "tile-height", opts->tileHeight, NULL); + } + if (opts->has_tileWidth) { + vips_object_set(VIPS_OBJECT(op), "tile-width", opts->tileWidth, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_canny(VipsImage * input, VipsImage ** out_out, GenCannyOpts *opts) { + VipsOperation *op = vips_operation_new("canny"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (opts) { + if (opts->has_sigma) { + vips_object_set(VIPS_OBJECT(op), "sigma", opts->sigma, NULL); + } + if (opts->has_precision) { + vips_object_set(VIPS_OBJECT(op), "precision", (int)opts->precision, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_cast(VipsImage * input, VipsBandFormat format, VipsImage ** out_out, GenCastOpts *opts) { + VipsOperation *op = vips_operation_new("cast"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "format", (int)format, NULL)) goto error; + + if (opts) { + if (opts->has_shift) { + vips_object_set(VIPS_OBJECT(op), "shift", (gboolean)opts->shift, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_clamp(VipsImage * input, VipsImage ** out_out, GenClampOpts *opts) { + VipsOperation *op = vips_operation_new("clamp"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (opts) { + if (opts->has_min) { + vips_object_set(VIPS_OBJECT(op), "min", opts->min, NULL); + } + if (opts->has_max) { + vips_object_set(VIPS_OBJECT(op), "max", opts->max, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_compass(VipsImage * input, VipsImage * mask, VipsImage ** out_out, GenCompassOpts *opts) { + VipsOperation *op = vips_operation_new("compass"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "mask", mask, NULL)) goto error; + + if (opts) { + if (opts->has_times) { + vips_object_set(VIPS_OBJECT(op), "times", opts->times, NULL); + } + if (opts->has_angle) { + vips_object_set(VIPS_OBJECT(op), "angle", (int)opts->angle, NULL); + } + if (opts->has_combine) { + vips_object_set(VIPS_OBJECT(op), "combine", (int)opts->combine, NULL); + } + if (opts->has_precision) { + vips_object_set(VIPS_OBJECT(op), "precision", (int)opts->precision, NULL); + } + if (opts->has_layers) { + vips_object_set(VIPS_OBJECT(op), "layers", opts->layers, NULL); + } + if (opts->has_cluster) { + vips_object_set(VIPS_OBJECT(op), "cluster", opts->cluster, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_complex(VipsImage * input, VipsOperationComplex cmplx, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("complex"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "cmplx", (int)cmplx, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_complex2(VipsImage * left, VipsImage * right, VipsOperationComplex2 cmplx, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("complex2"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "left", left, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "right", right, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "cmplx", (int)cmplx, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_complexform(VipsImage * left, VipsImage * right, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("complexform"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "left", left, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "right", right, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_complexget(VipsImage * input, VipsOperationComplexget get, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("complexget"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "get", (int)get, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_composite2(VipsImage * base, VipsImage * overlay, VipsBlendMode mode, VipsImage ** out_out, GenComposite2Opts *opts) { + VipsOperation *op = vips_operation_new("composite2"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "base", base, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "overlay", overlay, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "mode", (int)mode, NULL)) goto error; + + if (opts) { + if (opts->has_x) { + vips_object_set(VIPS_OBJECT(op), "x", opts->x, NULL); + } + if (opts->has_y) { + vips_object_set(VIPS_OBJECT(op), "y", opts->y, NULL); + } + if (opts->has_compositingSpace) { + vips_object_set(VIPS_OBJECT(op), "compositing-space", (int)opts->compositingSpace, NULL); + } + if (opts->has_premultiplied) { + vips_object_set(VIPS_OBJECT(op), "premultiplied", (gboolean)opts->premultiplied, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_conv(VipsImage * input, VipsImage * mask, VipsImage ** out_out, GenConvOpts *opts) { + VipsOperation *op = vips_operation_new("conv"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "mask", mask, NULL)) goto error; + + if (opts) { + if (opts->has_precision) { + vips_object_set(VIPS_OBJECT(op), "precision", (int)opts->precision, NULL); + } + if (opts->has_layers) { + vips_object_set(VIPS_OBJECT(op), "layers", opts->layers, NULL); + } + if (opts->has_cluster) { + vips_object_set(VIPS_OBJECT(op), "cluster", opts->cluster, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_conva(VipsImage * input, VipsImage * mask, VipsImage ** out_out, GenConvaOpts *opts) { + VipsOperation *op = vips_operation_new("conva"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "mask", mask, NULL)) goto error; + + if (opts) { + if (opts->has_layers) { + vips_object_set(VIPS_OBJECT(op), "layers", opts->layers, NULL); + } + if (opts->has_cluster) { + vips_object_set(VIPS_OBJECT(op), "cluster", opts->cluster, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_convasep(VipsImage * input, VipsImage * mask, VipsImage ** out_out, GenConvasepOpts *opts) { + VipsOperation *op = vips_operation_new("convasep"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "mask", mask, NULL)) goto error; + + if (opts) { + if (opts->has_layers) { + vips_object_set(VIPS_OBJECT(op), "layers", opts->layers, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_convf(VipsImage * input, VipsImage * mask, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("convf"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "mask", mask, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_convi(VipsImage * input, VipsImage * mask, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("convi"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "mask", mask, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_convsep(VipsImage * input, VipsImage * mask, VipsImage ** out_out, GenConvsepOpts *opts) { + VipsOperation *op = vips_operation_new("convsep"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "mask", mask, NULL)) goto error; + + if (opts) { + if (opts->has_precision) { + vips_object_set(VIPS_OBJECT(op), "precision", (int)opts->precision, NULL); + } + if (opts->has_layers) { + vips_object_set(VIPS_OBJECT(op), "layers", opts->layers, NULL); + } + if (opts->has_cluster) { + vips_object_set(VIPS_OBJECT(op), "cluster", opts->cluster, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_copy(VipsImage * input, VipsImage ** out_out, GenCopyOpts *opts) { + VipsOperation *op = vips_operation_new("copy"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (opts) { + if (opts->has_width) { + vips_object_set(VIPS_OBJECT(op), "width", opts->width, NULL); + } + if (opts->has_height) { + vips_object_set(VIPS_OBJECT(op), "height", opts->height, NULL); + } + if (opts->has_bands) { + vips_object_set(VIPS_OBJECT(op), "bands", opts->bands, NULL); + } + if (opts->has_format) { + vips_object_set(VIPS_OBJECT(op), "format", (int)opts->format, NULL); + } + if (opts->has_coding) { + vips_object_set(VIPS_OBJECT(op), "coding", (int)opts->coding, NULL); + } + if (opts->has_interpretation) { + vips_object_set(VIPS_OBJECT(op), "interpretation", (int)opts->interpretation, NULL); + } + if (opts->has_xres) { + vips_object_set(VIPS_OBJECT(op), "xres", opts->xres, NULL); + } + if (opts->has_yres) { + vips_object_set(VIPS_OBJECT(op), "yres", opts->yres, NULL); + } + if (opts->has_xoffset) { + vips_object_set(VIPS_OBJECT(op), "xoffset", opts->xoffset, NULL); + } + if (opts->has_yoffset) { + vips_object_set(VIPS_OBJECT(op), "yoffset", opts->yoffset, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_countlines(VipsImage * input, VipsDirection direction, double * out_nolines) { + VipsOperation *op = vips_operation_new("countlines"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "direction", (int)direction, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "nolines", out_nolines, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_dE00(VipsImage * left, VipsImage * right, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("dE00"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "left", left, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "right", right, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_dE76(VipsImage * left, VipsImage * right, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("dE76"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "left", left, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "right", right, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_dECMC(VipsImage * left, VipsImage * right, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("dECMC"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "left", left, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "right", right, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_deviate(VipsImage * input, double * out_out) { + VipsOperation *op = vips_operation_new("deviate"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_divide(VipsImage * left, VipsImage * right, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("divide"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "left", left, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "right", right, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_extract_area(VipsImage * input, int left, int top, int width, int height, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("extract_area"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "input", input, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "left", left, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "top", top, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "width", width, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "height", height, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_extract_band(VipsImage * input, int band, VipsImage ** out_out, GenExtractBandOpts *opts) { + VipsOperation *op = vips_operation_new("extract_band"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "band", band, NULL)) goto error; + + if (opts) { + if (opts->has_n) { + vips_object_set(VIPS_OBJECT(op), "n", opts->n, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_eye(int width, int height, VipsImage ** out_out, GenEyeOpts *opts) { + VipsOperation *op = vips_operation_new("eye"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "width", width, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "height", height, NULL)) goto error; + + if (opts) { + if (opts->has_uchar) { + vips_object_set(VIPS_OBJECT(op), "uchar", (gboolean)opts->uchar, NULL); + } + if (opts->has_factor) { + vips_object_set(VIPS_OBJECT(op), "factor", opts->factor, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_falsecolour(VipsImage * input, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("falsecolour"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_fastcor(VipsImage * input, VipsImage * ref, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("fastcor"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "ref", ref, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_fill_nearest(VipsImage * input, VipsImage ** out_out, VipsImage ** out_distance) { + VipsOperation *op = vips_operation_new("fill_nearest"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + g_object_get(VIPS_OBJECT(op), "distance", out_distance, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_flatten(VipsImage * input, VipsImage ** out_out, GenFlattenOpts *opts) { + VipsOperation *op = vips_operation_new("flatten"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (opts) { + if (opts->has_background) { + { + VipsArrayDouble *arr = vips_array_double_new(opts->background, opts->background_n); + vips_object_set(VIPS_OBJECT(op), "background", arr, NULL); + vips_area_unref(VIPS_AREA(arr)); + } + } + if (opts->has_maxAlpha) { + vips_object_set(VIPS_OBJECT(op), "max-alpha", opts->maxAlpha, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_flip(VipsImage * input, VipsDirection direction, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("flip"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "direction", (int)direction, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_float2rad(VipsImage * input, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("float2rad"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_fractsurf(int width, int height, double fractalDimension, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("fractsurf"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "width", width, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "height", height, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "fractal-dimension", fractalDimension, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_freqmult(VipsImage * input, VipsImage * mask, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("freqmult"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "mask", mask, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_fwfft(VipsImage * input, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("fwfft"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_gamma(VipsImage * input, VipsImage ** out_out, GenGammaOpts *opts) { + VipsOperation *op = vips_operation_new("gamma"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (opts) { + if (opts->has_exponent) { + vips_object_set(VIPS_OBJECT(op), "exponent", opts->exponent, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_gaussblur(VipsImage * input, double sigma, VipsImage ** out_out, GenGaussblurOpts *opts) { + VipsOperation *op = vips_operation_new("gaussblur"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "sigma", sigma, NULL)) goto error; + + if (opts) { + if (opts->has_minAmpl) { + vips_object_set(VIPS_OBJECT(op), "min-ampl", opts->minAmpl, NULL); + } + if (opts->has_precision) { + vips_object_set(VIPS_OBJECT(op), "precision", (int)opts->precision, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_gaussmat(double sigma, double minAmpl, VipsImage ** out_out, GenGaussmatOpts *opts) { + VipsOperation *op = vips_operation_new("gaussmat"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "sigma", sigma, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "min-ampl", minAmpl, NULL)) goto error; + + if (opts) { + if (opts->has_separable) { + vips_object_set(VIPS_OBJECT(op), "separable", (gboolean)opts->separable, NULL); + } + if (opts->has_precision) { + vips_object_set(VIPS_OBJECT(op), "precision", (int)opts->precision, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_gaussnoise(int width, int height, VipsImage ** out_out, GenGaussnoiseOpts *opts) { + VipsOperation *op = vips_operation_new("gaussnoise"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "width", width, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "height", height, NULL)) goto error; + + if (opts) { + if (opts->has_sigma) { + vips_object_set(VIPS_OBJECT(op), "sigma", opts->sigma, NULL); + } + if (opts->has_mean) { + vips_object_set(VIPS_OBJECT(op), "mean", opts->mean, NULL); + } + if (opts->has_seed) { + vips_object_set(VIPS_OBJECT(op), "seed", opts->seed, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_globalbalance(VipsImage * input, VipsImage ** out_out, GenGlobalbalanceOpts *opts) { + VipsOperation *op = vips_operation_new("globalbalance"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (opts) { + if (opts->has_gamma) { + vips_object_set(VIPS_OBJECT(op), "gamma", opts->gamma, NULL); + } + if (opts->has_intOutput) { + vips_object_set(VIPS_OBJECT(op), "int-output", (gboolean)opts->intOutput, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_gravity(VipsImage * input, VipsCompassDirection direction, int width, int height, VipsImage ** out_out, GenGravityOpts *opts) { + VipsOperation *op = vips_operation_new("gravity"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "direction", (int)direction, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "width", width, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "height", height, NULL)) goto error; + + if (opts) { + if (opts->has_extend) { + vips_object_set(VIPS_OBJECT(op), "extend", (int)opts->extend, NULL); + } + if (opts->has_background) { + { + VipsArrayDouble *arr = vips_array_double_new(opts->background, opts->background_n); + vips_object_set(VIPS_OBJECT(op), "background", arr, NULL); + vips_area_unref(VIPS_AREA(arr)); + } + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_grey(int width, int height, VipsImage ** out_out, GenGreyOpts *opts) { + VipsOperation *op = vips_operation_new("grey"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "width", width, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "height", height, NULL)) goto error; + + if (opts) { + if (opts->has_uchar) { + vips_object_set(VIPS_OBJECT(op), "uchar", (gboolean)opts->uchar, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_grid(VipsImage * input, int tileHeight, int across, int down, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("grid"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "tile-height", tileHeight, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "across", across, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "down", down, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_hist_cum(VipsImage * input, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("hist_cum"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_hist_entropy(VipsImage * input, double * out_out) { + VipsOperation *op = vips_operation_new("hist_entropy"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_hist_equal(VipsImage * input, VipsImage ** out_out, GenHistEqualOpts *opts) { + VipsOperation *op = vips_operation_new("hist_equal"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (opts) { + if (opts->has_band) { + vips_object_set(VIPS_OBJECT(op), "band", opts->band, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_hist_find(VipsImage * input, VipsImage ** out_out, GenHistFindOpts *opts) { + VipsOperation *op = vips_operation_new("hist_find"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (opts) { + if (opts->has_band) { + vips_object_set(VIPS_OBJECT(op), "band", opts->band, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_hist_find_indexed(VipsImage * input, VipsImage * index, VipsImage ** out_out, GenHistFindIndexedOpts *opts) { + VipsOperation *op = vips_operation_new("hist_find_indexed"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "index", index, NULL)) goto error; + + if (opts) { + if (opts->has_combine) { + vips_object_set(VIPS_OBJECT(op), "combine", (int)opts->combine, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_hist_find_ndim(VipsImage * input, VipsImage ** out_out, GenHistFindNdimOpts *opts) { + VipsOperation *op = vips_operation_new("hist_find_ndim"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (opts) { + if (opts->has_bins) { + vips_object_set(VIPS_OBJECT(op), "bins", opts->bins, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_hist_ismonotonic(VipsImage * input, int * out_monotonic) { + VipsOperation *op = vips_operation_new("hist_ismonotonic"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "monotonic", out_monotonic, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_hist_local(VipsImage * input, int width, int height, VipsImage ** out_out, GenHistLocalOpts *opts) { + VipsOperation *op = vips_operation_new("hist_local"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "width", width, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "height", height, NULL)) goto error; + + if (opts) { + if (opts->has_maxSlope) { + vips_object_set(VIPS_OBJECT(op), "max-slope", opts->maxSlope, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_hist_match(VipsImage * input, VipsImage * ref, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("hist_match"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "ref", ref, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_hist_norm(VipsImage * input, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("hist_norm"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_hist_plot(VipsImage * input, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("hist_plot"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_hough_circle(VipsImage * input, VipsImage ** out_out, GenHoughCircleOpts *opts) { + VipsOperation *op = vips_operation_new("hough_circle"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (opts) { + if (opts->has_scale) { + vips_object_set(VIPS_OBJECT(op), "scale", opts->scale, NULL); + } + if (opts->has_minRadius) { + vips_object_set(VIPS_OBJECT(op), "min-radius", opts->minRadius, NULL); + } + if (opts->has_maxRadius) { + vips_object_set(VIPS_OBJECT(op), "max-radius", opts->maxRadius, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_hough_line(VipsImage * input, VipsImage ** out_out, GenHoughLineOpts *opts) { + VipsOperation *op = vips_operation_new("hough_line"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (opts) { + if (opts->has_width) { + vips_object_set(VIPS_OBJECT(op), "width", opts->width, NULL); + } + if (opts->has_height) { + vips_object_set(VIPS_OBJECT(op), "height", opts->height, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_icc_export(VipsImage * input, VipsImage ** out_out, GenIccExportOpts *opts) { + VipsOperation *op = vips_operation_new("icc_export"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (opts) { + if (opts->has_pcs) { + vips_object_set(VIPS_OBJECT(op), "pcs", (int)opts->pcs, NULL); + } + if (opts->has_intent) { + vips_object_set(VIPS_OBJECT(op), "intent", (int)opts->intent, NULL); + } + if (opts->has_blackPointCompensation) { + vips_object_set(VIPS_OBJECT(op), "black-point-compensation", (gboolean)opts->blackPointCompensation, NULL); + } + if (opts->has_outputProfile) { + vips_object_set(VIPS_OBJECT(op), "output-profile", opts->outputProfile, NULL); + } + if (opts->has_depth) { + vips_object_set(VIPS_OBJECT(op), "depth", opts->depth, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_icc_import(VipsImage * input, VipsImage ** out_out, GenIccImportOpts *opts) { + VipsOperation *op = vips_operation_new("icc_import"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (opts) { + if (opts->has_pcs) { + vips_object_set(VIPS_OBJECT(op), "pcs", (int)opts->pcs, NULL); + } + if (opts->has_intent) { + vips_object_set(VIPS_OBJECT(op), "intent", (int)opts->intent, NULL); + } + if (opts->has_blackPointCompensation) { + vips_object_set(VIPS_OBJECT(op), "black-point-compensation", (gboolean)opts->blackPointCompensation, NULL); + } + if (opts->has_embedded) { + vips_object_set(VIPS_OBJECT(op), "embedded", (gboolean)opts->embedded, NULL); + } + if (opts->has_inputProfile) { + vips_object_set(VIPS_OBJECT(op), "input-profile", opts->inputProfile, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_identity(VipsImage ** out_out, GenIdentityOpts *opts) { + VipsOperation *op = vips_operation_new("identity"); + if (!op) return -1; + + + if (opts) { + if (opts->has_bands) { + vips_object_set(VIPS_OBJECT(op), "bands", opts->bands, NULL); + } + if (opts->has_ushort) { + vips_object_set(VIPS_OBJECT(op), "ushort", (gboolean)opts->ushort, NULL); + } + if (opts->has_size) { + vips_object_set(VIPS_OBJECT(op), "size", opts->size, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_ifthenelse(VipsImage * cond, VipsImage * in1, VipsImage * in2, VipsImage ** out_out, GenIfthenelseOpts *opts) { + VipsOperation *op = vips_operation_new("ifthenelse"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "cond", cond, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "in1", in1, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "in2", in2, NULL)) goto error; + + if (opts) { + if (opts->has_blend) { + vips_object_set(VIPS_OBJECT(op), "blend", (gboolean)opts->blend, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_insert(VipsImage * main, VipsImage * sub, int x, int y, VipsImage ** out_out, GenInsertOpts *opts) { + VipsOperation *op = vips_operation_new("insert"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "main", main, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "sub", sub, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "x", x, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "y", y, NULL)) goto error; + + if (opts) { + if (opts->has_expand) { + vips_object_set(VIPS_OBJECT(op), "expand", (gboolean)opts->expand, NULL); + } + if (opts->has_background) { + { + VipsArrayDouble *arr = vips_array_double_new(opts->background, opts->background_n); + vips_object_set(VIPS_OBJECT(op), "background", arr, NULL); + vips_area_unref(VIPS_AREA(arr)); + } + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_invert(VipsImage * input, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("invert"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_invertlut(VipsImage * input, VipsImage ** out_out, GenInvertlutOpts *opts) { + VipsOperation *op = vips_operation_new("invertlut"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (opts) { + if (opts->has_size) { + vips_object_set(VIPS_OBJECT(op), "size", opts->size, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_invfft(VipsImage * input, VipsImage ** out_out, GenInvfftOpts *opts) { + VipsOperation *op = vips_operation_new("invfft"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (opts) { + if (opts->has_real) { + vips_object_set(VIPS_OBJECT(op), "real", (gboolean)opts->real, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_join(VipsImage * in1, VipsImage * in2, VipsDirection direction, VipsImage ** out_out, GenJoinOpts *opts) { + VipsOperation *op = vips_operation_new("join"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in1", in1, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "in2", in2, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "direction", (int)direction, NULL)) goto error; + + if (opts) { + if (opts->has_expand) { + vips_object_set(VIPS_OBJECT(op), "expand", (gboolean)opts->expand, NULL); + } + if (opts->has_shim) { + vips_object_set(VIPS_OBJECT(op), "shim", opts->shim, NULL); + } + if (opts->has_background) { + { + VipsArrayDouble *arr = vips_array_double_new(opts->background, opts->background_n); + vips_object_set(VIPS_OBJECT(op), "background", arr, NULL); + vips_area_unref(VIPS_AREA(arr)); + } + } + if (opts->has_align) { + vips_object_set(VIPS_OBJECT(op), "align", (int)opts->align, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_labelregions(VipsImage * input, VipsImage ** out_mask, int * out_segments) { + VipsOperation *op = vips_operation_new("labelregions"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "mask", out_mask, NULL); + g_object_get(VIPS_OBJECT(op), "segments", out_segments, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_linear(VipsImage * input, double * a, int a_n, double * b, int b_n, VipsImage ** out_out, GenLinearOpts *opts) { + VipsOperation *op = vips_operation_new("linear"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + { + VipsArrayDouble *arr = vips_array_double_new(a, a_n); + int ret = vips_object_set(VIPS_OBJECT(op), "a", arr, NULL); + vips_area_unref(VIPS_AREA(arr)); + if (ret) goto error; + } + { + VipsArrayDouble *arr = vips_array_double_new(b, b_n); + int ret = vips_object_set(VIPS_OBJECT(op), "b", arr, NULL); + vips_area_unref(VIPS_AREA(arr)); + if (ret) goto error; + } + + if (opts) { + if (opts->has_uchar) { + vips_object_set(VIPS_OBJECT(op), "uchar", (gboolean)opts->uchar, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_linecache(VipsImage * input, VipsImage ** out_out, GenLinecacheOpts *opts) { + VipsOperation *op = vips_operation_new("linecache"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (opts) { + if (opts->has_tileHeight) { + vips_object_set(VIPS_OBJECT(op), "tile-height", opts->tileHeight, NULL); + } + if (opts->has_access) { + vips_object_set(VIPS_OBJECT(op), "access", (int)opts->access, NULL); + } + if (opts->has_threaded) { + vips_object_set(VIPS_OBJECT(op), "threaded", (gboolean)opts->threaded, NULL); + } + if (opts->has_persistent) { + vips_object_set(VIPS_OBJECT(op), "persistent", (gboolean)opts->persistent, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_logmat(double sigma, double minAmpl, VipsImage ** out_out, GenLogmatOpts *opts) { + VipsOperation *op = vips_operation_new("logmat"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "sigma", sigma, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "min-ampl", minAmpl, NULL)) goto error; + + if (opts) { + if (opts->has_separable) { + vips_object_set(VIPS_OBJECT(op), "separable", (gboolean)opts->separable, NULL); + } + if (opts->has_precision) { + vips_object_set(VIPS_OBJECT(op), "precision", (int)opts->precision, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_mapim(VipsImage * input, VipsImage * index, VipsImage ** out_out, GenMapimOpts *opts) { + VipsOperation *op = vips_operation_new("mapim"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "index", index, NULL)) goto error; + + if (opts) { + if (opts->has_interpolate) { + vips_object_set(VIPS_OBJECT(op), "interpolate", opts->interpolate, NULL); + } + if (opts->has_background) { + { + VipsArrayDouble *arr = vips_array_double_new(opts->background, opts->background_n); + vips_object_set(VIPS_OBJECT(op), "background", arr, NULL); + vips_area_unref(VIPS_AREA(arr)); + } + } + if (opts->has_premultiplied) { + vips_object_set(VIPS_OBJECT(op), "premultiplied", (gboolean)opts->premultiplied, NULL); + } + if (opts->has_extend) { + vips_object_set(VIPS_OBJECT(op), "extend", (int)opts->extend, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_maplut(VipsImage * input, VipsImage * lut, VipsImage ** out_out, GenMaplutOpts *opts) { + VipsOperation *op = vips_operation_new("maplut"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "lut", lut, NULL)) goto error; + + if (opts) { + if (opts->has_band) { + vips_object_set(VIPS_OBJECT(op), "band", opts->band, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_mask_butterworth(int width, int height, double order, double frequencyCutoff, double amplitudeCutoff, VipsImage ** out_out, GenMaskButterworthOpts *opts) { + VipsOperation *op = vips_operation_new("mask_butterworth"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "width", width, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "height", height, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "order", order, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "frequency-cutoff", frequencyCutoff, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "amplitude-cutoff", amplitudeCutoff, NULL)) goto error; + + if (opts) { + if (opts->has_uchar) { + vips_object_set(VIPS_OBJECT(op), "uchar", (gboolean)opts->uchar, NULL); + } + if (opts->has_nodc) { + vips_object_set(VIPS_OBJECT(op), "nodc", (gboolean)opts->nodc, NULL); + } + if (opts->has_reject) { + vips_object_set(VIPS_OBJECT(op), "reject", (gboolean)opts->reject, NULL); + } + if (opts->has_optical) { + vips_object_set(VIPS_OBJECT(op), "optical", (gboolean)opts->optical, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_mask_butterworth_band(int width, int height, double order, double frequencyCutoffX, double frequencyCutoffY, double radius, double amplitudeCutoff, VipsImage ** out_out, GenMaskButterworthBandOpts *opts) { + VipsOperation *op = vips_operation_new("mask_butterworth_band"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "width", width, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "height", height, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "order", order, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "frequency-cutoff-x", frequencyCutoffX, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "frequency-cutoff-y", frequencyCutoffY, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "radius", radius, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "amplitude-cutoff", amplitudeCutoff, NULL)) goto error; + + if (opts) { + if (opts->has_uchar) { + vips_object_set(VIPS_OBJECT(op), "uchar", (gboolean)opts->uchar, NULL); + } + if (opts->has_nodc) { + vips_object_set(VIPS_OBJECT(op), "nodc", (gboolean)opts->nodc, NULL); + } + if (opts->has_reject) { + vips_object_set(VIPS_OBJECT(op), "reject", (gboolean)opts->reject, NULL); + } + if (opts->has_optical) { + vips_object_set(VIPS_OBJECT(op), "optical", (gboolean)opts->optical, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_mask_butterworth_ring(int width, int height, double order, double frequencyCutoff, double amplitudeCutoff, double ringwidth, VipsImage ** out_out, GenMaskButterworthRingOpts *opts) { + VipsOperation *op = vips_operation_new("mask_butterworth_ring"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "width", width, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "height", height, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "order", order, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "frequency-cutoff", frequencyCutoff, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "amplitude-cutoff", amplitudeCutoff, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "ringwidth", ringwidth, NULL)) goto error; + + if (opts) { + if (opts->has_uchar) { + vips_object_set(VIPS_OBJECT(op), "uchar", (gboolean)opts->uchar, NULL); + } + if (opts->has_nodc) { + vips_object_set(VIPS_OBJECT(op), "nodc", (gboolean)opts->nodc, NULL); + } + if (opts->has_reject) { + vips_object_set(VIPS_OBJECT(op), "reject", (gboolean)opts->reject, NULL); + } + if (opts->has_optical) { + vips_object_set(VIPS_OBJECT(op), "optical", (gboolean)opts->optical, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_mask_fractal(int width, int height, double fractalDimension, VipsImage ** out_out, GenMaskFractalOpts *opts) { + VipsOperation *op = vips_operation_new("mask_fractal"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "width", width, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "height", height, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "fractal-dimension", fractalDimension, NULL)) goto error; + + if (opts) { + if (opts->has_uchar) { + vips_object_set(VIPS_OBJECT(op), "uchar", (gboolean)opts->uchar, NULL); + } + if (opts->has_nodc) { + vips_object_set(VIPS_OBJECT(op), "nodc", (gboolean)opts->nodc, NULL); + } + if (opts->has_reject) { + vips_object_set(VIPS_OBJECT(op), "reject", (gboolean)opts->reject, NULL); + } + if (opts->has_optical) { + vips_object_set(VIPS_OBJECT(op), "optical", (gboolean)opts->optical, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_mask_gaussian(int width, int height, double frequencyCutoff, double amplitudeCutoff, VipsImage ** out_out, GenMaskGaussianOpts *opts) { + VipsOperation *op = vips_operation_new("mask_gaussian"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "width", width, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "height", height, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "frequency-cutoff", frequencyCutoff, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "amplitude-cutoff", amplitudeCutoff, NULL)) goto error; + + if (opts) { + if (opts->has_uchar) { + vips_object_set(VIPS_OBJECT(op), "uchar", (gboolean)opts->uchar, NULL); + } + if (opts->has_nodc) { + vips_object_set(VIPS_OBJECT(op), "nodc", (gboolean)opts->nodc, NULL); + } + if (opts->has_reject) { + vips_object_set(VIPS_OBJECT(op), "reject", (gboolean)opts->reject, NULL); + } + if (opts->has_optical) { + vips_object_set(VIPS_OBJECT(op), "optical", (gboolean)opts->optical, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_mask_gaussian_band(int width, int height, double frequencyCutoffX, double frequencyCutoffY, double radius, double amplitudeCutoff, VipsImage ** out_out, GenMaskGaussianBandOpts *opts) { + VipsOperation *op = vips_operation_new("mask_gaussian_band"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "width", width, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "height", height, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "frequency-cutoff-x", frequencyCutoffX, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "frequency-cutoff-y", frequencyCutoffY, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "radius", radius, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "amplitude-cutoff", amplitudeCutoff, NULL)) goto error; + + if (opts) { + if (opts->has_uchar) { + vips_object_set(VIPS_OBJECT(op), "uchar", (gboolean)opts->uchar, NULL); + } + if (opts->has_nodc) { + vips_object_set(VIPS_OBJECT(op), "nodc", (gboolean)opts->nodc, NULL); + } + if (opts->has_reject) { + vips_object_set(VIPS_OBJECT(op), "reject", (gboolean)opts->reject, NULL); + } + if (opts->has_optical) { + vips_object_set(VIPS_OBJECT(op), "optical", (gboolean)opts->optical, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_mask_gaussian_ring(int width, int height, double frequencyCutoff, double amplitudeCutoff, double ringwidth, VipsImage ** out_out, GenMaskGaussianRingOpts *opts) { + VipsOperation *op = vips_operation_new("mask_gaussian_ring"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "width", width, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "height", height, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "frequency-cutoff", frequencyCutoff, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "amplitude-cutoff", amplitudeCutoff, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "ringwidth", ringwidth, NULL)) goto error; + + if (opts) { + if (opts->has_uchar) { + vips_object_set(VIPS_OBJECT(op), "uchar", (gboolean)opts->uchar, NULL); + } + if (opts->has_nodc) { + vips_object_set(VIPS_OBJECT(op), "nodc", (gboolean)opts->nodc, NULL); + } + if (opts->has_reject) { + vips_object_set(VIPS_OBJECT(op), "reject", (gboolean)opts->reject, NULL); + } + if (opts->has_optical) { + vips_object_set(VIPS_OBJECT(op), "optical", (gboolean)opts->optical, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_mask_ideal(int width, int height, double frequencyCutoff, VipsImage ** out_out, GenMaskIdealOpts *opts) { + VipsOperation *op = vips_operation_new("mask_ideal"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "width", width, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "height", height, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "frequency-cutoff", frequencyCutoff, NULL)) goto error; + + if (opts) { + if (opts->has_uchar) { + vips_object_set(VIPS_OBJECT(op), "uchar", (gboolean)opts->uchar, NULL); + } + if (opts->has_nodc) { + vips_object_set(VIPS_OBJECT(op), "nodc", (gboolean)opts->nodc, NULL); + } + if (opts->has_reject) { + vips_object_set(VIPS_OBJECT(op), "reject", (gboolean)opts->reject, NULL); + } + if (opts->has_optical) { + vips_object_set(VIPS_OBJECT(op), "optical", (gboolean)opts->optical, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_mask_ideal_band(int width, int height, double frequencyCutoffX, double frequencyCutoffY, double radius, VipsImage ** out_out, GenMaskIdealBandOpts *opts) { + VipsOperation *op = vips_operation_new("mask_ideal_band"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "width", width, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "height", height, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "frequency-cutoff-x", frequencyCutoffX, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "frequency-cutoff-y", frequencyCutoffY, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "radius", radius, NULL)) goto error; + + if (opts) { + if (opts->has_uchar) { + vips_object_set(VIPS_OBJECT(op), "uchar", (gboolean)opts->uchar, NULL); + } + if (opts->has_nodc) { + vips_object_set(VIPS_OBJECT(op), "nodc", (gboolean)opts->nodc, NULL); + } + if (opts->has_reject) { + vips_object_set(VIPS_OBJECT(op), "reject", (gboolean)opts->reject, NULL); + } + if (opts->has_optical) { + vips_object_set(VIPS_OBJECT(op), "optical", (gboolean)opts->optical, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_mask_ideal_ring(int width, int height, double frequencyCutoff, double ringwidth, VipsImage ** out_out, GenMaskIdealRingOpts *opts) { + VipsOperation *op = vips_operation_new("mask_ideal_ring"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "width", width, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "height", height, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "frequency-cutoff", frequencyCutoff, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "ringwidth", ringwidth, NULL)) goto error; + + if (opts) { + if (opts->has_uchar) { + vips_object_set(VIPS_OBJECT(op), "uchar", (gboolean)opts->uchar, NULL); + } + if (opts->has_nodc) { + vips_object_set(VIPS_OBJECT(op), "nodc", (gboolean)opts->nodc, NULL); + } + if (opts->has_reject) { + vips_object_set(VIPS_OBJECT(op), "reject", (gboolean)opts->reject, NULL); + } + if (opts->has_optical) { + vips_object_set(VIPS_OBJECT(op), "optical", (gboolean)opts->optical, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_match(VipsImage * ref, VipsImage * sec, int xr1, int yr1, int xs1, int ys1, int xr2, int yr2, int xs2, int ys2, VipsImage ** out_out, GenMatchOpts *opts) { + VipsOperation *op = vips_operation_new("match"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "ref", ref, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "sec", sec, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "xr1", xr1, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "yr1", yr1, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "xs1", xs1, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "ys1", ys1, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "xr2", xr2, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "yr2", yr2, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "xs2", xs2, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "ys2", ys2, NULL)) goto error; + + if (opts) { + if (opts->has_hwindow) { + vips_object_set(VIPS_OBJECT(op), "hwindow", opts->hwindow, NULL); + } + if (opts->has_harea) { + vips_object_set(VIPS_OBJECT(op), "harea", opts->harea, NULL); + } + if (opts->has_search) { + vips_object_set(VIPS_OBJECT(op), "search", (gboolean)opts->search, NULL); + } + if (opts->has_interpolate) { + vips_object_set(VIPS_OBJECT(op), "interpolate", opts->interpolate, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_math(VipsImage * input, VipsOperationMath math, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("math"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "math", (int)math, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_math2(VipsImage * left, VipsImage * right, VipsOperationMath2 math2, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("math2"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "left", left, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "right", right, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "math2", (int)math2, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_math2_const(VipsImage * input, VipsOperationMath2 math2, double * c, int c_n, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("math2_const"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "math2", (int)math2, NULL)) goto error; + { + VipsArrayDouble *arr = vips_array_double_new(c, c_n); + int ret = vips_object_set(VIPS_OBJECT(op), "c", arr, NULL); + vips_area_unref(VIPS_AREA(arr)); + if (ret) goto error; + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_matrixinvert(VipsImage * input, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("matrixinvert"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_matrixmultiply(VipsImage * left, VipsImage * right, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("matrixmultiply"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "left", left, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "right", right, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_maxpair(VipsImage * left, VipsImage * right, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("maxpair"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "left", left, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "right", right, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_merge(VipsImage * ref, VipsImage * sec, VipsDirection direction, int dx, int dy, VipsImage ** out_out, GenMergeOpts *opts) { + VipsOperation *op = vips_operation_new("merge"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "ref", ref, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "sec", sec, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "direction", (int)direction, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "dx", dx, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "dy", dy, NULL)) goto error; + + if (opts) { + if (opts->has_mblend) { + vips_object_set(VIPS_OBJECT(op), "mblend", opts->mblend, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_minpair(VipsImage * left, VipsImage * right, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("minpair"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "left", left, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "right", right, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_morph(VipsImage * input, VipsImage * mask, VipsOperationMorphology morph, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("morph"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "mask", mask, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "morph", (int)morph, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_mosaic(VipsImage * ref, VipsImage * sec, VipsDirection direction, int xref, int yref, int xsec, int ysec, VipsImage ** out_out, int * out_dx0, int * out_dy0, double * out_scale1, double * out_angle1, double * out_dy1, double * out_dx1, GenMosaicOpts *opts) { + VipsOperation *op = vips_operation_new("mosaic"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "ref", ref, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "sec", sec, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "direction", (int)direction, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "xref", xref, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "yref", yref, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "xsec", xsec, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "ysec", ysec, NULL)) goto error; + + if (opts) { + if (opts->has_hwindow) { + vips_object_set(VIPS_OBJECT(op), "hwindow", opts->hwindow, NULL); + } + if (opts->has_harea) { + vips_object_set(VIPS_OBJECT(op), "harea", opts->harea, NULL); + } + if (opts->has_mblend) { + vips_object_set(VIPS_OBJECT(op), "mblend", opts->mblend, NULL); + } + if (opts->has_bandno) { + vips_object_set(VIPS_OBJECT(op), "bandno", opts->bandno, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + g_object_get(VIPS_OBJECT(op), "dx0", out_dx0, NULL); + g_object_get(VIPS_OBJECT(op), "dy0", out_dy0, NULL); + g_object_get(VIPS_OBJECT(op), "scale1", out_scale1, NULL); + g_object_get(VIPS_OBJECT(op), "angle1", out_angle1, NULL); + g_object_get(VIPS_OBJECT(op), "dy1", out_dy1, NULL); + g_object_get(VIPS_OBJECT(op), "dx1", out_dx1, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_mosaic1(VipsImage * ref, VipsImage * sec, VipsDirection direction, int xr1, int yr1, int xs1, int ys1, int xr2, int yr2, int xs2, int ys2, VipsImage ** out_out, GenMosaic1Opts *opts) { + VipsOperation *op = vips_operation_new("mosaic1"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "ref", ref, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "sec", sec, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "direction", (int)direction, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "xr1", xr1, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "yr1", yr1, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "xs1", xs1, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "ys1", ys1, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "xr2", xr2, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "yr2", yr2, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "xs2", xs2, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "ys2", ys2, NULL)) goto error; + + if (opts) { + if (opts->has_hwindow) { + vips_object_set(VIPS_OBJECT(op), "hwindow", opts->hwindow, NULL); + } + if (opts->has_harea) { + vips_object_set(VIPS_OBJECT(op), "harea", opts->harea, NULL); + } + if (opts->has_search) { + vips_object_set(VIPS_OBJECT(op), "search", (gboolean)opts->search, NULL); + } + if (opts->has_interpolate) { + vips_object_set(VIPS_OBJECT(op), "interpolate", opts->interpolate, NULL); + } + if (opts->has_mblend) { + vips_object_set(VIPS_OBJECT(op), "mblend", opts->mblend, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_msb(VipsImage * input, VipsImage ** out_out, GenMsbOpts *opts) { + VipsOperation *op = vips_operation_new("msb"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (opts) { + if (opts->has_band) { + vips_object_set(VIPS_OBJECT(op), "band", opts->band, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_multiply(VipsImage * left, VipsImage * right, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("multiply"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "left", left, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "right", right, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_percent(VipsImage * input, double percent, int * out_threshold) { + VipsOperation *op = vips_operation_new("percent"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "percent", percent, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "threshold", out_threshold, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_perlin(int width, int height, VipsImage ** out_out, GenPerlinOpts *opts) { + VipsOperation *op = vips_operation_new("perlin"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "width", width, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "height", height, NULL)) goto error; + + if (opts) { + if (opts->has_cellSize) { + vips_object_set(VIPS_OBJECT(op), "cell-size", opts->cellSize, NULL); + } + if (opts->has_uchar) { + vips_object_set(VIPS_OBJECT(op), "uchar", (gboolean)opts->uchar, NULL); + } + if (opts->has_seed) { + vips_object_set(VIPS_OBJECT(op), "seed", opts->seed, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_phasecor(VipsImage * input, VipsImage * in2, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("phasecor"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "in2", in2, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_premultiply(VipsImage * input, VipsImage ** out_out, GenPremultiplyOpts *opts) { + VipsOperation *op = vips_operation_new("premultiply"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (opts) { + if (opts->has_maxAlpha) { + vips_object_set(VIPS_OBJECT(op), "max-alpha", opts->maxAlpha, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_prewitt(VipsImage * input, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("prewitt"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_profile(VipsImage * input, VipsImage ** out_columns, VipsImage ** out_rows) { + VipsOperation *op = vips_operation_new("profile"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "columns", out_columns, NULL); + g_object_get(VIPS_OBJECT(op), "rows", out_rows, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_project(VipsImage * input, VipsImage ** out_columns, VipsImage ** out_rows) { + VipsOperation *op = vips_operation_new("project"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "columns", out_columns, NULL); + g_object_get(VIPS_OBJECT(op), "rows", out_rows, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_quadratic(VipsImage * input, VipsImage * coeff, VipsImage ** out_out, GenQuadraticOpts *opts) { + VipsOperation *op = vips_operation_new("quadratic"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "coeff", coeff, NULL)) goto error; + + if (opts) { + if (opts->has_interpolate) { + vips_object_set(VIPS_OBJECT(op), "interpolate", opts->interpolate, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_rad2float(VipsImage * input, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("rad2float"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_rank(VipsImage * input, int width, int height, int index, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("rank"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "width", width, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "height", height, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "index", index, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_recomb(VipsImage * input, VipsImage * m, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("recomb"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "m", m, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_reduce(VipsImage * input, double hshrink, double vshrink, VipsImage ** out_out, GenReduceOpts *opts) { + VipsOperation *op = vips_operation_new("reduce"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "hshrink", hshrink, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "vshrink", vshrink, NULL)) goto error; + + if (opts) { + if (opts->has_kernel) { + vips_object_set(VIPS_OBJECT(op), "kernel", (int)opts->kernel, NULL); + } + if (opts->has_gap) { + vips_object_set(VIPS_OBJECT(op), "gap", opts->gap, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_reduceh(VipsImage * input, double hshrink, VipsImage ** out_out, GenReducehOpts *opts) { + VipsOperation *op = vips_operation_new("reduceh"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "hshrink", hshrink, NULL)) goto error; + + if (opts) { + if (opts->has_kernel) { + vips_object_set(VIPS_OBJECT(op), "kernel", (int)opts->kernel, NULL); + } + if (opts->has_gap) { + vips_object_set(VIPS_OBJECT(op), "gap", opts->gap, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_reducev(VipsImage * input, double vshrink, VipsImage ** out_out, GenReducevOpts *opts) { + VipsOperation *op = vips_operation_new("reducev"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "vshrink", vshrink, NULL)) goto error; + + if (opts) { + if (opts->has_kernel) { + vips_object_set(VIPS_OBJECT(op), "kernel", (int)opts->kernel, NULL); + } + if (opts->has_gap) { + vips_object_set(VIPS_OBJECT(op), "gap", opts->gap, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_relational(VipsImage * left, VipsImage * right, VipsOperationRelational relational, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("relational"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "left", left, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "right", right, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "relational", (int)relational, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_relational_const(VipsImage * input, VipsOperationRelational relational, double * c, int c_n, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("relational_const"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "relational", (int)relational, NULL)) goto error; + { + VipsArrayDouble *arr = vips_array_double_new(c, c_n); + int ret = vips_object_set(VIPS_OBJECT(op), "c", arr, NULL); + vips_area_unref(VIPS_AREA(arr)); + if (ret) goto error; + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_remainder(VipsImage * left, VipsImage * right, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("remainder"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "left", left, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "right", right, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_remainder_const(VipsImage * input, double * c, int c_n, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("remainder_const"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + { + VipsArrayDouble *arr = vips_array_double_new(c, c_n); + int ret = vips_object_set(VIPS_OBJECT(op), "c", arr, NULL); + vips_area_unref(VIPS_AREA(arr)); + if (ret) goto error; + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_remosaic(VipsImage * input, const char * oldStr, const char * newStr, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("remosaic"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "old-str", oldStr, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "new-str", newStr, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_replicate(VipsImage * input, int across, int down, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("replicate"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "across", across, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "down", down, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_rot(VipsImage * input, VipsAngle angle, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("rot"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "angle", (int)angle, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_rot45(VipsImage * input, VipsImage ** out_out, GenRot45Opts *opts) { + VipsOperation *op = vips_operation_new("rot45"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (opts) { + if (opts->has_angle) { + vips_object_set(VIPS_OBJECT(op), "angle", (int)opts->angle, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_rotate(VipsImage * input, double angle, VipsImage ** out_out, GenRotateOpts *opts) { + VipsOperation *op = vips_operation_new("rotate"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "angle", angle, NULL)) goto error; + + if (opts) { + if (opts->has_interpolate) { + vips_object_set(VIPS_OBJECT(op), "interpolate", opts->interpolate, NULL); + } + if (opts->has_background) { + { + VipsArrayDouble *arr = vips_array_double_new(opts->background, opts->background_n); + vips_object_set(VIPS_OBJECT(op), "background", arr, NULL); + vips_area_unref(VIPS_AREA(arr)); + } + } + if (opts->has_odx) { + vips_object_set(VIPS_OBJECT(op), "odx", opts->odx, NULL); + } + if (opts->has_ody) { + vips_object_set(VIPS_OBJECT(op), "ody", opts->ody, NULL); + } + if (opts->has_idx) { + vips_object_set(VIPS_OBJECT(op), "idx", opts->idx, NULL); + } + if (opts->has_idy) { + vips_object_set(VIPS_OBJECT(op), "idy", opts->idy, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_round(VipsImage * input, VipsOperationRound round, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("round"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "round", (int)round, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_sRGB2HSV(VipsImage * input, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("sRGB2HSV"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_sRGB2scRGB(VipsImage * input, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("sRGB2scRGB"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_scRGB2BW(VipsImage * input, VipsImage ** out_out, GenScRGB2BWOpts *opts) { + VipsOperation *op = vips_operation_new("scRGB2BW"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (opts) { + if (opts->has_depth) { + vips_object_set(VIPS_OBJECT(op), "depth", opts->depth, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_scRGB2XYZ(VipsImage * input, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("scRGB2XYZ"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_scRGB2sRGB(VipsImage * input, VipsImage ** out_out, GenScRGB2sRGBOpts *opts) { + VipsOperation *op = vips_operation_new("scRGB2sRGB"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (opts) { + if (opts->has_depth) { + vips_object_set(VIPS_OBJECT(op), "depth", opts->depth, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_scale(VipsImage * input, VipsImage ** out_out, GenScaleOpts *opts) { + VipsOperation *op = vips_operation_new("scale"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (opts) { + if (opts->has_exp) { + vips_object_set(VIPS_OBJECT(op), "exp", opts->exp, NULL); + } + if (opts->has_log) { + vips_object_set(VIPS_OBJECT(op), "log", (gboolean)opts->log, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_scharr(VipsImage * input, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("scharr"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_sequential(VipsImage * input, VipsImage ** out_out, GenSequentialOpts *opts) { + VipsOperation *op = vips_operation_new("sequential"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (opts) { + if (opts->has_tileHeight) { + vips_object_set(VIPS_OBJECT(op), "tile-height", opts->tileHeight, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_sharpen(VipsImage * input, VipsImage ** out_out, GenSharpenOpts *opts) { + VipsOperation *op = vips_operation_new("sharpen"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (opts) { + if (opts->has_sigma) { + vips_object_set(VIPS_OBJECT(op), "sigma", opts->sigma, NULL); + } + if (opts->has_x1) { + vips_object_set(VIPS_OBJECT(op), "x1", opts->x1, NULL); + } + if (opts->has_y2) { + vips_object_set(VIPS_OBJECT(op), "y2", opts->y2, NULL); + } + if (opts->has_y3) { + vips_object_set(VIPS_OBJECT(op), "y3", opts->y3, NULL); + } + if (opts->has_m1) { + vips_object_set(VIPS_OBJECT(op), "m1", opts->m1, NULL); + } + if (opts->has_m2) { + vips_object_set(VIPS_OBJECT(op), "m2", opts->m2, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_shrink(VipsImage * input, double hshrink, double vshrink, VipsImage ** out_out, GenShrinkOpts *opts) { + VipsOperation *op = vips_operation_new("shrink"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "hshrink", hshrink, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "vshrink", vshrink, NULL)) goto error; + + if (opts) { + if (opts->has_ceil) { + vips_object_set(VIPS_OBJECT(op), "ceil", (gboolean)opts->ceil, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_shrinkh(VipsImage * input, int hshrink, VipsImage ** out_out, GenShrinkhOpts *opts) { + VipsOperation *op = vips_operation_new("shrinkh"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "hshrink", hshrink, NULL)) goto error; + + if (opts) { + if (opts->has_ceil) { + vips_object_set(VIPS_OBJECT(op), "ceil", (gboolean)opts->ceil, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_shrinkv(VipsImage * input, int vshrink, VipsImage ** out_out, GenShrinkvOpts *opts) { + VipsOperation *op = vips_operation_new("shrinkv"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "vshrink", vshrink, NULL)) goto error; + + if (opts) { + if (opts->has_ceil) { + vips_object_set(VIPS_OBJECT(op), "ceil", (gboolean)opts->ceil, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_sign(VipsImage * input, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("sign"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_similarity(VipsImage * input, VipsImage ** out_out, GenSimilarityOpts *opts) { + VipsOperation *op = vips_operation_new("similarity"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (opts) { + if (opts->has_scale) { + vips_object_set(VIPS_OBJECT(op), "scale", opts->scale, NULL); + } + if (opts->has_angle) { + vips_object_set(VIPS_OBJECT(op), "angle", opts->angle, NULL); + } + if (opts->has_interpolate) { + vips_object_set(VIPS_OBJECT(op), "interpolate", opts->interpolate, NULL); + } + if (opts->has_background) { + { + VipsArrayDouble *arr = vips_array_double_new(opts->background, opts->background_n); + vips_object_set(VIPS_OBJECT(op), "background", arr, NULL); + vips_area_unref(VIPS_AREA(arr)); + } + } + if (opts->has_odx) { + vips_object_set(VIPS_OBJECT(op), "odx", opts->odx, NULL); + } + if (opts->has_ody) { + vips_object_set(VIPS_OBJECT(op), "ody", opts->ody, NULL); + } + if (opts->has_idx) { + vips_object_set(VIPS_OBJECT(op), "idx", opts->idx, NULL); + } + if (opts->has_idy) { + vips_object_set(VIPS_OBJECT(op), "idy", opts->idy, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_sines(int width, int height, VipsImage ** out_out, GenSinesOpts *opts) { + VipsOperation *op = vips_operation_new("sines"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "width", width, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "height", height, NULL)) goto error; + + if (opts) { + if (opts->has_uchar) { + vips_object_set(VIPS_OBJECT(op), "uchar", (gboolean)opts->uchar, NULL); + } + if (opts->has_hfreq) { + vips_object_set(VIPS_OBJECT(op), "hfreq", opts->hfreq, NULL); + } + if (opts->has_vfreq) { + vips_object_set(VIPS_OBJECT(op), "vfreq", opts->vfreq, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_smartcrop(VipsImage * input, int width, int height, int * out_attentionX, VipsImage ** out_out, int * out_attentionY, GenSmartcropOpts *opts) { + VipsOperation *op = vips_operation_new("smartcrop"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "input", input, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "width", width, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "height", height, NULL)) goto error; + + if (opts) { + if (opts->has_interesting) { + vips_object_set(VIPS_OBJECT(op), "interesting", (int)opts->interesting, NULL); + } + if (opts->has_premultiplied) { + vips_object_set(VIPS_OBJECT(op), "premultiplied", (gboolean)opts->premultiplied, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "attention-x", out_attentionX, NULL); + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + g_object_get(VIPS_OBJECT(op), "attention-y", out_attentionY, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_sobel(VipsImage * input, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("sobel"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_spcor(VipsImage * input, VipsImage * ref, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("spcor"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "ref", ref, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_spectrum(VipsImage * input, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("spectrum"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_stats(VipsImage * input, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("stats"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_stdif(VipsImage * input, int width, int height, VipsImage ** out_out, GenStdifOpts *opts) { + VipsOperation *op = vips_operation_new("stdif"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "width", width, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "height", height, NULL)) goto error; + + if (opts) { + if (opts->has_s0) { + vips_object_set(VIPS_OBJECT(op), "s0", opts->s0, NULL); + } + if (opts->has_b) { + vips_object_set(VIPS_OBJECT(op), "b", opts->b, NULL); + } + if (opts->has_m0) { + vips_object_set(VIPS_OBJECT(op), "m0", opts->m0, NULL); + } + if (opts->has_a) { + vips_object_set(VIPS_OBJECT(op), "a", opts->a, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_subsample(VipsImage * input, int xfac, int yfac, VipsImage ** out_out, GenSubsampleOpts *opts) { + VipsOperation *op = vips_operation_new("subsample"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "input", input, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "xfac", xfac, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "yfac", yfac, NULL)) goto error; + + if (opts) { + if (opts->has_point) { + vips_object_set(VIPS_OBJECT(op), "point", (gboolean)opts->point, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_subtract(VipsImage * left, VipsImage * right, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("subtract"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "left", left, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "right", right, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_sum(VipsImage **input, int input_n, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("sum"); + if (!op) return -1; + + { + VipsArrayImage *arr = vips_array_image_new(input, input_n); + int ret = vips_object_set(VIPS_OBJECT(op), "in", arr, NULL); + vips_area_unref(VIPS_AREA(arr)); + if (ret) goto error; + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_tilecache(VipsImage * input, VipsImage ** out_out, GenTilecacheOpts *opts) { + VipsOperation *op = vips_operation_new("tilecache"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (opts) { + if (opts->has_tileWidth) { + vips_object_set(VIPS_OBJECT(op), "tile-width", opts->tileWidth, NULL); + } + if (opts->has_tileHeight) { + vips_object_set(VIPS_OBJECT(op), "tile-height", opts->tileHeight, NULL); + } + if (opts->has_maxTiles) { + vips_object_set(VIPS_OBJECT(op), "max-tiles", opts->maxTiles, NULL); + } + if (opts->has_access) { + vips_object_set(VIPS_OBJECT(op), "access", (int)opts->access, NULL); + } + if (opts->has_threaded) { + vips_object_set(VIPS_OBJECT(op), "threaded", (gboolean)opts->threaded, NULL); + } + if (opts->has_persistent) { + vips_object_set(VIPS_OBJECT(op), "persistent", (gboolean)opts->persistent, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_tonelut(VipsImage ** out_out, GenTonelutOpts *opts) { + VipsOperation *op = vips_operation_new("tonelut"); + if (!op) return -1; + + + if (opts) { + if (opts->has_inMax) { + vips_object_set(VIPS_OBJECT(op), "in-max", opts->inMax, NULL); + } + if (opts->has_outMax) { + vips_object_set(VIPS_OBJECT(op), "out-max", opts->outMax, NULL); + } + if (opts->has_Lb) { + vips_object_set(VIPS_OBJECT(op), "Lb", opts->Lb, NULL); + } + if (opts->has_Lw) { + vips_object_set(VIPS_OBJECT(op), "Lw", opts->Lw, NULL); + } + if (opts->has_Ps) { + vips_object_set(VIPS_OBJECT(op), "Ps", opts->Ps, NULL); + } + if (opts->has_Pm) { + vips_object_set(VIPS_OBJECT(op), "Pm", opts->Pm, NULL); + } + if (opts->has_Ph) { + vips_object_set(VIPS_OBJECT(op), "Ph", opts->Ph, NULL); + } + if (opts->has_S) { + vips_object_set(VIPS_OBJECT(op), "S", opts->S, NULL); + } + if (opts->has_M) { + vips_object_set(VIPS_OBJECT(op), "M", opts->M, NULL); + } + if (opts->has_H) { + vips_object_set(VIPS_OBJECT(op), "H", opts->H, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_transpose3d(VipsImage * input, VipsImage ** out_out, GenTranspose3dOpts *opts) { + VipsOperation *op = vips_operation_new("transpose3d"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (opts) { + if (opts->has_pageHeight) { + vips_object_set(VIPS_OBJECT(op), "page-height", opts->pageHeight, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_uhdr2scRGB(VipsImage * input, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("uhdr2scRGB"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_unpremultiply(VipsImage * input, VipsImage ** out_out, GenUnpremultiplyOpts *opts) { + VipsOperation *op = vips_operation_new("unpremultiply"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (opts) { + if (opts->has_maxAlpha) { + vips_object_set(VIPS_OBJECT(op), "max-alpha", opts->maxAlpha, NULL); + } + if (opts->has_alphaBand) { + vips_object_set(VIPS_OBJECT(op), "alpha-band", opts->alphaBand, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_worley(int width, int height, VipsImage ** out_out, GenWorleyOpts *opts) { + VipsOperation *op = vips_operation_new("worley"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "width", width, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "height", height, NULL)) goto error; + + if (opts) { + if (opts->has_cellSize) { + vips_object_set(VIPS_OBJECT(op), "cell-size", opts->cellSize, NULL); + } + if (opts->has_seed) { + vips_object_set(VIPS_OBJECT(op), "seed", opts->seed, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_wrap(VipsImage * input, VipsImage ** out_out, GenWrapOpts *opts) { + VipsOperation *op = vips_operation_new("wrap"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error; + + if (opts) { + if (opts->has_x) { + vips_object_set(VIPS_OBJECT(op), "x", opts->x, NULL); + } + if (opts->has_y) { + vips_object_set(VIPS_OBJECT(op), "y", opts->y, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_xyz(int width, int height, VipsImage ** out_out, GenXyzOpts *opts) { + VipsOperation *op = vips_operation_new("xyz"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "width", width, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "height", height, NULL)) goto error; + + if (opts) { + if (opts->has_csize) { + vips_object_set(VIPS_OBJECT(op), "csize", opts->csize, NULL); + } + if (opts->has_dsize) { + vips_object_set(VIPS_OBJECT(op), "dsize", opts->dsize, NULL); + } + if (opts->has_esize) { + vips_object_set(VIPS_OBJECT(op), "esize", opts->esize, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_zone(int width, int height, VipsImage ** out_out, GenZoneOpts *opts) { + VipsOperation *op = vips_operation_new("zone"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "width", width, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "height", height, NULL)) goto error; + + if (opts) { + if (opts->has_uchar) { + vips_object_set(VIPS_OBJECT(op), "uchar", (gboolean)opts->uchar, NULL); + } + } + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + +int gen_vips_zoom(VipsImage * input, int xfac, int yfac, VipsImage ** out_out) { + VipsOperation *op = vips_operation_new("zoom"); + if (!op) return -1; + + if (vips_object_set(VIPS_OBJECT(op), "input", input, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "xfac", xfac, NULL)) goto error; + if (vips_object_set(VIPS_OBJECT(op), "yfac", yfac, NULL)) goto error; + + if (vips_cache_operation_buildp(&op)) goto error; + + g_object_get(VIPS_OBJECT(op), "out", out_out, NULL); + + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return 0; + +error: + vips_object_unref_outputs(VIPS_OBJECT(op)); + g_object_unref(op); + return -1; +} + diff --git a/vendor/github.com/davidbyttow/govips/v2/vips/generated.go b/vendor/github.com/davidbyttow/govips/v2/vips/generated.go new file mode 100644 index 0000000000..03237add33 --- /dev/null +++ b/vendor/github.com/davidbyttow/govips/v2/vips/generated.go @@ -0,0 +1,5001 @@ +// Code generated by vipsgen. DO NOT EDIT. +package vips + +// #include "generated.h" +import "C" + +import ( + "runtime" + "unsafe" +) + +// Ensure imports are used. +var _ = unsafe.Pointer(nil) + +// vipsGenCMC2LCh calls the vips CMC2LCh operation. +// transform LCh to CMC +func vipsGenCMC2LCh(input *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("CMC2LCh") + + var out_out *C.VipsImage + + ret := C.gen_vips_CMC2LCh(input, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenCMYK2XYZ calls the vips CMYK2XYZ operation. +// transform CMYK to XYZ +func vipsGenCMYK2XYZ(input *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("CMYK2XYZ") + + var out_out *C.VipsImage + + ret := C.gen_vips_CMYK2XYZ(input, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenHSV2sRGB calls the vips HSV2sRGB operation. +// transform HSV to sRGB +func vipsGenHSV2sRGB(input *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("HSV2sRGB") + + var out_out *C.VipsImage + + ret := C.gen_vips_HSV2sRGB(input, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenLCh2CMC calls the vips LCh2CMC operation. +// transform LCh to CMC +func vipsGenLCh2CMC(input *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("LCh2CMC") + + var out_out *C.VipsImage + + ret := C.gen_vips_LCh2CMC(input, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenLCh2Lab calls the vips LCh2Lab operation. +// transform LCh to Lab +func vipsGenLCh2Lab(input *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("LCh2Lab") + + var out_out *C.VipsImage + + ret := C.gen_vips_LCh2Lab(input, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenLab2LCh calls the vips Lab2LCh operation. +// transform Lab to LCh +func vipsGenLab2LCh(input *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("Lab2LCh") + + var out_out *C.VipsImage + + ret := C.gen_vips_Lab2LCh(input, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenLab2LabQ calls the vips Lab2LabQ operation. +// transform float Lab to LabQ coding +func vipsGenLab2LabQ(input *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("Lab2LabQ") + + var out_out *C.VipsImage + + ret := C.gen_vips_Lab2LabQ(input, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenLab2LabS calls the vips Lab2LabS operation. +// transform float Lab to signed short +func vipsGenLab2LabS(input *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("Lab2LabS") + + var out_out *C.VipsImage + + ret := C.gen_vips_Lab2LabS(input, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// Lab2XYZOptions are optional parameters for Lab2XYZ. +type Lab2XYZOptions struct { + Temp []float64 +} + +// vipsGenLab2XYZ calls the vips Lab2XYZ operation. +// transform CIELAB to XYZ +func vipsGenLab2XYZ(input *C.VipsImage, opts *Lab2XYZOptions) (*C.VipsImage, error) { + incOpCounter("Lab2XYZ") + + var out_out *C.VipsImage + + var cOpts C.GenLab2XYZOpts + var pinner runtime.Pinner + defer pinner.Unpin() + if opts != nil { + if opts.Temp != nil { + cOpts.has_temp = 1 + pinner.Pin(&opts.Temp[0]) + cOpts.temp = (*C.double)(unsafe.Pointer(&opts.Temp[0])) + cOpts.temp_n = C.int(len(opts.Temp)) + } + } + + ret := C.gen_vips_Lab2XYZ(input, &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenLabQ2Lab calls the vips LabQ2Lab operation. +// unpack a LabQ image to float Lab +func vipsGenLabQ2Lab(input *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("LabQ2Lab") + + var out_out *C.VipsImage + + ret := C.gen_vips_LabQ2Lab(input, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenLabQ2LabS calls the vips LabQ2LabS operation. +// unpack a LabQ image to short Lab +func vipsGenLabQ2LabS(input *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("LabQ2LabS") + + var out_out *C.VipsImage + + ret := C.gen_vips_LabQ2LabS(input, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenLabQ2sRGB calls the vips LabQ2sRGB operation. +// convert a LabQ image to sRGB +func vipsGenLabQ2sRGB(input *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("LabQ2sRGB") + + var out_out *C.VipsImage + + ret := C.gen_vips_LabQ2sRGB(input, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenLabS2Lab calls the vips LabS2Lab operation. +// transform signed short Lab to float +func vipsGenLabS2Lab(input *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("LabS2Lab") + + var out_out *C.VipsImage + + ret := C.gen_vips_LabS2Lab(input, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenLabS2LabQ calls the vips LabS2LabQ operation. +// transform short Lab to LabQ coding +func vipsGenLabS2LabQ(input *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("LabS2LabQ") + + var out_out *C.VipsImage + + ret := C.gen_vips_LabS2LabQ(input, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenOklab2Oklch calls the vips Oklab2Oklch operation. +// transform Oklab to Oklch +func vipsGenOklab2Oklch(input *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("Oklab2Oklch") + + var out_out *C.VipsImage + + ret := C.gen_vips_Oklab2Oklch(input, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenOklab2XYZ calls the vips Oklab2XYZ operation. +// transform Oklab to XYZ +func vipsGenOklab2XYZ(input *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("Oklab2XYZ") + + var out_out *C.VipsImage + + ret := C.gen_vips_Oklab2XYZ(input, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenOklch2Oklab calls the vips Oklch2Oklab operation. +// transform Oklch to Oklab +func vipsGenOklch2Oklab(input *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("Oklch2Oklab") + + var out_out *C.VipsImage + + ret := C.gen_vips_Oklch2Oklab(input, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenXYZ2CMYK calls the vips XYZ2CMYK operation. +// transform XYZ to CMYK +func vipsGenXYZ2CMYK(input *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("XYZ2CMYK") + + var out_out *C.VipsImage + + ret := C.gen_vips_XYZ2CMYK(input, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// XYZ2LabOptions are optional parameters for XYZ2Lab. +type XYZ2LabOptions struct { + Temp []float64 +} + +// vipsGenXYZ2Lab calls the vips XYZ2Lab operation. +// transform XYZ to Lab +func vipsGenXYZ2Lab(input *C.VipsImage, opts *XYZ2LabOptions) (*C.VipsImage, error) { + incOpCounter("XYZ2Lab") + + var out_out *C.VipsImage + + var cOpts C.GenXYZ2LabOpts + var pinner runtime.Pinner + defer pinner.Unpin() + if opts != nil { + if opts.Temp != nil { + cOpts.has_temp = 1 + pinner.Pin(&opts.Temp[0]) + cOpts.temp = (*C.double)(unsafe.Pointer(&opts.Temp[0])) + cOpts.temp_n = C.int(len(opts.Temp)) + } + } + + ret := C.gen_vips_XYZ2Lab(input, &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenXYZ2Oklab calls the vips XYZ2Oklab operation. +// transform XYZ to Oklab +func vipsGenXYZ2Oklab(input *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("XYZ2Oklab") + + var out_out *C.VipsImage + + ret := C.gen_vips_XYZ2Oklab(input, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenXYZ2Yxy calls the vips XYZ2Yxy operation. +// transform XYZ to Yxy +func vipsGenXYZ2Yxy(input *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("XYZ2Yxy") + + var out_out *C.VipsImage + + ret := C.gen_vips_XYZ2Yxy(input, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenXYZ2scRGB calls the vips XYZ2scRGB operation. +// transform XYZ to scRGB +func vipsGenXYZ2scRGB(input *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("XYZ2scRGB") + + var out_out *C.VipsImage + + ret := C.gen_vips_XYZ2scRGB(input, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenYxy2XYZ calls the vips Yxy2XYZ operation. +// transform Yxy to XYZ +func vipsGenYxy2XYZ(input *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("Yxy2XYZ") + + var out_out *C.VipsImage + + ret := C.gen_vips_Yxy2XYZ(input, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenAbs calls the vips abs operation. +// absolute value of an image +func vipsGenAbs(input *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("abs") + + var out_out *C.VipsImage + + ret := C.gen_vips_abs(input, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenAdd calls the vips add operation. +// add two images +func vipsGenAdd(left *C.VipsImage, right *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("add") + + var out_out *C.VipsImage + + ret := C.gen_vips_add(left, right, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// AffineOptions are optional parameters for affine. +type AffineOptions struct { + Interpolate *C.VipsInterpolate + Oarea []int + Odx *float64 + Ody *float64 + Idx *float64 + Idy *float64 + Background []float64 + Premultiplied *bool + Extend *ExtendStrategy +} + +// vipsGenAffine calls the vips affine operation. +// affine transform of an image +func vipsGenAffine(input *C.VipsImage, matrix []float64, opts *AffineOptions) (*C.VipsImage, error) { + incOpCounter("affine") + + var out_out *C.VipsImage + + var cOpts C.GenAffineOpts + var pinner runtime.Pinner + defer pinner.Unpin() + if opts != nil { + if opts.Interpolate != nil { + cOpts.has_interpolate = 1 + cOpts.interpolate = opts.Interpolate + } + if opts.Oarea != nil { + cOpts.has_oarea = 1 + pinner.Pin(&opts.Oarea[0]) + cOpts.oarea = (*C.int)(unsafe.Pointer(&opts.Oarea[0])) + cOpts.oarea_n = C.int(len(opts.Oarea)) + } + if opts.Odx != nil { + cOpts.has_odx = 1 + cOpts.odx = C.double(*opts.Odx) + } + if opts.Ody != nil { + cOpts.has_ody = 1 + cOpts.ody = C.double(*opts.Ody) + } + if opts.Idx != nil { + cOpts.has_idx = 1 + cOpts.idx = C.double(*opts.Idx) + } + if opts.Idy != nil { + cOpts.has_idy = 1 + cOpts.idy = C.double(*opts.Idy) + } + if opts.Background != nil { + cOpts.has_background = 1 + pinner.Pin(&opts.Background[0]) + cOpts.background = (*C.double)(unsafe.Pointer(&opts.Background[0])) + cOpts.background_n = C.int(len(opts.Background)) + } + if opts.Premultiplied != nil { + cOpts.has_premultiplied = 1 + cOpts.premultiplied = C.int(boolToInt(*opts.Premultiplied)) + } + if opts.Extend != nil { + cOpts.has_extend = 1 + cOpts.extend = C.VipsExtend(*opts.Extend) + } + } + + ret := C.gen_vips_affine(input, (*C.double)(unsafe.Pointer(&matrix[0])), C.int(len(matrix)), &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// ArrayjoinOptions are optional parameters for arrayjoin. +type ArrayjoinOptions struct { + Across *int + Shim *int + Background []float64 + Halign *Align + Valign *Align + Hspacing *int + Vspacing *int +} + +// vipsGenArrayjoin calls the vips arrayjoin operation. +// join an array of images +func vipsGenArrayjoin(input []*C.VipsImage, opts *ArrayjoinOptions) (*C.VipsImage, error) { + incOpCounter("arrayjoin") + + var out_out *C.VipsImage + + var cOpts C.GenArrayjoinOpts + var pinner runtime.Pinner + defer pinner.Unpin() + if opts != nil { + if opts.Across != nil { + cOpts.has_across = 1 + cOpts.across = C.int(*opts.Across) + } + if opts.Shim != nil { + cOpts.has_shim = 1 + cOpts.shim = C.int(*opts.Shim) + } + if opts.Background != nil { + cOpts.has_background = 1 + pinner.Pin(&opts.Background[0]) + cOpts.background = (*C.double)(unsafe.Pointer(&opts.Background[0])) + cOpts.background_n = C.int(len(opts.Background)) + } + if opts.Halign != nil { + cOpts.has_halign = 1 + cOpts.halign = C.VipsAlign(*opts.Halign) + } + if opts.Valign != nil { + cOpts.has_valign = 1 + cOpts.valign = C.VipsAlign(*opts.Valign) + } + if opts.Hspacing != nil { + cOpts.has_hspacing = 1 + cOpts.hspacing = C.int(*opts.Hspacing) + } + if opts.Vspacing != nil { + cOpts.has_vspacing = 1 + cOpts.vspacing = C.int(*opts.Vspacing) + } + } + + ret := C.gen_vips_arrayjoin((**C.VipsImage)(unsafe.Pointer(&input[0])), C.int(len(input)), &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenAutorot calls the vips autorot operation. +// autorotate image by exif tag +func vipsGenAutorot(input *C.VipsImage) (*C.VipsImage, Angle, bool, error) { + incOpCounter("autorot") + + var out_out *C.VipsImage + var out_angle C.int + var out_flip C.int + + ret := C.gen_vips_autorot(input, &out_out, &out_angle, &out_flip) + if ret != 0 { + return nil, 0, false, handleImageError(out_out) + } + + return out_out, Angle(out_angle), out_flip != 0, nil +} + +// vipsGenAvg calls the vips avg operation. +// find image average +func vipsGenAvg(input *C.VipsImage) (float64, error) { + incOpCounter("avg") + + var out_out C.double + + ret := C.gen_vips_avg(input, &out_out) + if ret != 0 { + return 0, handleVipsError() + } + + return float64(out_out), nil +} + +// vipsGenBandbool calls the vips bandbool operation. +// boolean operation across image bands +func vipsGenBandbool(input *C.VipsImage, boolean OperationBoolean) (*C.VipsImage, error) { + incOpCounter("bandbool") + + var out_out *C.VipsImage + + ret := C.gen_vips_bandbool(input, C.VipsOperationBoolean(boolean), &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// BandfoldOptions are optional parameters for bandfold. +type BandfoldOptions struct { + Factor *int +} + +// vipsGenBandfold calls the vips bandfold operation. +// fold up x axis into bands +func vipsGenBandfold(input *C.VipsImage, opts *BandfoldOptions) (*C.VipsImage, error) { + incOpCounter("bandfold") + + var out_out *C.VipsImage + + var cOpts C.GenBandfoldOpts + if opts != nil { + if opts.Factor != nil { + cOpts.has_factor = 1 + cOpts.factor = C.int(*opts.Factor) + } + } + + ret := C.gen_vips_bandfold(input, &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenBandjoin calls the vips bandjoin operation. +// bandwise join a set of images +func vipsGenBandjoin(input []*C.VipsImage) (*C.VipsImage, error) { + incOpCounter("bandjoin") + + var out_out *C.VipsImage + + ret := C.gen_vips_bandjoin((**C.VipsImage)(unsafe.Pointer(&input[0])), C.int(len(input)), &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenBandjoinConst calls the vips bandjoin_const operation. +// append a constant band to an image +func vipsGenBandjoinConst(input *C.VipsImage, c []float64) (*C.VipsImage, error) { + incOpCounter("bandjoin_const") + + var out_out *C.VipsImage + + ret := C.gen_vips_bandjoin_const(input, (*C.double)(unsafe.Pointer(&c[0])), C.int(len(c)), &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenBandmean calls the vips bandmean operation. +// band-wise average +func vipsGenBandmean(input *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("bandmean") + + var out_out *C.VipsImage + + ret := C.gen_vips_bandmean(input, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// BandrankOptions are optional parameters for bandrank. +type BandrankOptions struct { + Index *int +} + +// vipsGenBandrank calls the vips bandrank operation. +// band-wise rank of a set of images +func vipsGenBandrank(input []*C.VipsImage, opts *BandrankOptions) (*C.VipsImage, error) { + incOpCounter("bandrank") + + var out_out *C.VipsImage + + var cOpts C.GenBandrankOpts + if opts != nil { + if opts.Index != nil { + cOpts.has_index = 1 + cOpts.index = C.int(*opts.Index) + } + } + + ret := C.gen_vips_bandrank((**C.VipsImage)(unsafe.Pointer(&input[0])), C.int(len(input)), &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// BandunfoldOptions are optional parameters for bandunfold. +type BandunfoldOptions struct { + Factor *int +} + +// vipsGenBandunfold calls the vips bandunfold operation. +// unfold image bands into x axis +func vipsGenBandunfold(input *C.VipsImage, opts *BandunfoldOptions) (*C.VipsImage, error) { + incOpCounter("bandunfold") + + var out_out *C.VipsImage + + var cOpts C.GenBandunfoldOpts + if opts != nil { + if opts.Factor != nil { + cOpts.has_factor = 1 + cOpts.factor = C.int(*opts.Factor) + } + } + + ret := C.gen_vips_bandunfold(input, &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// BlackOptions are optional parameters for black. +type BlackOptions struct { + Bands *int +} + +// vipsGenBlack calls the vips black operation. +// make a black image +func vipsGenBlack(width int, height int, opts *BlackOptions) (*C.VipsImage, error) { + incOpCounter("black") + + var out_out *C.VipsImage + + var cOpts C.GenBlackOpts + if opts != nil { + if opts.Bands != nil { + cOpts.has_bands = 1 + cOpts.bands = C.int(*opts.Bands) + } + } + + ret := C.gen_vips_black(C.int(width), C.int(height), &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenBoolean calls the vips boolean operation. +// boolean operation on two images +func vipsGenBoolean(left *C.VipsImage, right *C.VipsImage, boolean OperationBoolean) (*C.VipsImage, error) { + incOpCounter("boolean") + + var out_out *C.VipsImage + + ret := C.gen_vips_boolean(left, right, C.VipsOperationBoolean(boolean), &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenBooleanConst calls the vips boolean_const operation. +// boolean operations against a constant +func vipsGenBooleanConst(input *C.VipsImage, boolean OperationBoolean, c []float64) (*C.VipsImage, error) { + incOpCounter("boolean_const") + + var out_out *C.VipsImage + + ret := C.gen_vips_boolean_const(input, C.VipsOperationBoolean(boolean), (*C.double)(unsafe.Pointer(&c[0])), C.int(len(c)), &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenBuildlut calls the vips buildlut operation. +// build a look-up table +func vipsGenBuildlut(input *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("buildlut") + + var out_out *C.VipsImage + + ret := C.gen_vips_buildlut(input, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenByteswap calls the vips byteswap operation. +// byteswap an image +func vipsGenByteswap(input *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("byteswap") + + var out_out *C.VipsImage + + ret := C.gen_vips_byteswap(input, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// CacheOptions are optional parameters for cache. +type CacheOptions struct { + MaxTiles *int + TileHeight *int + TileWidth *int +} + +// vipsGenCache calls the vips cache operation. +// cache an image +func vipsGenCache(input *C.VipsImage, opts *CacheOptions) (*C.VipsImage, error) { + incOpCounter("cache") + + var out_out *C.VipsImage + + var cOpts C.GenCacheOpts + if opts != nil { + if opts.MaxTiles != nil { + cOpts.has_maxTiles = 1 + cOpts.maxTiles = C.int(*opts.MaxTiles) + } + if opts.TileHeight != nil { + cOpts.has_tileHeight = 1 + cOpts.tileHeight = C.int(*opts.TileHeight) + } + if opts.TileWidth != nil { + cOpts.has_tileWidth = 1 + cOpts.tileWidth = C.int(*opts.TileWidth) + } + } + + ret := C.gen_vips_cache(input, &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// CannyOptions are optional parameters for canny. +type CannyOptions struct { + Sigma *float64 + Precision *Precision +} + +// vipsGenCanny calls the vips canny operation. +// Canny edge detector +func vipsGenCanny(input *C.VipsImage, opts *CannyOptions) (*C.VipsImage, error) { + incOpCounter("canny") + + var out_out *C.VipsImage + + var cOpts C.GenCannyOpts + if opts != nil { + if opts.Sigma != nil { + cOpts.has_sigma = 1 + cOpts.sigma = C.double(*opts.Sigma) + } + if opts.Precision != nil { + cOpts.has_precision = 1 + cOpts.precision = C.VipsPrecision(*opts.Precision) + } + } + + ret := C.gen_vips_canny(input, &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// CastOptions are optional parameters for cast. +type CastOptions struct { + Shift *bool +} + +// vipsGenCast calls the vips cast operation. +// cast an image +func vipsGenCast(input *C.VipsImage, format BandFormat, opts *CastOptions) (*C.VipsImage, error) { + incOpCounter("cast") + + var out_out *C.VipsImage + + var cOpts C.GenCastOpts + if opts != nil { + if opts.Shift != nil { + cOpts.has_shift = 1 + cOpts.shift = C.int(boolToInt(*opts.Shift)) + } + } + + ret := C.gen_vips_cast(input, C.VipsBandFormat(format), &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// ClampOptions are optional parameters for clamp. +type ClampOptions struct { + Min *float64 + Max *float64 +} + +// vipsGenClamp calls the vips clamp operation. +// clamp values of an image +func vipsGenClamp(input *C.VipsImage, opts *ClampOptions) (*C.VipsImage, error) { + incOpCounter("clamp") + + var out_out *C.VipsImage + + var cOpts C.GenClampOpts + if opts != nil { + if opts.Min != nil { + cOpts.has_min = 1 + cOpts.min = C.double(*opts.Min) + } + if opts.Max != nil { + cOpts.has_max = 1 + cOpts.max = C.double(*opts.Max) + } + } + + ret := C.gen_vips_clamp(input, &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// CompassOptions are optional parameters for compass. +type CompassOptions struct { + Times *int + Angle *Angle45 + Combine *Combine + Precision *Precision + Layers *int + Cluster *int +} + +// vipsGenCompass calls the vips compass operation. +// convolve with rotating mask +func vipsGenCompass(input *C.VipsImage, mask *C.VipsImage, opts *CompassOptions) (*C.VipsImage, error) { + incOpCounter("compass") + + var out_out *C.VipsImage + + var cOpts C.GenCompassOpts + if opts != nil { + if opts.Times != nil { + cOpts.has_times = 1 + cOpts.times = C.int(*opts.Times) + } + if opts.Angle != nil { + cOpts.has_angle = 1 + cOpts.angle = C.VipsAngle45(*opts.Angle) + } + if opts.Combine != nil { + cOpts.has_combine = 1 + cOpts.combine = C.VipsCombine(*opts.Combine) + } + if opts.Precision != nil { + cOpts.has_precision = 1 + cOpts.precision = C.VipsPrecision(*opts.Precision) + } + if opts.Layers != nil { + cOpts.has_layers = 1 + cOpts.layers = C.int(*opts.Layers) + } + if opts.Cluster != nil { + cOpts.has_cluster = 1 + cOpts.cluster = C.int(*opts.Cluster) + } + } + + ret := C.gen_vips_compass(input, mask, &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenComplex calls the vips complex operation. +// perform a complex operation on an image +func vipsGenComplex(input *C.VipsImage, cmplx OperationComplex) (*C.VipsImage, error) { + incOpCounter("complex") + + var out_out *C.VipsImage + + ret := C.gen_vips_complex(input, C.VipsOperationComplex(cmplx), &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenComplex2 calls the vips complex2 operation. +// complex binary operations on two images +func vipsGenComplex2(left *C.VipsImage, right *C.VipsImage, cmplx OperationComplex2) (*C.VipsImage, error) { + incOpCounter("complex2") + + var out_out *C.VipsImage + + ret := C.gen_vips_complex2(left, right, C.VipsOperationComplex2(cmplx), &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenComplexform calls the vips complexform operation. +// form a complex image from two real images +func vipsGenComplexform(left *C.VipsImage, right *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("complexform") + + var out_out *C.VipsImage + + ret := C.gen_vips_complexform(left, right, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenComplexget calls the vips complexget operation. +// get a component from a complex image +func vipsGenComplexget(input *C.VipsImage, get OperationComplexget) (*C.VipsImage, error) { + incOpCounter("complexget") + + var out_out *C.VipsImage + + ret := C.gen_vips_complexget(input, C.VipsOperationComplexget(get), &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// Composite2Options are optional parameters for composite2. +type Composite2Options struct { + X *int + Y *int + CompositingSpace *Interpretation + Premultiplied *bool +} + +// vipsGenComposite2 calls the vips composite2 operation. +// blend a pair of images with a blend mode +func vipsGenComposite2(base *C.VipsImage, overlay *C.VipsImage, mode BlendMode, opts *Composite2Options) (*C.VipsImage, error) { + incOpCounter("composite2") + + var out_out *C.VipsImage + + var cOpts C.GenComposite2Opts + if opts != nil { + if opts.X != nil { + cOpts.has_x = 1 + cOpts.x = C.int(*opts.X) + } + if opts.Y != nil { + cOpts.has_y = 1 + cOpts.y = C.int(*opts.Y) + } + if opts.CompositingSpace != nil { + cOpts.has_compositingSpace = 1 + cOpts.compositingSpace = C.VipsInterpretation(*opts.CompositingSpace) + } + if opts.Premultiplied != nil { + cOpts.has_premultiplied = 1 + cOpts.premultiplied = C.int(boolToInt(*opts.Premultiplied)) + } + } + + ret := C.gen_vips_composite2(base, overlay, C.VipsBlendMode(mode), &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// ConvOptions are optional parameters for conv. +type ConvOptions struct { + Precision *Precision + Layers *int + Cluster *int +} + +// vipsGenConv calls the vips conv operation. +// convolution operation +func vipsGenConv(input *C.VipsImage, mask *C.VipsImage, opts *ConvOptions) (*C.VipsImage, error) { + incOpCounter("conv") + + var out_out *C.VipsImage + + var cOpts C.GenConvOpts + if opts != nil { + if opts.Precision != nil { + cOpts.has_precision = 1 + cOpts.precision = C.VipsPrecision(*opts.Precision) + } + if opts.Layers != nil { + cOpts.has_layers = 1 + cOpts.layers = C.int(*opts.Layers) + } + if opts.Cluster != nil { + cOpts.has_cluster = 1 + cOpts.cluster = C.int(*opts.Cluster) + } + } + + ret := C.gen_vips_conv(input, mask, &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// ConvaOptions are optional parameters for conva. +type ConvaOptions struct { + Layers *int + Cluster *int +} + +// vipsGenConva calls the vips conva operation. +// approximate integer convolution +func vipsGenConva(input *C.VipsImage, mask *C.VipsImage, opts *ConvaOptions) (*C.VipsImage, error) { + incOpCounter("conva") + + var out_out *C.VipsImage + + var cOpts C.GenConvaOpts + if opts != nil { + if opts.Layers != nil { + cOpts.has_layers = 1 + cOpts.layers = C.int(*opts.Layers) + } + if opts.Cluster != nil { + cOpts.has_cluster = 1 + cOpts.cluster = C.int(*opts.Cluster) + } + } + + ret := C.gen_vips_conva(input, mask, &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// ConvasepOptions are optional parameters for convasep. +type ConvasepOptions struct { + Layers *int +} + +// vipsGenConvasep calls the vips convasep operation. +// approximate separable integer convolution +func vipsGenConvasep(input *C.VipsImage, mask *C.VipsImage, opts *ConvasepOptions) (*C.VipsImage, error) { + incOpCounter("convasep") + + var out_out *C.VipsImage + + var cOpts C.GenConvasepOpts + if opts != nil { + if opts.Layers != nil { + cOpts.has_layers = 1 + cOpts.layers = C.int(*opts.Layers) + } + } + + ret := C.gen_vips_convasep(input, mask, &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenConvf calls the vips convf operation. +// float convolution operation +func vipsGenConvf(input *C.VipsImage, mask *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("convf") + + var out_out *C.VipsImage + + ret := C.gen_vips_convf(input, mask, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenConvi calls the vips convi operation. +// int convolution operation +func vipsGenConvi(input *C.VipsImage, mask *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("convi") + + var out_out *C.VipsImage + + ret := C.gen_vips_convi(input, mask, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// ConvsepOptions are optional parameters for convsep. +type ConvsepOptions struct { + Precision *Precision + Layers *int + Cluster *int +} + +// vipsGenConvsep calls the vips convsep operation. +// separable convolution operation +func vipsGenConvsep(input *C.VipsImage, mask *C.VipsImage, opts *ConvsepOptions) (*C.VipsImage, error) { + incOpCounter("convsep") + + var out_out *C.VipsImage + + var cOpts C.GenConvsepOpts + if opts != nil { + if opts.Precision != nil { + cOpts.has_precision = 1 + cOpts.precision = C.VipsPrecision(*opts.Precision) + } + if opts.Layers != nil { + cOpts.has_layers = 1 + cOpts.layers = C.int(*opts.Layers) + } + if opts.Cluster != nil { + cOpts.has_cluster = 1 + cOpts.cluster = C.int(*opts.Cluster) + } + } + + ret := C.gen_vips_convsep(input, mask, &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// CopyOptions are optional parameters for copy. +type CopyOptions struct { + Width *int + Height *int + Bands *int + Format *BandFormat + Coding *Coding + Interpretation *Interpretation + Xres *float64 + Yres *float64 + Xoffset *int + Yoffset *int +} + +// vipsGenCopy calls the vips copy operation. +// copy an image +func vipsGenCopy(input *C.VipsImage, opts *CopyOptions) (*C.VipsImage, error) { + incOpCounter("copy") + + var out_out *C.VipsImage + + var cOpts C.GenCopyOpts + if opts != nil { + if opts.Width != nil { + cOpts.has_width = 1 + cOpts.width = C.int(*opts.Width) + } + if opts.Height != nil { + cOpts.has_height = 1 + cOpts.height = C.int(*opts.Height) + } + if opts.Bands != nil { + cOpts.has_bands = 1 + cOpts.bands = C.int(*opts.Bands) + } + if opts.Format != nil { + cOpts.has_format = 1 + cOpts.format = C.VipsBandFormat(*opts.Format) + } + if opts.Coding != nil { + cOpts.has_coding = 1 + cOpts.coding = C.VipsCoding(*opts.Coding) + } + if opts.Interpretation != nil { + cOpts.has_interpretation = 1 + cOpts.interpretation = C.VipsInterpretation(*opts.Interpretation) + } + if opts.Xres != nil { + cOpts.has_xres = 1 + cOpts.xres = C.double(*opts.Xres) + } + if opts.Yres != nil { + cOpts.has_yres = 1 + cOpts.yres = C.double(*opts.Yres) + } + if opts.Xoffset != nil { + cOpts.has_xoffset = 1 + cOpts.xoffset = C.int(*opts.Xoffset) + } + if opts.Yoffset != nil { + cOpts.has_yoffset = 1 + cOpts.yoffset = C.int(*opts.Yoffset) + } + } + + ret := C.gen_vips_copy(input, &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenCountlines calls the vips countlines operation. +// count lines in an image +func vipsGenCountlines(input *C.VipsImage, direction Direction) (float64, error) { + incOpCounter("countlines") + + var out_nolines C.double + + ret := C.gen_vips_countlines(input, C.VipsDirection(direction), &out_nolines) + if ret != 0 { + return 0, handleVipsError() + } + + return float64(out_nolines), nil +} + +// vipsGenDE00 calls the vips dE00 operation. +// calculate dE00 +func vipsGenDE00(left *C.VipsImage, right *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("dE00") + + var out_out *C.VipsImage + + ret := C.gen_vips_dE00(left, right, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenDE76 calls the vips dE76 operation. +// calculate dE76 +func vipsGenDE76(left *C.VipsImage, right *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("dE76") + + var out_out *C.VipsImage + + ret := C.gen_vips_dE76(left, right, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenDECMC calls the vips dECMC operation. +// calculate dECMC +func vipsGenDECMC(left *C.VipsImage, right *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("dECMC") + + var out_out *C.VipsImage + + ret := C.gen_vips_dECMC(left, right, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenDeviate calls the vips deviate operation. +// find image standard deviation +func vipsGenDeviate(input *C.VipsImage) (float64, error) { + incOpCounter("deviate") + + var out_out C.double + + ret := C.gen_vips_deviate(input, &out_out) + if ret != 0 { + return 0, handleVipsError() + } + + return float64(out_out), nil +} + +// vipsGenDivide calls the vips divide operation. +// divide two images +func vipsGenDivide(left *C.VipsImage, right *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("divide") + + var out_out *C.VipsImage + + ret := C.gen_vips_divide(left, right, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenExtractArea calls the vips extract_area operation. +// extract an area from an image +func vipsGenExtractArea(input *C.VipsImage, left int, top int, width int, height int) (*C.VipsImage, error) { + incOpCounter("extract_area") + + var out_out *C.VipsImage + + ret := C.gen_vips_extract_area(input, C.int(left), C.int(top), C.int(width), C.int(height), &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// ExtractBandOptions are optional parameters for extract_band. +type ExtractBandOptions struct { + N *int +} + +// vipsGenExtractBand calls the vips extract_band operation. +// extract band from an image +func vipsGenExtractBand(input *C.VipsImage, band int, opts *ExtractBandOptions) (*C.VipsImage, error) { + incOpCounter("extract_band") + + var out_out *C.VipsImage + + var cOpts C.GenExtractBandOpts + if opts != nil { + if opts.N != nil { + cOpts.has_n = 1 + cOpts.n = C.int(*opts.N) + } + } + + ret := C.gen_vips_extract_band(input, C.int(band), &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// EyeOptions are optional parameters for eye. +type EyeOptions struct { + Uchar *bool + Factor *float64 +} + +// vipsGenEye calls the vips eye operation. +// make an image showing the eye's spatial response +func vipsGenEye(width int, height int, opts *EyeOptions) (*C.VipsImage, error) { + incOpCounter("eye") + + var out_out *C.VipsImage + + var cOpts C.GenEyeOpts + if opts != nil { + if opts.Uchar != nil { + cOpts.has_uchar = 1 + cOpts.uchar = C.int(boolToInt(*opts.Uchar)) + } + if opts.Factor != nil { + cOpts.has_factor = 1 + cOpts.factor = C.double(*opts.Factor) + } + } + + ret := C.gen_vips_eye(C.int(width), C.int(height), &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenFalsecolour calls the vips falsecolour operation. +// false-color an image +func vipsGenFalsecolour(input *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("falsecolour") + + var out_out *C.VipsImage + + ret := C.gen_vips_falsecolour(input, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenFastcor calls the vips fastcor operation. +// fast correlation +func vipsGenFastcor(input *C.VipsImage, ref *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("fastcor") + + var out_out *C.VipsImage + + ret := C.gen_vips_fastcor(input, ref, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenFillNearest calls the vips fill_nearest operation. +// fill image zeros with nearest non-zero pixel +func vipsGenFillNearest(input *C.VipsImage) (*C.VipsImage, *C.VipsImage, error) { + incOpCounter("fill_nearest") + + var out_out *C.VipsImage + var out_distance *C.VipsImage + + ret := C.gen_vips_fill_nearest(input, &out_out, &out_distance) + if ret != 0 { + return nil, nil, handleImageError(out_out) + } + + return out_out, out_distance, nil +} + +// FlattenOptions are optional parameters for flatten. +type FlattenOptions struct { + Background []float64 + MaxAlpha *float64 +} + +// vipsGenFlatten calls the vips flatten operation. +// flatten alpha out of an image +func vipsGenFlatten(input *C.VipsImage, opts *FlattenOptions) (*C.VipsImage, error) { + incOpCounter("flatten") + + var out_out *C.VipsImage + + var cOpts C.GenFlattenOpts + var pinner runtime.Pinner + defer pinner.Unpin() + if opts != nil { + if opts.Background != nil { + cOpts.has_background = 1 + pinner.Pin(&opts.Background[0]) + cOpts.background = (*C.double)(unsafe.Pointer(&opts.Background[0])) + cOpts.background_n = C.int(len(opts.Background)) + } + if opts.MaxAlpha != nil { + cOpts.has_maxAlpha = 1 + cOpts.maxAlpha = C.double(*opts.MaxAlpha) + } + } + + ret := C.gen_vips_flatten(input, &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenFlip calls the vips flip operation. +// flip an image +func vipsGenFlip(input *C.VipsImage, direction Direction) (*C.VipsImage, error) { + incOpCounter("flip") + + var out_out *C.VipsImage + + ret := C.gen_vips_flip(input, C.VipsDirection(direction), &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenFloat2rad calls the vips float2rad operation. +// transform float RGB to Radiance coding +func vipsGenFloat2rad(input *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("float2rad") + + var out_out *C.VipsImage + + ret := C.gen_vips_float2rad(input, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenFractsurf calls the vips fractsurf operation. +// make a fractal surface +func vipsGenFractsurf(width int, height int, fractalDimension float64) (*C.VipsImage, error) { + incOpCounter("fractsurf") + + var out_out *C.VipsImage + + ret := C.gen_vips_fractsurf(C.int(width), C.int(height), C.double(fractalDimension), &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenFreqmult calls the vips freqmult operation. +// frequency-domain filtering +func vipsGenFreqmult(input *C.VipsImage, mask *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("freqmult") + + var out_out *C.VipsImage + + ret := C.gen_vips_freqmult(input, mask, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenFwfft calls the vips fwfft operation. +// forward FFT +func vipsGenFwfft(input *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("fwfft") + + var out_out *C.VipsImage + + ret := C.gen_vips_fwfft(input, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// GammaOptions are optional parameters for gamma. +type GammaOptions struct { + Exponent *float64 +} + +// vipsGenGamma calls the vips gamma operation. +// gamma an image +func vipsGenGamma(input *C.VipsImage, opts *GammaOptions) (*C.VipsImage, error) { + incOpCounter("gamma") + + var out_out *C.VipsImage + + var cOpts C.GenGammaOpts + if opts != nil { + if opts.Exponent != nil { + cOpts.has_exponent = 1 + cOpts.exponent = C.double(*opts.Exponent) + } + } + + ret := C.gen_vips_gamma(input, &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// GaussblurOptions are optional parameters for gaussblur. +type GaussblurOptions struct { + MinAmpl *float64 + Precision *Precision +} + +// vipsGenGaussblur calls the vips gaussblur operation. +// gaussian blur +func vipsGenGaussblur(input *C.VipsImage, sigma float64, opts *GaussblurOptions) (*C.VipsImage, error) { + incOpCounter("gaussblur") + + var out_out *C.VipsImage + + var cOpts C.GenGaussblurOpts + if opts != nil { + if opts.MinAmpl != nil { + cOpts.has_minAmpl = 1 + cOpts.minAmpl = C.double(*opts.MinAmpl) + } + if opts.Precision != nil { + cOpts.has_precision = 1 + cOpts.precision = C.VipsPrecision(*opts.Precision) + } + } + + ret := C.gen_vips_gaussblur(input, C.double(sigma), &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// GaussmatOptions are optional parameters for gaussmat. +type GaussmatOptions struct { + Separable *bool + Precision *Precision +} + +// vipsGenGaussmat calls the vips gaussmat operation. +// make a gaussian image +func vipsGenGaussmat(sigma float64, minAmpl float64, opts *GaussmatOptions) (*C.VipsImage, error) { + incOpCounter("gaussmat") + + var out_out *C.VipsImage + + var cOpts C.GenGaussmatOpts + if opts != nil { + if opts.Separable != nil { + cOpts.has_separable = 1 + cOpts.separable = C.int(boolToInt(*opts.Separable)) + } + if opts.Precision != nil { + cOpts.has_precision = 1 + cOpts.precision = C.VipsPrecision(*opts.Precision) + } + } + + ret := C.gen_vips_gaussmat(C.double(sigma), C.double(minAmpl), &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// GaussnoiseOptions are optional parameters for gaussnoise. +type GaussnoiseOptions struct { + Sigma *float64 + Mean *float64 + Seed *int +} + +// vipsGenGaussnoise calls the vips gaussnoise operation. +// make a gaussnoise image +func vipsGenGaussnoise(width int, height int, opts *GaussnoiseOptions) (*C.VipsImage, error) { + incOpCounter("gaussnoise") + + var out_out *C.VipsImage + + var cOpts C.GenGaussnoiseOpts + if opts != nil { + if opts.Sigma != nil { + cOpts.has_sigma = 1 + cOpts.sigma = C.double(*opts.Sigma) + } + if opts.Mean != nil { + cOpts.has_mean = 1 + cOpts.mean = C.double(*opts.Mean) + } + if opts.Seed != nil { + cOpts.has_seed = 1 + cOpts.seed = C.int(*opts.Seed) + } + } + + ret := C.gen_vips_gaussnoise(C.int(width), C.int(height), &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// GlobalbalanceOptions are optional parameters for globalbalance. +type GlobalbalanceOptions struct { + Gamma *float64 + IntOutput *bool +} + +// vipsGenGlobalbalance calls the vips globalbalance operation. +// global balance an image mosaic +func vipsGenGlobalbalance(input *C.VipsImage, opts *GlobalbalanceOptions) (*C.VipsImage, error) { + incOpCounter("globalbalance") + + var out_out *C.VipsImage + + var cOpts C.GenGlobalbalanceOpts + if opts != nil { + if opts.Gamma != nil { + cOpts.has_gamma = 1 + cOpts.gamma = C.double(*opts.Gamma) + } + if opts.IntOutput != nil { + cOpts.has_intOutput = 1 + cOpts.intOutput = C.int(boolToInt(*opts.IntOutput)) + } + } + + ret := C.gen_vips_globalbalance(input, &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// GravityOptions are optional parameters for gravity. +type GravityOptions struct { + Extend *ExtendStrategy + Background []float64 +} + +// vipsGenGravity calls the vips gravity operation. +// place an image within a larger image with a certain gravity +func vipsGenGravity(input *C.VipsImage, direction Gravity, width int, height int, opts *GravityOptions) (*C.VipsImage, error) { + incOpCounter("gravity") + + var out_out *C.VipsImage + + var cOpts C.GenGravityOpts + var pinner runtime.Pinner + defer pinner.Unpin() + if opts != nil { + if opts.Extend != nil { + cOpts.has_extend = 1 + cOpts.extend = C.VipsExtend(*opts.Extend) + } + if opts.Background != nil { + cOpts.has_background = 1 + pinner.Pin(&opts.Background[0]) + cOpts.background = (*C.double)(unsafe.Pointer(&opts.Background[0])) + cOpts.background_n = C.int(len(opts.Background)) + } + } + + ret := C.gen_vips_gravity(input, C.VipsCompassDirection(direction), C.int(width), C.int(height), &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// GreyOptions are optional parameters for grey. +type GreyOptions struct { + Uchar *bool +} + +// vipsGenGrey calls the vips grey operation. +// make a grey ramp image +func vipsGenGrey(width int, height int, opts *GreyOptions) (*C.VipsImage, error) { + incOpCounter("grey") + + var out_out *C.VipsImage + + var cOpts C.GenGreyOpts + if opts != nil { + if opts.Uchar != nil { + cOpts.has_uchar = 1 + cOpts.uchar = C.int(boolToInt(*opts.Uchar)) + } + } + + ret := C.gen_vips_grey(C.int(width), C.int(height), &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenGrid calls the vips grid operation. +// grid an image +func vipsGenGrid(input *C.VipsImage, tileHeight int, across int, down int) (*C.VipsImage, error) { + incOpCounter("grid") + + var out_out *C.VipsImage + + ret := C.gen_vips_grid(input, C.int(tileHeight), C.int(across), C.int(down), &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenHistCum calls the vips hist_cum operation. +// form cumulative histogram +func vipsGenHistCum(input *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("hist_cum") + + var out_out *C.VipsImage + + ret := C.gen_vips_hist_cum(input, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenHistEntropy calls the vips hist_entropy operation. +// estimate image entropy +func vipsGenHistEntropy(input *C.VipsImage) (float64, error) { + incOpCounter("hist_entropy") + + var out_out C.double + + ret := C.gen_vips_hist_entropy(input, &out_out) + if ret != 0 { + return 0, handleVipsError() + } + + return float64(out_out), nil +} + +// HistEqualOptions are optional parameters for hist_equal. +type HistEqualOptions struct { + Band *int +} + +// vipsGenHistEqual calls the vips hist_equal operation. +// histogram equalisation +func vipsGenHistEqual(input *C.VipsImage, opts *HistEqualOptions) (*C.VipsImage, error) { + incOpCounter("hist_equal") + + var out_out *C.VipsImage + + var cOpts C.GenHistEqualOpts + if opts != nil { + if opts.Band != nil { + cOpts.has_band = 1 + cOpts.band = C.int(*opts.Band) + } + } + + ret := C.gen_vips_hist_equal(input, &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// HistFindOptions are optional parameters for hist_find. +type HistFindOptions struct { + Band *int +} + +// vipsGenHistFind calls the vips hist_find operation. +// find image histogram +func vipsGenHistFind(input *C.VipsImage, opts *HistFindOptions) (*C.VipsImage, error) { + incOpCounter("hist_find") + + var out_out *C.VipsImage + + var cOpts C.GenHistFindOpts + if opts != nil { + if opts.Band != nil { + cOpts.has_band = 1 + cOpts.band = C.int(*opts.Band) + } + } + + ret := C.gen_vips_hist_find(input, &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// HistFindIndexedOptions are optional parameters for hist_find_indexed. +type HistFindIndexedOptions struct { + Combine *Combine +} + +// vipsGenHistFindIndexed calls the vips hist_find_indexed operation. +// find indexed image histogram +func vipsGenHistFindIndexed(input *C.VipsImage, index *C.VipsImage, opts *HistFindIndexedOptions) (*C.VipsImage, error) { + incOpCounter("hist_find_indexed") + + var out_out *C.VipsImage + + var cOpts C.GenHistFindIndexedOpts + if opts != nil { + if opts.Combine != nil { + cOpts.has_combine = 1 + cOpts.combine = C.VipsCombine(*opts.Combine) + } + } + + ret := C.gen_vips_hist_find_indexed(input, index, &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// HistFindNdimOptions are optional parameters for hist_find_ndim. +type HistFindNdimOptions struct { + Bins *int +} + +// vipsGenHistFindNdim calls the vips hist_find_ndim operation. +// find n-dimensional image histogram +func vipsGenHistFindNdim(input *C.VipsImage, opts *HistFindNdimOptions) (*C.VipsImage, error) { + incOpCounter("hist_find_ndim") + + var out_out *C.VipsImage + + var cOpts C.GenHistFindNdimOpts + if opts != nil { + if opts.Bins != nil { + cOpts.has_bins = 1 + cOpts.bins = C.int(*opts.Bins) + } + } + + ret := C.gen_vips_hist_find_ndim(input, &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenHistIsmonotonic calls the vips hist_ismonotonic operation. +// test for monotonicity +func vipsGenHistIsmonotonic(input *C.VipsImage) (bool, error) { + incOpCounter("hist_ismonotonic") + + var out_monotonic C.int + + ret := C.gen_vips_hist_ismonotonic(input, &out_monotonic) + if ret != 0 { + return false, handleVipsError() + } + + return out_monotonic != 0, nil +} + +// HistLocalOptions are optional parameters for hist_local. +type HistLocalOptions struct { + MaxSlope *int +} + +// vipsGenHistLocal calls the vips hist_local operation. +// local histogram equalisation +func vipsGenHistLocal(input *C.VipsImage, width int, height int, opts *HistLocalOptions) (*C.VipsImage, error) { + incOpCounter("hist_local") + + var out_out *C.VipsImage + + var cOpts C.GenHistLocalOpts + if opts != nil { + if opts.MaxSlope != nil { + cOpts.has_maxSlope = 1 + cOpts.maxSlope = C.int(*opts.MaxSlope) + } + } + + ret := C.gen_vips_hist_local(input, C.int(width), C.int(height), &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenHistMatch calls the vips hist_match operation. +// match two histograms +func vipsGenHistMatch(input *C.VipsImage, ref *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("hist_match") + + var out_out *C.VipsImage + + ret := C.gen_vips_hist_match(input, ref, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenHistNorm calls the vips hist_norm operation. +// normalise histogram +func vipsGenHistNorm(input *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("hist_norm") + + var out_out *C.VipsImage + + ret := C.gen_vips_hist_norm(input, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenHistPlot calls the vips hist_plot operation. +// plot histogram +func vipsGenHistPlot(input *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("hist_plot") + + var out_out *C.VipsImage + + ret := C.gen_vips_hist_plot(input, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// HoughCircleOptions are optional parameters for hough_circle. +type HoughCircleOptions struct { + Scale *int + MinRadius *int + MaxRadius *int +} + +// vipsGenHoughCircle calls the vips hough_circle operation. +// find hough circle transform +func vipsGenHoughCircle(input *C.VipsImage, opts *HoughCircleOptions) (*C.VipsImage, error) { + incOpCounter("hough_circle") + + var out_out *C.VipsImage + + var cOpts C.GenHoughCircleOpts + if opts != nil { + if opts.Scale != nil { + cOpts.has_scale = 1 + cOpts.scale = C.int(*opts.Scale) + } + if opts.MinRadius != nil { + cOpts.has_minRadius = 1 + cOpts.minRadius = C.int(*opts.MinRadius) + } + if opts.MaxRadius != nil { + cOpts.has_maxRadius = 1 + cOpts.maxRadius = C.int(*opts.MaxRadius) + } + } + + ret := C.gen_vips_hough_circle(input, &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// HoughLineOptions are optional parameters for hough_line. +type HoughLineOptions struct { + Width *int + Height *int +} + +// vipsGenHoughLine calls the vips hough_line operation. +// find hough line transform +func vipsGenHoughLine(input *C.VipsImage, opts *HoughLineOptions) (*C.VipsImage, error) { + incOpCounter("hough_line") + + var out_out *C.VipsImage + + var cOpts C.GenHoughLineOpts + if opts != nil { + if opts.Width != nil { + cOpts.has_width = 1 + cOpts.width = C.int(*opts.Width) + } + if opts.Height != nil { + cOpts.has_height = 1 + cOpts.height = C.int(*opts.Height) + } + } + + ret := C.gen_vips_hough_line(input, &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// IccExportOptions are optional parameters for icc_export. +type IccExportOptions struct { + Pcs *int + Intent *Intent + BlackPointCompensation *bool + OutputProfile *string + Depth *int +} + +// vipsGenIccExport calls the vips icc_export operation. +// output to device with ICC profile +func vipsGenIccExport(input *C.VipsImage, opts *IccExportOptions) (*C.VipsImage, error) { + incOpCounter("icc_export") + + var out_out *C.VipsImage + + var cOpts C.GenIccExportOpts + if opts != nil { + if opts.Pcs != nil { + cOpts.has_pcs = 1 + cOpts.pcs = C.VipsPCS(*opts.Pcs) + } + if opts.Intent != nil { + cOpts.has_intent = 1 + cOpts.intent = C.VipsIntent(*opts.Intent) + } + if opts.BlackPointCompensation != nil { + cOpts.has_blackPointCompensation = 1 + cOpts.blackPointCompensation = C.int(boolToInt(*opts.BlackPointCompensation)) + } + if opts.OutputProfile != nil { + cOpts.has_outputProfile = 1 + tmp_outputProfile := C.CString(*opts.OutputProfile) + defer C.free(unsafe.Pointer(tmp_outputProfile)) + cOpts.outputProfile = tmp_outputProfile + } + if opts.Depth != nil { + cOpts.has_depth = 1 + cOpts.depth = C.int(*opts.Depth) + } + } + + ret := C.gen_vips_icc_export(input, &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// IccImportOptions are optional parameters for icc_import. +type IccImportOptions struct { + Pcs *int + Intent *Intent + BlackPointCompensation *bool + Embedded *bool + InputProfile *string +} + +// vipsGenIccImport calls the vips icc_import operation. +// import from device with ICC profile +func vipsGenIccImport(input *C.VipsImage, opts *IccImportOptions) (*C.VipsImage, error) { + incOpCounter("icc_import") + + var out_out *C.VipsImage + + var cOpts C.GenIccImportOpts + if opts != nil { + if opts.Pcs != nil { + cOpts.has_pcs = 1 + cOpts.pcs = C.VipsPCS(*opts.Pcs) + } + if opts.Intent != nil { + cOpts.has_intent = 1 + cOpts.intent = C.VipsIntent(*opts.Intent) + } + if opts.BlackPointCompensation != nil { + cOpts.has_blackPointCompensation = 1 + cOpts.blackPointCompensation = C.int(boolToInt(*opts.BlackPointCompensation)) + } + if opts.Embedded != nil { + cOpts.has_embedded = 1 + cOpts.embedded = C.int(boolToInt(*opts.Embedded)) + } + if opts.InputProfile != nil { + cOpts.has_inputProfile = 1 + tmp_inputProfile := C.CString(*opts.InputProfile) + defer C.free(unsafe.Pointer(tmp_inputProfile)) + cOpts.inputProfile = tmp_inputProfile + } + } + + ret := C.gen_vips_icc_import(input, &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// IdentityOptions are optional parameters for identity. +type IdentityOptions struct { + Bands *int + Ushort *bool + Size *int +} + +// vipsGenIdentity calls the vips identity operation. +// make a 1D image where pixel values are indexes +func vipsGenIdentity(opts *IdentityOptions) (*C.VipsImage, error) { + incOpCounter("identity") + + var out_out *C.VipsImage + + var cOpts C.GenIdentityOpts + if opts != nil { + if opts.Bands != nil { + cOpts.has_bands = 1 + cOpts.bands = C.int(*opts.Bands) + } + if opts.Ushort != nil { + cOpts.has_ushort = 1 + cOpts.ushort = C.int(boolToInt(*opts.Ushort)) + } + if opts.Size != nil { + cOpts.has_size = 1 + cOpts.size = C.int(*opts.Size) + } + } + + ret := C.gen_vips_identity(&out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// IfthenelseOptions are optional parameters for ifthenelse. +type IfthenelseOptions struct { + Blend *bool +} + +// vipsGenIfthenelse calls the vips ifthenelse operation. +// ifthenelse an image +func vipsGenIfthenelse(cond *C.VipsImage, in1 *C.VipsImage, in2 *C.VipsImage, opts *IfthenelseOptions) (*C.VipsImage, error) { + incOpCounter("ifthenelse") + + var out_out *C.VipsImage + + var cOpts C.GenIfthenelseOpts + if opts != nil { + if opts.Blend != nil { + cOpts.has_blend = 1 + cOpts.blend = C.int(boolToInt(*opts.Blend)) + } + } + + ret := C.gen_vips_ifthenelse(cond, in1, in2, &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// InsertOptions are optional parameters for insert. +type InsertOptions struct { + Expand *bool + Background []float64 +} + +// vipsGenInsert calls the vips insert operation. +// insert image @sub into @main at @x, @y +func vipsGenInsert(main *C.VipsImage, sub *C.VipsImage, x int, y int, opts *InsertOptions) (*C.VipsImage, error) { + incOpCounter("insert") + + var out_out *C.VipsImage + + var cOpts C.GenInsertOpts + var pinner runtime.Pinner + defer pinner.Unpin() + if opts != nil { + if opts.Expand != nil { + cOpts.has_expand = 1 + cOpts.expand = C.int(boolToInt(*opts.Expand)) + } + if opts.Background != nil { + cOpts.has_background = 1 + pinner.Pin(&opts.Background[0]) + cOpts.background = (*C.double)(unsafe.Pointer(&opts.Background[0])) + cOpts.background_n = C.int(len(opts.Background)) + } + } + + ret := C.gen_vips_insert(main, sub, C.int(x), C.int(y), &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenInvert calls the vips invert operation. +// invert an image +func vipsGenInvert(input *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("invert") + + var out_out *C.VipsImage + + ret := C.gen_vips_invert(input, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// InvertlutOptions are optional parameters for invertlut. +type InvertlutOptions struct { + Size *int +} + +// vipsGenInvertlut calls the vips invertlut operation. +// build an inverted look-up table +func vipsGenInvertlut(input *C.VipsImage, opts *InvertlutOptions) (*C.VipsImage, error) { + incOpCounter("invertlut") + + var out_out *C.VipsImage + + var cOpts C.GenInvertlutOpts + if opts != nil { + if opts.Size != nil { + cOpts.has_size = 1 + cOpts.size = C.int(*opts.Size) + } + } + + ret := C.gen_vips_invertlut(input, &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// InvfftOptions are optional parameters for invfft. +type InvfftOptions struct { + Real *bool +} + +// vipsGenInvfft calls the vips invfft operation. +// inverse FFT +func vipsGenInvfft(input *C.VipsImage, opts *InvfftOptions) (*C.VipsImage, error) { + incOpCounter("invfft") + + var out_out *C.VipsImage + + var cOpts C.GenInvfftOpts + if opts != nil { + if opts.Real != nil { + cOpts.has_real = 1 + cOpts.real = C.int(boolToInt(*opts.Real)) + } + } + + ret := C.gen_vips_invfft(input, &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// JoinOptions are optional parameters for join. +type JoinOptions struct { + Expand *bool + Shim *int + Background []float64 + Align *Align +} + +// vipsGenJoin calls the vips join operation. +// join a pair of images +func vipsGenJoin(in1 *C.VipsImage, in2 *C.VipsImage, direction Direction, opts *JoinOptions) (*C.VipsImage, error) { + incOpCounter("join") + + var out_out *C.VipsImage + + var cOpts C.GenJoinOpts + var pinner runtime.Pinner + defer pinner.Unpin() + if opts != nil { + if opts.Expand != nil { + cOpts.has_expand = 1 + cOpts.expand = C.int(boolToInt(*opts.Expand)) + } + if opts.Shim != nil { + cOpts.has_shim = 1 + cOpts.shim = C.int(*opts.Shim) + } + if opts.Background != nil { + cOpts.has_background = 1 + pinner.Pin(&opts.Background[0]) + cOpts.background = (*C.double)(unsafe.Pointer(&opts.Background[0])) + cOpts.background_n = C.int(len(opts.Background)) + } + if opts.Align != nil { + cOpts.has_align = 1 + cOpts.align = C.VipsAlign(*opts.Align) + } + } + + ret := C.gen_vips_join(in1, in2, C.VipsDirection(direction), &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenLabelregions calls the vips labelregions operation. +// label regions in an image +func vipsGenLabelregions(input *C.VipsImage) (*C.VipsImage, int, error) { + incOpCounter("labelregions") + + var out_mask *C.VipsImage + var out_segments C.int + + ret := C.gen_vips_labelregions(input, &out_mask, &out_segments) + if ret != 0 { + return nil, 0, handleImageError(out_mask) + } + + return out_mask, int(out_segments), nil +} + +// LinearOptions are optional parameters for linear. +type LinearOptions struct { + Uchar *bool +} + +// vipsGenLinear calls the vips linear operation. +// calculate (a * in + b) +func vipsGenLinear(input *C.VipsImage, a []float64, b []float64, opts *LinearOptions) (*C.VipsImage, error) { + incOpCounter("linear") + + var out_out *C.VipsImage + + var cOpts C.GenLinearOpts + if opts != nil { + if opts.Uchar != nil { + cOpts.has_uchar = 1 + cOpts.uchar = C.int(boolToInt(*opts.Uchar)) + } + } + + ret := C.gen_vips_linear(input, (*C.double)(unsafe.Pointer(&a[0])), C.int(len(a)), (*C.double)(unsafe.Pointer(&b[0])), C.int(len(b)), &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// LinecacheOptions are optional parameters for linecache. +type LinecacheOptions struct { + TileHeight *int + Access *int + Threaded *bool + Persistent *bool +} + +// vipsGenLinecache calls the vips linecache operation. +// cache an image as a set of lines +func vipsGenLinecache(input *C.VipsImage, opts *LinecacheOptions) (*C.VipsImage, error) { + incOpCounter("linecache") + + var out_out *C.VipsImage + + var cOpts C.GenLinecacheOpts + if opts != nil { + if opts.TileHeight != nil { + cOpts.has_tileHeight = 1 + cOpts.tileHeight = C.int(*opts.TileHeight) + } + if opts.Access != nil { + cOpts.has_access = 1 + cOpts.access = C.VipsAccess(*opts.Access) + } + if opts.Threaded != nil { + cOpts.has_threaded = 1 + cOpts.threaded = C.int(boolToInt(*opts.Threaded)) + } + if opts.Persistent != nil { + cOpts.has_persistent = 1 + cOpts.persistent = C.int(boolToInt(*opts.Persistent)) + } + } + + ret := C.gen_vips_linecache(input, &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// LogmatOptions are optional parameters for logmat. +type LogmatOptions struct { + Separable *bool + Precision *Precision +} + +// vipsGenLogmat calls the vips logmat operation. +// make a Laplacian of Gaussian image +func vipsGenLogmat(sigma float64, minAmpl float64, opts *LogmatOptions) (*C.VipsImage, error) { + incOpCounter("logmat") + + var out_out *C.VipsImage + + var cOpts C.GenLogmatOpts + if opts != nil { + if opts.Separable != nil { + cOpts.has_separable = 1 + cOpts.separable = C.int(boolToInt(*opts.Separable)) + } + if opts.Precision != nil { + cOpts.has_precision = 1 + cOpts.precision = C.VipsPrecision(*opts.Precision) + } + } + + ret := C.gen_vips_logmat(C.double(sigma), C.double(minAmpl), &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// MapimOptions are optional parameters for mapim. +type MapimOptions struct { + Interpolate *C.VipsInterpolate + Background []float64 + Premultiplied *bool + Extend *ExtendStrategy +} + +// vipsGenMapim calls the vips mapim operation. +// resample with a map image +func vipsGenMapim(input *C.VipsImage, index *C.VipsImage, opts *MapimOptions) (*C.VipsImage, error) { + incOpCounter("mapim") + + var out_out *C.VipsImage + + var cOpts C.GenMapimOpts + var pinner runtime.Pinner + defer pinner.Unpin() + if opts != nil { + if opts.Interpolate != nil { + cOpts.has_interpolate = 1 + cOpts.interpolate = opts.Interpolate + } + if opts.Background != nil { + cOpts.has_background = 1 + pinner.Pin(&opts.Background[0]) + cOpts.background = (*C.double)(unsafe.Pointer(&opts.Background[0])) + cOpts.background_n = C.int(len(opts.Background)) + } + if opts.Premultiplied != nil { + cOpts.has_premultiplied = 1 + cOpts.premultiplied = C.int(boolToInt(*opts.Premultiplied)) + } + if opts.Extend != nil { + cOpts.has_extend = 1 + cOpts.extend = C.VipsExtend(*opts.Extend) + } + } + + ret := C.gen_vips_mapim(input, index, &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// MaplutOptions are optional parameters for maplut. +type MaplutOptions struct { + Band *int +} + +// vipsGenMaplut calls the vips maplut operation. +// map an image though a lut +func vipsGenMaplut(input *C.VipsImage, lut *C.VipsImage, opts *MaplutOptions) (*C.VipsImage, error) { + incOpCounter("maplut") + + var out_out *C.VipsImage + + var cOpts C.GenMaplutOpts + if opts != nil { + if opts.Band != nil { + cOpts.has_band = 1 + cOpts.band = C.int(*opts.Band) + } + } + + ret := C.gen_vips_maplut(input, lut, &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// MaskButterworthOptions are optional parameters for mask_butterworth. +type MaskButterworthOptions struct { + Uchar *bool + Nodc *bool + Reject *bool + Optical *bool +} + +// vipsGenMaskButterworth calls the vips mask_butterworth operation. +// make a butterworth filter +func vipsGenMaskButterworth(width int, height int, order float64, frequencyCutoff float64, amplitudeCutoff float64, opts *MaskButterworthOptions) (*C.VipsImage, error) { + incOpCounter("mask_butterworth") + + var out_out *C.VipsImage + + var cOpts C.GenMaskButterworthOpts + if opts != nil { + if opts.Uchar != nil { + cOpts.has_uchar = 1 + cOpts.uchar = C.int(boolToInt(*opts.Uchar)) + } + if opts.Nodc != nil { + cOpts.has_nodc = 1 + cOpts.nodc = C.int(boolToInt(*opts.Nodc)) + } + if opts.Reject != nil { + cOpts.has_reject = 1 + cOpts.reject = C.int(boolToInt(*opts.Reject)) + } + if opts.Optical != nil { + cOpts.has_optical = 1 + cOpts.optical = C.int(boolToInt(*opts.Optical)) + } + } + + ret := C.gen_vips_mask_butterworth(C.int(width), C.int(height), C.double(order), C.double(frequencyCutoff), C.double(amplitudeCutoff), &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// MaskButterworthBandOptions are optional parameters for mask_butterworth_band. +type MaskButterworthBandOptions struct { + Uchar *bool + Nodc *bool + Reject *bool + Optical *bool +} + +// vipsGenMaskButterworthBand calls the vips mask_butterworth_band operation. +// make a butterworth_band filter +func vipsGenMaskButterworthBand(width int, height int, order float64, frequencyCutoffX float64, frequencyCutoffY float64, radius float64, amplitudeCutoff float64, opts *MaskButterworthBandOptions) (*C.VipsImage, error) { + incOpCounter("mask_butterworth_band") + + var out_out *C.VipsImage + + var cOpts C.GenMaskButterworthBandOpts + if opts != nil { + if opts.Uchar != nil { + cOpts.has_uchar = 1 + cOpts.uchar = C.int(boolToInt(*opts.Uchar)) + } + if opts.Nodc != nil { + cOpts.has_nodc = 1 + cOpts.nodc = C.int(boolToInt(*opts.Nodc)) + } + if opts.Reject != nil { + cOpts.has_reject = 1 + cOpts.reject = C.int(boolToInt(*opts.Reject)) + } + if opts.Optical != nil { + cOpts.has_optical = 1 + cOpts.optical = C.int(boolToInt(*opts.Optical)) + } + } + + ret := C.gen_vips_mask_butterworth_band(C.int(width), C.int(height), C.double(order), C.double(frequencyCutoffX), C.double(frequencyCutoffY), C.double(radius), C.double(amplitudeCutoff), &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// MaskButterworthRingOptions are optional parameters for mask_butterworth_ring. +type MaskButterworthRingOptions struct { + Uchar *bool + Nodc *bool + Reject *bool + Optical *bool +} + +// vipsGenMaskButterworthRing calls the vips mask_butterworth_ring operation. +// make a butterworth ring filter +func vipsGenMaskButterworthRing(width int, height int, order float64, frequencyCutoff float64, amplitudeCutoff float64, ringwidth float64, opts *MaskButterworthRingOptions) (*C.VipsImage, error) { + incOpCounter("mask_butterworth_ring") + + var out_out *C.VipsImage + + var cOpts C.GenMaskButterworthRingOpts + if opts != nil { + if opts.Uchar != nil { + cOpts.has_uchar = 1 + cOpts.uchar = C.int(boolToInt(*opts.Uchar)) + } + if opts.Nodc != nil { + cOpts.has_nodc = 1 + cOpts.nodc = C.int(boolToInt(*opts.Nodc)) + } + if opts.Reject != nil { + cOpts.has_reject = 1 + cOpts.reject = C.int(boolToInt(*opts.Reject)) + } + if opts.Optical != nil { + cOpts.has_optical = 1 + cOpts.optical = C.int(boolToInt(*opts.Optical)) + } + } + + ret := C.gen_vips_mask_butterworth_ring(C.int(width), C.int(height), C.double(order), C.double(frequencyCutoff), C.double(amplitudeCutoff), C.double(ringwidth), &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// MaskFractalOptions are optional parameters for mask_fractal. +type MaskFractalOptions struct { + Uchar *bool + Nodc *bool + Reject *bool + Optical *bool +} + +// vipsGenMaskFractal calls the vips mask_fractal operation. +// make fractal filter +func vipsGenMaskFractal(width int, height int, fractalDimension float64, opts *MaskFractalOptions) (*C.VipsImage, error) { + incOpCounter("mask_fractal") + + var out_out *C.VipsImage + + var cOpts C.GenMaskFractalOpts + if opts != nil { + if opts.Uchar != nil { + cOpts.has_uchar = 1 + cOpts.uchar = C.int(boolToInt(*opts.Uchar)) + } + if opts.Nodc != nil { + cOpts.has_nodc = 1 + cOpts.nodc = C.int(boolToInt(*opts.Nodc)) + } + if opts.Reject != nil { + cOpts.has_reject = 1 + cOpts.reject = C.int(boolToInt(*opts.Reject)) + } + if opts.Optical != nil { + cOpts.has_optical = 1 + cOpts.optical = C.int(boolToInt(*opts.Optical)) + } + } + + ret := C.gen_vips_mask_fractal(C.int(width), C.int(height), C.double(fractalDimension), &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// MaskGaussianOptions are optional parameters for mask_gaussian. +type MaskGaussianOptions struct { + Uchar *bool + Nodc *bool + Reject *bool + Optical *bool +} + +// vipsGenMaskGaussian calls the vips mask_gaussian operation. +// make a gaussian filter +func vipsGenMaskGaussian(width int, height int, frequencyCutoff float64, amplitudeCutoff float64, opts *MaskGaussianOptions) (*C.VipsImage, error) { + incOpCounter("mask_gaussian") + + var out_out *C.VipsImage + + var cOpts C.GenMaskGaussianOpts + if opts != nil { + if opts.Uchar != nil { + cOpts.has_uchar = 1 + cOpts.uchar = C.int(boolToInt(*opts.Uchar)) + } + if opts.Nodc != nil { + cOpts.has_nodc = 1 + cOpts.nodc = C.int(boolToInt(*opts.Nodc)) + } + if opts.Reject != nil { + cOpts.has_reject = 1 + cOpts.reject = C.int(boolToInt(*opts.Reject)) + } + if opts.Optical != nil { + cOpts.has_optical = 1 + cOpts.optical = C.int(boolToInt(*opts.Optical)) + } + } + + ret := C.gen_vips_mask_gaussian(C.int(width), C.int(height), C.double(frequencyCutoff), C.double(amplitudeCutoff), &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// MaskGaussianBandOptions are optional parameters for mask_gaussian_band. +type MaskGaussianBandOptions struct { + Uchar *bool + Nodc *bool + Reject *bool + Optical *bool +} + +// vipsGenMaskGaussianBand calls the vips mask_gaussian_band operation. +// make a gaussian filter +func vipsGenMaskGaussianBand(width int, height int, frequencyCutoffX float64, frequencyCutoffY float64, radius float64, amplitudeCutoff float64, opts *MaskGaussianBandOptions) (*C.VipsImage, error) { + incOpCounter("mask_gaussian_band") + + var out_out *C.VipsImage + + var cOpts C.GenMaskGaussianBandOpts + if opts != nil { + if opts.Uchar != nil { + cOpts.has_uchar = 1 + cOpts.uchar = C.int(boolToInt(*opts.Uchar)) + } + if opts.Nodc != nil { + cOpts.has_nodc = 1 + cOpts.nodc = C.int(boolToInt(*opts.Nodc)) + } + if opts.Reject != nil { + cOpts.has_reject = 1 + cOpts.reject = C.int(boolToInt(*opts.Reject)) + } + if opts.Optical != nil { + cOpts.has_optical = 1 + cOpts.optical = C.int(boolToInt(*opts.Optical)) + } + } + + ret := C.gen_vips_mask_gaussian_band(C.int(width), C.int(height), C.double(frequencyCutoffX), C.double(frequencyCutoffY), C.double(radius), C.double(amplitudeCutoff), &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// MaskGaussianRingOptions are optional parameters for mask_gaussian_ring. +type MaskGaussianRingOptions struct { + Uchar *bool + Nodc *bool + Reject *bool + Optical *bool +} + +// vipsGenMaskGaussianRing calls the vips mask_gaussian_ring operation. +// make a gaussian ring filter +func vipsGenMaskGaussianRing(width int, height int, frequencyCutoff float64, amplitudeCutoff float64, ringwidth float64, opts *MaskGaussianRingOptions) (*C.VipsImage, error) { + incOpCounter("mask_gaussian_ring") + + var out_out *C.VipsImage + + var cOpts C.GenMaskGaussianRingOpts + if opts != nil { + if opts.Uchar != nil { + cOpts.has_uchar = 1 + cOpts.uchar = C.int(boolToInt(*opts.Uchar)) + } + if opts.Nodc != nil { + cOpts.has_nodc = 1 + cOpts.nodc = C.int(boolToInt(*opts.Nodc)) + } + if opts.Reject != nil { + cOpts.has_reject = 1 + cOpts.reject = C.int(boolToInt(*opts.Reject)) + } + if opts.Optical != nil { + cOpts.has_optical = 1 + cOpts.optical = C.int(boolToInt(*opts.Optical)) + } + } + + ret := C.gen_vips_mask_gaussian_ring(C.int(width), C.int(height), C.double(frequencyCutoff), C.double(amplitudeCutoff), C.double(ringwidth), &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// MaskIdealOptions are optional parameters for mask_ideal. +type MaskIdealOptions struct { + Uchar *bool + Nodc *bool + Reject *bool + Optical *bool +} + +// vipsGenMaskIdeal calls the vips mask_ideal operation. +// make an ideal filter +func vipsGenMaskIdeal(width int, height int, frequencyCutoff float64, opts *MaskIdealOptions) (*C.VipsImage, error) { + incOpCounter("mask_ideal") + + var out_out *C.VipsImage + + var cOpts C.GenMaskIdealOpts + if opts != nil { + if opts.Uchar != nil { + cOpts.has_uchar = 1 + cOpts.uchar = C.int(boolToInt(*opts.Uchar)) + } + if opts.Nodc != nil { + cOpts.has_nodc = 1 + cOpts.nodc = C.int(boolToInt(*opts.Nodc)) + } + if opts.Reject != nil { + cOpts.has_reject = 1 + cOpts.reject = C.int(boolToInt(*opts.Reject)) + } + if opts.Optical != nil { + cOpts.has_optical = 1 + cOpts.optical = C.int(boolToInt(*opts.Optical)) + } + } + + ret := C.gen_vips_mask_ideal(C.int(width), C.int(height), C.double(frequencyCutoff), &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// MaskIdealBandOptions are optional parameters for mask_ideal_band. +type MaskIdealBandOptions struct { + Uchar *bool + Nodc *bool + Reject *bool + Optical *bool +} + +// vipsGenMaskIdealBand calls the vips mask_ideal_band operation. +// make an ideal band filter +func vipsGenMaskIdealBand(width int, height int, frequencyCutoffX float64, frequencyCutoffY float64, radius float64, opts *MaskIdealBandOptions) (*C.VipsImage, error) { + incOpCounter("mask_ideal_band") + + var out_out *C.VipsImage + + var cOpts C.GenMaskIdealBandOpts + if opts != nil { + if opts.Uchar != nil { + cOpts.has_uchar = 1 + cOpts.uchar = C.int(boolToInt(*opts.Uchar)) + } + if opts.Nodc != nil { + cOpts.has_nodc = 1 + cOpts.nodc = C.int(boolToInt(*opts.Nodc)) + } + if opts.Reject != nil { + cOpts.has_reject = 1 + cOpts.reject = C.int(boolToInt(*opts.Reject)) + } + if opts.Optical != nil { + cOpts.has_optical = 1 + cOpts.optical = C.int(boolToInt(*opts.Optical)) + } + } + + ret := C.gen_vips_mask_ideal_band(C.int(width), C.int(height), C.double(frequencyCutoffX), C.double(frequencyCutoffY), C.double(radius), &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// MaskIdealRingOptions are optional parameters for mask_ideal_ring. +type MaskIdealRingOptions struct { + Uchar *bool + Nodc *bool + Reject *bool + Optical *bool +} + +// vipsGenMaskIdealRing calls the vips mask_ideal_ring operation. +// make an ideal ring filter +func vipsGenMaskIdealRing(width int, height int, frequencyCutoff float64, ringwidth float64, opts *MaskIdealRingOptions) (*C.VipsImage, error) { + incOpCounter("mask_ideal_ring") + + var out_out *C.VipsImage + + var cOpts C.GenMaskIdealRingOpts + if opts != nil { + if opts.Uchar != nil { + cOpts.has_uchar = 1 + cOpts.uchar = C.int(boolToInt(*opts.Uchar)) + } + if opts.Nodc != nil { + cOpts.has_nodc = 1 + cOpts.nodc = C.int(boolToInt(*opts.Nodc)) + } + if opts.Reject != nil { + cOpts.has_reject = 1 + cOpts.reject = C.int(boolToInt(*opts.Reject)) + } + if opts.Optical != nil { + cOpts.has_optical = 1 + cOpts.optical = C.int(boolToInt(*opts.Optical)) + } + } + + ret := C.gen_vips_mask_ideal_ring(C.int(width), C.int(height), C.double(frequencyCutoff), C.double(ringwidth), &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// MatchOptions are optional parameters for match. +type MatchOptions struct { + Hwindow *int + Harea *int + Search *bool + Interpolate *C.VipsInterpolate +} + +// vipsGenMatch calls the vips match operation. +// first-order match of two images +func vipsGenMatch(ref *C.VipsImage, sec *C.VipsImage, xr1 int, yr1 int, xs1 int, ys1 int, xr2 int, yr2 int, xs2 int, ys2 int, opts *MatchOptions) (*C.VipsImage, error) { + incOpCounter("match") + + var out_out *C.VipsImage + + var cOpts C.GenMatchOpts + if opts != nil { + if opts.Hwindow != nil { + cOpts.has_hwindow = 1 + cOpts.hwindow = C.int(*opts.Hwindow) + } + if opts.Harea != nil { + cOpts.has_harea = 1 + cOpts.harea = C.int(*opts.Harea) + } + if opts.Search != nil { + cOpts.has_search = 1 + cOpts.search = C.int(boolToInt(*opts.Search)) + } + if opts.Interpolate != nil { + cOpts.has_interpolate = 1 + cOpts.interpolate = opts.Interpolate + } + } + + ret := C.gen_vips_match(ref, sec, C.int(xr1), C.int(yr1), C.int(xs1), C.int(ys1), C.int(xr2), C.int(yr2), C.int(xs2), C.int(ys2), &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenMath calls the vips math operation. +// apply a math operation to an image +func vipsGenMath(input *C.VipsImage, math OperationMath) (*C.VipsImage, error) { + incOpCounter("math") + + var out_out *C.VipsImage + + ret := C.gen_vips_math(input, C.VipsOperationMath(math), &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenMath2 calls the vips math2 operation. +// binary math operations +func vipsGenMath2(left *C.VipsImage, right *C.VipsImage, math2 OperationMath2) (*C.VipsImage, error) { + incOpCounter("math2") + + var out_out *C.VipsImage + + ret := C.gen_vips_math2(left, right, C.VipsOperationMath2(math2), &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenMath2Const calls the vips math2_const operation. +// binary math operations with a constant +func vipsGenMath2Const(input *C.VipsImage, math2 OperationMath2, c []float64) (*C.VipsImage, error) { + incOpCounter("math2_const") + + var out_out *C.VipsImage + + ret := C.gen_vips_math2_const(input, C.VipsOperationMath2(math2), (*C.double)(unsafe.Pointer(&c[0])), C.int(len(c)), &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenMatrixinvert calls the vips matrixinvert operation. +// invert a matrix +func vipsGenMatrixinvert(input *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("matrixinvert") + + var out_out *C.VipsImage + + ret := C.gen_vips_matrixinvert(input, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenMatrixmultiply calls the vips matrixmultiply operation. +// multiply two matrices +func vipsGenMatrixmultiply(left *C.VipsImage, right *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("matrixmultiply") + + var out_out *C.VipsImage + + ret := C.gen_vips_matrixmultiply(left, right, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenMaxpair calls the vips maxpair operation. +// maximum of a pair of images +func vipsGenMaxpair(left *C.VipsImage, right *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("maxpair") + + var out_out *C.VipsImage + + ret := C.gen_vips_maxpair(left, right, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// MergeOptions are optional parameters for merge. +type MergeOptions struct { + Mblend *int +} + +// vipsGenMerge calls the vips merge operation. +// merge two images +func vipsGenMerge(ref *C.VipsImage, sec *C.VipsImage, direction Direction, dx int, dy int, opts *MergeOptions) (*C.VipsImage, error) { + incOpCounter("merge") + + var out_out *C.VipsImage + + var cOpts C.GenMergeOpts + if opts != nil { + if opts.Mblend != nil { + cOpts.has_mblend = 1 + cOpts.mblend = C.int(*opts.Mblend) + } + } + + ret := C.gen_vips_merge(ref, sec, C.VipsDirection(direction), C.int(dx), C.int(dy), &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenMinpair calls the vips minpair operation. +// minimum of a pair of images +func vipsGenMinpair(left *C.VipsImage, right *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("minpair") + + var out_out *C.VipsImage + + ret := C.gen_vips_minpair(left, right, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenMorph calls the vips morph operation. +// morphology operation +func vipsGenMorph(input *C.VipsImage, mask *C.VipsImage, morph OperationMorphology) (*C.VipsImage, error) { + incOpCounter("morph") + + var out_out *C.VipsImage + + ret := C.gen_vips_morph(input, mask, C.VipsOperationMorphology(morph), &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// MosaicOptions are optional parameters for mosaic. +type MosaicOptions struct { + Hwindow *int + Harea *int + Mblend *int + Bandno *int +} + +// vipsGenMosaic calls the vips mosaic operation. +// mosaic two images +func vipsGenMosaic(ref *C.VipsImage, sec *C.VipsImage, direction Direction, xref int, yref int, xsec int, ysec int, opts *MosaicOptions) (*C.VipsImage, int, int, float64, float64, float64, float64, error) { + incOpCounter("mosaic") + + var out_out *C.VipsImage + var out_dx0 C.int + var out_dy0 C.int + var out_scale1 C.double + var out_angle1 C.double + var out_dy1 C.double + var out_dx1 C.double + + var cOpts C.GenMosaicOpts + if opts != nil { + if opts.Hwindow != nil { + cOpts.has_hwindow = 1 + cOpts.hwindow = C.int(*opts.Hwindow) + } + if opts.Harea != nil { + cOpts.has_harea = 1 + cOpts.harea = C.int(*opts.Harea) + } + if opts.Mblend != nil { + cOpts.has_mblend = 1 + cOpts.mblend = C.int(*opts.Mblend) + } + if opts.Bandno != nil { + cOpts.has_bandno = 1 + cOpts.bandno = C.int(*opts.Bandno) + } + } + + ret := C.gen_vips_mosaic(ref, sec, C.VipsDirection(direction), C.int(xref), C.int(yref), C.int(xsec), C.int(ysec), &out_out, &out_dx0, &out_dy0, &out_scale1, &out_angle1, &out_dy1, &out_dx1, &cOpts) + if ret != 0 { + return nil, 0, 0, 0, 0, 0, 0, handleImageError(out_out) + } + + return out_out, int(out_dx0), int(out_dy0), float64(out_scale1), float64(out_angle1), float64(out_dy1), float64(out_dx1), nil +} + +// Mosaic1Options are optional parameters for mosaic1. +type Mosaic1Options struct { + Hwindow *int + Harea *int + Search *bool + Interpolate *C.VipsInterpolate + Mblend *int +} + +// vipsGenMosaic1 calls the vips mosaic1 operation. +// first-order mosaic of two images +func vipsGenMosaic1(ref *C.VipsImage, sec *C.VipsImage, direction Direction, xr1 int, yr1 int, xs1 int, ys1 int, xr2 int, yr2 int, xs2 int, ys2 int, opts *Mosaic1Options) (*C.VipsImage, error) { + incOpCounter("mosaic1") + + var out_out *C.VipsImage + + var cOpts C.GenMosaic1Opts + if opts != nil { + if opts.Hwindow != nil { + cOpts.has_hwindow = 1 + cOpts.hwindow = C.int(*opts.Hwindow) + } + if opts.Harea != nil { + cOpts.has_harea = 1 + cOpts.harea = C.int(*opts.Harea) + } + if opts.Search != nil { + cOpts.has_search = 1 + cOpts.search = C.int(boolToInt(*opts.Search)) + } + if opts.Interpolate != nil { + cOpts.has_interpolate = 1 + cOpts.interpolate = opts.Interpolate + } + if opts.Mblend != nil { + cOpts.has_mblend = 1 + cOpts.mblend = C.int(*opts.Mblend) + } + } + + ret := C.gen_vips_mosaic1(ref, sec, C.VipsDirection(direction), C.int(xr1), C.int(yr1), C.int(xs1), C.int(ys1), C.int(xr2), C.int(yr2), C.int(xs2), C.int(ys2), &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// MsbOptions are optional parameters for msb. +type MsbOptions struct { + Band *int +} + +// vipsGenMsb calls the vips msb operation. +// pick most-significant byte from an image +func vipsGenMsb(input *C.VipsImage, opts *MsbOptions) (*C.VipsImage, error) { + incOpCounter("msb") + + var out_out *C.VipsImage + + var cOpts C.GenMsbOpts + if opts != nil { + if opts.Band != nil { + cOpts.has_band = 1 + cOpts.band = C.int(*opts.Band) + } + } + + ret := C.gen_vips_msb(input, &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenMultiply calls the vips multiply operation. +// multiply two images +func vipsGenMultiply(left *C.VipsImage, right *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("multiply") + + var out_out *C.VipsImage + + ret := C.gen_vips_multiply(left, right, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenPercent calls the vips percent operation. +// find threshold for percent of pixels +func vipsGenPercent(input *C.VipsImage, percent float64) (int, error) { + incOpCounter("percent") + + var out_threshold C.int + + ret := C.gen_vips_percent(input, C.double(percent), &out_threshold) + if ret != 0 { + return 0, handleVipsError() + } + + return int(out_threshold), nil +} + +// PerlinOptions are optional parameters for perlin. +type PerlinOptions struct { + CellSize *int + Uchar *bool + Seed *int +} + +// vipsGenPerlin calls the vips perlin operation. +// make a perlin noise image +func vipsGenPerlin(width int, height int, opts *PerlinOptions) (*C.VipsImage, error) { + incOpCounter("perlin") + + var out_out *C.VipsImage + + var cOpts C.GenPerlinOpts + if opts != nil { + if opts.CellSize != nil { + cOpts.has_cellSize = 1 + cOpts.cellSize = C.int(*opts.CellSize) + } + if opts.Uchar != nil { + cOpts.has_uchar = 1 + cOpts.uchar = C.int(boolToInt(*opts.Uchar)) + } + if opts.Seed != nil { + cOpts.has_seed = 1 + cOpts.seed = C.int(*opts.Seed) + } + } + + ret := C.gen_vips_perlin(C.int(width), C.int(height), &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenPhasecor calls the vips phasecor operation. +// calculate phase correlation +func vipsGenPhasecor(input *C.VipsImage, in2 *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("phasecor") + + var out_out *C.VipsImage + + ret := C.gen_vips_phasecor(input, in2, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// PremultiplyOptions are optional parameters for premultiply. +type PremultiplyOptions struct { + MaxAlpha *float64 +} + +// vipsGenPremultiply calls the vips premultiply operation. +// premultiply image alpha +func vipsGenPremultiply(input *C.VipsImage, opts *PremultiplyOptions) (*C.VipsImage, error) { + incOpCounter("premultiply") + + var out_out *C.VipsImage + + var cOpts C.GenPremultiplyOpts + if opts != nil { + if opts.MaxAlpha != nil { + cOpts.has_maxAlpha = 1 + cOpts.maxAlpha = C.double(*opts.MaxAlpha) + } + } + + ret := C.gen_vips_premultiply(input, &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenPrewitt calls the vips prewitt operation. +// Prewitt edge detector +func vipsGenPrewitt(input *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("prewitt") + + var out_out *C.VipsImage + + ret := C.gen_vips_prewitt(input, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenProfile calls the vips profile operation. +// find image profiles +func vipsGenProfile(input *C.VipsImage) (*C.VipsImage, *C.VipsImage, error) { + incOpCounter("profile") + + var out_columns *C.VipsImage + var out_rows *C.VipsImage + + ret := C.gen_vips_profile(input, &out_columns, &out_rows) + if ret != 0 { + return nil, nil, handleImageError(out_columns) + } + + return out_columns, out_rows, nil +} + +// vipsGenProject calls the vips project operation. +// find image projections +func vipsGenProject(input *C.VipsImage) (*C.VipsImage, *C.VipsImage, error) { + incOpCounter("project") + + var out_columns *C.VipsImage + var out_rows *C.VipsImage + + ret := C.gen_vips_project(input, &out_columns, &out_rows) + if ret != 0 { + return nil, nil, handleImageError(out_columns) + } + + return out_columns, out_rows, nil +} + +// QuadraticOptions are optional parameters for quadratic. +type QuadraticOptions struct { + Interpolate *C.VipsInterpolate +} + +// vipsGenQuadratic calls the vips quadratic operation. +// resample an image with a quadratic transform +func vipsGenQuadratic(input *C.VipsImage, coeff *C.VipsImage, opts *QuadraticOptions) (*C.VipsImage, error) { + incOpCounter("quadratic") + + var out_out *C.VipsImage + + var cOpts C.GenQuadraticOpts + if opts != nil { + if opts.Interpolate != nil { + cOpts.has_interpolate = 1 + cOpts.interpolate = opts.Interpolate + } + } + + ret := C.gen_vips_quadratic(input, coeff, &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenRad2float calls the vips rad2float operation. +// unpack Radiance coding to float RGB +func vipsGenRad2float(input *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("rad2float") + + var out_out *C.VipsImage + + ret := C.gen_vips_rad2float(input, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenRank calls the vips rank operation. +// rank filter +func vipsGenRank(input *C.VipsImage, width int, height int, index int) (*C.VipsImage, error) { + incOpCounter("rank") + + var out_out *C.VipsImage + + ret := C.gen_vips_rank(input, C.int(width), C.int(height), C.int(index), &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenRecomb calls the vips recomb operation. +// linear recombination with matrix +func vipsGenRecomb(input *C.VipsImage, m *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("recomb") + + var out_out *C.VipsImage + + ret := C.gen_vips_recomb(input, m, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// ReduceOptions are optional parameters for reduce. +type ReduceOptions struct { + Kernel *Kernel + Gap *float64 +} + +// vipsGenReduce calls the vips reduce operation. +// reduce an image +func vipsGenReduce(input *C.VipsImage, hshrink float64, vshrink float64, opts *ReduceOptions) (*C.VipsImage, error) { + incOpCounter("reduce") + + var out_out *C.VipsImage + + var cOpts C.GenReduceOpts + if opts != nil { + if opts.Kernel != nil { + cOpts.has_kernel = 1 + cOpts.kernel = C.VipsKernel(*opts.Kernel) + } + if opts.Gap != nil { + cOpts.has_gap = 1 + cOpts.gap = C.double(*opts.Gap) + } + } + + ret := C.gen_vips_reduce(input, C.double(hshrink), C.double(vshrink), &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// ReducehOptions are optional parameters for reduceh. +type ReducehOptions struct { + Kernel *Kernel + Gap *float64 +} + +// vipsGenReduceh calls the vips reduceh operation. +// shrink an image horizontally +func vipsGenReduceh(input *C.VipsImage, hshrink float64, opts *ReducehOptions) (*C.VipsImage, error) { + incOpCounter("reduceh") + + var out_out *C.VipsImage + + var cOpts C.GenReducehOpts + if opts != nil { + if opts.Kernel != nil { + cOpts.has_kernel = 1 + cOpts.kernel = C.VipsKernel(*opts.Kernel) + } + if opts.Gap != nil { + cOpts.has_gap = 1 + cOpts.gap = C.double(*opts.Gap) + } + } + + ret := C.gen_vips_reduceh(input, C.double(hshrink), &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// ReducevOptions are optional parameters for reducev. +type ReducevOptions struct { + Kernel *Kernel + Gap *float64 +} + +// vipsGenReducev calls the vips reducev operation. +// shrink an image vertically +func vipsGenReducev(input *C.VipsImage, vshrink float64, opts *ReducevOptions) (*C.VipsImage, error) { + incOpCounter("reducev") + + var out_out *C.VipsImage + + var cOpts C.GenReducevOpts + if opts != nil { + if opts.Kernel != nil { + cOpts.has_kernel = 1 + cOpts.kernel = C.VipsKernel(*opts.Kernel) + } + if opts.Gap != nil { + cOpts.has_gap = 1 + cOpts.gap = C.double(*opts.Gap) + } + } + + ret := C.gen_vips_reducev(input, C.double(vshrink), &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenRelational calls the vips relational operation. +// relational operation on two images +func vipsGenRelational(left *C.VipsImage, right *C.VipsImage, relational OperationRelational) (*C.VipsImage, error) { + incOpCounter("relational") + + var out_out *C.VipsImage + + ret := C.gen_vips_relational(left, right, C.VipsOperationRelational(relational), &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenRelationalConst calls the vips relational_const operation. +// relational operations against a constant +func vipsGenRelationalConst(input *C.VipsImage, relational OperationRelational, c []float64) (*C.VipsImage, error) { + incOpCounter("relational_const") + + var out_out *C.VipsImage + + ret := C.gen_vips_relational_const(input, C.VipsOperationRelational(relational), (*C.double)(unsafe.Pointer(&c[0])), C.int(len(c)), &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenRemainder calls the vips remainder operation. +// remainder after integer division of two images +func vipsGenRemainder(left *C.VipsImage, right *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("remainder") + + var out_out *C.VipsImage + + ret := C.gen_vips_remainder(left, right, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenRemainderConst calls the vips remainder_const operation. +// remainder after integer division of an image and a constant +func vipsGenRemainderConst(input *C.VipsImage, c []float64) (*C.VipsImage, error) { + incOpCounter("remainder_const") + + var out_out *C.VipsImage + + ret := C.gen_vips_remainder_const(input, (*C.double)(unsafe.Pointer(&c[0])), C.int(len(c)), &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenRemosaic calls the vips remosaic operation. +// rebuild an mosaiced image +func vipsGenRemosaic(input *C.VipsImage, oldStr string, newStr string) (*C.VipsImage, error) { + incOpCounter("remosaic") + + cStr_oldStr := C.CString(oldStr) + defer C.free(unsafe.Pointer(cStr_oldStr)) + cStr_newStr := C.CString(newStr) + defer C.free(unsafe.Pointer(cStr_newStr)) + var out_out *C.VipsImage + + ret := C.gen_vips_remosaic(input, cStr_oldStr, cStr_newStr, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenReplicate calls the vips replicate operation. +// replicate an image +func vipsGenReplicate(input *C.VipsImage, across int, down int) (*C.VipsImage, error) { + incOpCounter("replicate") + + var out_out *C.VipsImage + + ret := C.gen_vips_replicate(input, C.int(across), C.int(down), &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenRot calls the vips rot operation. +// rotate an image +func vipsGenRot(input *C.VipsImage, angle Angle) (*C.VipsImage, error) { + incOpCounter("rot") + + var out_out *C.VipsImage + + ret := C.gen_vips_rot(input, C.VipsAngle(angle), &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// Rot45Options are optional parameters for rot45. +type Rot45Options struct { + Angle *Angle45 +} + +// vipsGenRot45 calls the vips rot45 operation. +// rotate an image +func vipsGenRot45(input *C.VipsImage, opts *Rot45Options) (*C.VipsImage, error) { + incOpCounter("rot45") + + var out_out *C.VipsImage + + var cOpts C.GenRot45Opts + if opts != nil { + if opts.Angle != nil { + cOpts.has_angle = 1 + cOpts.angle = C.VipsAngle45(*opts.Angle) + } + } + + ret := C.gen_vips_rot45(input, &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// RotateOptions are optional parameters for rotate. +type RotateOptions struct { + Interpolate *C.VipsInterpolate + Background []float64 + Odx *float64 + Ody *float64 + Idx *float64 + Idy *float64 +} + +// vipsGenRotate calls the vips rotate operation. +// rotate an image by a number of degrees +func vipsGenRotate(input *C.VipsImage, angle float64, opts *RotateOptions) (*C.VipsImage, error) { + incOpCounter("rotate") + + var out_out *C.VipsImage + + var cOpts C.GenRotateOpts + var pinner runtime.Pinner + defer pinner.Unpin() + if opts != nil { + if opts.Interpolate != nil { + cOpts.has_interpolate = 1 + cOpts.interpolate = opts.Interpolate + } + if opts.Background != nil { + cOpts.has_background = 1 + pinner.Pin(&opts.Background[0]) + cOpts.background = (*C.double)(unsafe.Pointer(&opts.Background[0])) + cOpts.background_n = C.int(len(opts.Background)) + } + if opts.Odx != nil { + cOpts.has_odx = 1 + cOpts.odx = C.double(*opts.Odx) + } + if opts.Ody != nil { + cOpts.has_ody = 1 + cOpts.ody = C.double(*opts.Ody) + } + if opts.Idx != nil { + cOpts.has_idx = 1 + cOpts.idx = C.double(*opts.Idx) + } + if opts.Idy != nil { + cOpts.has_idy = 1 + cOpts.idy = C.double(*opts.Idy) + } + } + + ret := C.gen_vips_rotate(input, C.double(angle), &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenRound calls the vips round operation. +// perform a round function on an image +func vipsGenRound(input *C.VipsImage, round OperationRound) (*C.VipsImage, error) { + incOpCounter("round") + + var out_out *C.VipsImage + + ret := C.gen_vips_round(input, C.VipsOperationRound(round), &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenSRGB2HSV calls the vips sRGB2HSV operation. +// transform sRGB to HSV +func vipsGenSRGB2HSV(input *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("sRGB2HSV") + + var out_out *C.VipsImage + + ret := C.gen_vips_sRGB2HSV(input, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenSRGB2scRGB calls the vips sRGB2scRGB operation. +// convert an sRGB image to scRGB +func vipsGenSRGB2scRGB(input *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("sRGB2scRGB") + + var out_out *C.VipsImage + + ret := C.gen_vips_sRGB2scRGB(input, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// ScRGB2BWOptions are optional parameters for scRGB2BW. +type ScRGB2BWOptions struct { + Depth *int +} + +// vipsGenScRGB2BW calls the vips scRGB2BW operation. +// convert scRGB to BW +func vipsGenScRGB2BW(input *C.VipsImage, opts *ScRGB2BWOptions) (*C.VipsImage, error) { + incOpCounter("scRGB2BW") + + var out_out *C.VipsImage + + var cOpts C.GenScRGB2BWOpts + if opts != nil { + if opts.Depth != nil { + cOpts.has_depth = 1 + cOpts.depth = C.int(*opts.Depth) + } + } + + ret := C.gen_vips_scRGB2BW(input, &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenScRGB2XYZ calls the vips scRGB2XYZ operation. +// transform scRGB to XYZ +func vipsGenScRGB2XYZ(input *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("scRGB2XYZ") + + var out_out *C.VipsImage + + ret := C.gen_vips_scRGB2XYZ(input, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// ScRGB2sRGBOptions are optional parameters for scRGB2sRGB. +type ScRGB2sRGBOptions struct { + Depth *int +} + +// vipsGenScRGB2sRGB calls the vips scRGB2sRGB operation. +// convert scRGB to sRGB +func vipsGenScRGB2sRGB(input *C.VipsImage, opts *ScRGB2sRGBOptions) (*C.VipsImage, error) { + incOpCounter("scRGB2sRGB") + + var out_out *C.VipsImage + + var cOpts C.GenScRGB2sRGBOpts + if opts != nil { + if opts.Depth != nil { + cOpts.has_depth = 1 + cOpts.depth = C.int(*opts.Depth) + } + } + + ret := C.gen_vips_scRGB2sRGB(input, &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// ScaleOptions are optional parameters for scale. +type ScaleOptions struct { + Exp *float64 + Log *bool +} + +// vipsGenScale calls the vips scale operation. +// scale an image to uchar +func vipsGenScale(input *C.VipsImage, opts *ScaleOptions) (*C.VipsImage, error) { + incOpCounter("scale") + + var out_out *C.VipsImage + + var cOpts C.GenScaleOpts + if opts != nil { + if opts.Exp != nil { + cOpts.has_exp = 1 + cOpts.exp = C.double(*opts.Exp) + } + if opts.Log != nil { + cOpts.has_log = 1 + cOpts.log = C.int(boolToInt(*opts.Log)) + } + } + + ret := C.gen_vips_scale(input, &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenScharr calls the vips scharr operation. +// Scharr edge detector +func vipsGenScharr(input *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("scharr") + + var out_out *C.VipsImage + + ret := C.gen_vips_scharr(input, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// SequentialOptions are optional parameters for sequential. +type SequentialOptions struct { + TileHeight *int +} + +// vipsGenSequential calls the vips sequential operation. +// check sequential access +func vipsGenSequential(input *C.VipsImage, opts *SequentialOptions) (*C.VipsImage, error) { + incOpCounter("sequential") + + var out_out *C.VipsImage + + var cOpts C.GenSequentialOpts + if opts != nil { + if opts.TileHeight != nil { + cOpts.has_tileHeight = 1 + cOpts.tileHeight = C.int(*opts.TileHeight) + } + } + + ret := C.gen_vips_sequential(input, &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// SharpenOptions are optional parameters for sharpen. +type SharpenOptions struct { + Sigma *float64 + X1 *float64 + Y2 *float64 + Y3 *float64 + M1 *float64 + M2 *float64 +} + +// vipsGenSharpen calls the vips sharpen operation. +// unsharp masking for print +func vipsGenSharpen(input *C.VipsImage, opts *SharpenOptions) (*C.VipsImage, error) { + incOpCounter("sharpen") + + var out_out *C.VipsImage + + var cOpts C.GenSharpenOpts + if opts != nil { + if opts.Sigma != nil { + cOpts.has_sigma = 1 + cOpts.sigma = C.double(*opts.Sigma) + } + if opts.X1 != nil { + cOpts.has_x1 = 1 + cOpts.x1 = C.double(*opts.X1) + } + if opts.Y2 != nil { + cOpts.has_y2 = 1 + cOpts.y2 = C.double(*opts.Y2) + } + if opts.Y3 != nil { + cOpts.has_y3 = 1 + cOpts.y3 = C.double(*opts.Y3) + } + if opts.M1 != nil { + cOpts.has_m1 = 1 + cOpts.m1 = C.double(*opts.M1) + } + if opts.M2 != nil { + cOpts.has_m2 = 1 + cOpts.m2 = C.double(*opts.M2) + } + } + + ret := C.gen_vips_sharpen(input, &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// ShrinkOptions are optional parameters for shrink. +type ShrinkOptions struct { + Ceil *bool +} + +// vipsGenShrink calls the vips shrink operation. +// shrink an image +func vipsGenShrink(input *C.VipsImage, hshrink float64, vshrink float64, opts *ShrinkOptions) (*C.VipsImage, error) { + incOpCounter("shrink") + + var out_out *C.VipsImage + + var cOpts C.GenShrinkOpts + if opts != nil { + if opts.Ceil != nil { + cOpts.has_ceil = 1 + cOpts.ceil = C.int(boolToInt(*opts.Ceil)) + } + } + + ret := C.gen_vips_shrink(input, C.double(hshrink), C.double(vshrink), &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// ShrinkhOptions are optional parameters for shrinkh. +type ShrinkhOptions struct { + Ceil *bool +} + +// vipsGenShrinkh calls the vips shrinkh operation. +// shrink an image horizontally +func vipsGenShrinkh(input *C.VipsImage, hshrink int, opts *ShrinkhOptions) (*C.VipsImage, error) { + incOpCounter("shrinkh") + + var out_out *C.VipsImage + + var cOpts C.GenShrinkhOpts + if opts != nil { + if opts.Ceil != nil { + cOpts.has_ceil = 1 + cOpts.ceil = C.int(boolToInt(*opts.Ceil)) + } + } + + ret := C.gen_vips_shrinkh(input, C.int(hshrink), &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// ShrinkvOptions are optional parameters for shrinkv. +type ShrinkvOptions struct { + Ceil *bool +} + +// vipsGenShrinkv calls the vips shrinkv operation. +// shrink an image vertically +func vipsGenShrinkv(input *C.VipsImage, vshrink int, opts *ShrinkvOptions) (*C.VipsImage, error) { + incOpCounter("shrinkv") + + var out_out *C.VipsImage + + var cOpts C.GenShrinkvOpts + if opts != nil { + if opts.Ceil != nil { + cOpts.has_ceil = 1 + cOpts.ceil = C.int(boolToInt(*opts.Ceil)) + } + } + + ret := C.gen_vips_shrinkv(input, C.int(vshrink), &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenSign calls the vips sign operation. +// unit vector of pixel +func vipsGenSign(input *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("sign") + + var out_out *C.VipsImage + + ret := C.gen_vips_sign(input, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// SimilarityOptions are optional parameters for similarity. +type SimilarityOptions struct { + Scale *float64 + Angle *float64 + Interpolate *C.VipsInterpolate + Background []float64 + Odx *float64 + Ody *float64 + Idx *float64 + Idy *float64 +} + +// vipsGenSimilarity calls the vips similarity operation. +// similarity transform of an image +func vipsGenSimilarity(input *C.VipsImage, opts *SimilarityOptions) (*C.VipsImage, error) { + incOpCounter("similarity") + + var out_out *C.VipsImage + + var cOpts C.GenSimilarityOpts + var pinner runtime.Pinner + defer pinner.Unpin() + if opts != nil { + if opts.Scale != nil { + cOpts.has_scale = 1 + cOpts.scale = C.double(*opts.Scale) + } + if opts.Angle != nil { + cOpts.has_angle = 1 + cOpts.angle = C.double(*opts.Angle) + } + if opts.Interpolate != nil { + cOpts.has_interpolate = 1 + cOpts.interpolate = opts.Interpolate + } + if opts.Background != nil { + cOpts.has_background = 1 + pinner.Pin(&opts.Background[0]) + cOpts.background = (*C.double)(unsafe.Pointer(&opts.Background[0])) + cOpts.background_n = C.int(len(opts.Background)) + } + if opts.Odx != nil { + cOpts.has_odx = 1 + cOpts.odx = C.double(*opts.Odx) + } + if opts.Ody != nil { + cOpts.has_ody = 1 + cOpts.ody = C.double(*opts.Ody) + } + if opts.Idx != nil { + cOpts.has_idx = 1 + cOpts.idx = C.double(*opts.Idx) + } + if opts.Idy != nil { + cOpts.has_idy = 1 + cOpts.idy = C.double(*opts.Idy) + } + } + + ret := C.gen_vips_similarity(input, &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// SinesOptions are optional parameters for sines. +type SinesOptions struct { + Uchar *bool + Hfreq *float64 + Vfreq *float64 +} + +// vipsGenSines calls the vips sines operation. +// make a 2D sine wave +func vipsGenSines(width int, height int, opts *SinesOptions) (*C.VipsImage, error) { + incOpCounter("sines") + + var out_out *C.VipsImage + + var cOpts C.GenSinesOpts + if opts != nil { + if opts.Uchar != nil { + cOpts.has_uchar = 1 + cOpts.uchar = C.int(boolToInt(*opts.Uchar)) + } + if opts.Hfreq != nil { + cOpts.has_hfreq = 1 + cOpts.hfreq = C.double(*opts.Hfreq) + } + if opts.Vfreq != nil { + cOpts.has_vfreq = 1 + cOpts.vfreq = C.double(*opts.Vfreq) + } + } + + ret := C.gen_vips_sines(C.int(width), C.int(height), &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// SmartcropOptions are optional parameters for smartcrop. +type SmartcropOptions struct { + Interesting *Interesting + Premultiplied *bool +} + +// vipsGenSmartcrop calls the vips smartcrop operation. +// extract an area from an image +func vipsGenSmartcrop(input *C.VipsImage, width int, height int, opts *SmartcropOptions) (int, *C.VipsImage, int, error) { + incOpCounter("smartcrop") + + var out_attentionX C.int + var out_out *C.VipsImage + var out_attentionY C.int + + var cOpts C.GenSmartcropOpts + if opts != nil { + if opts.Interesting != nil { + cOpts.has_interesting = 1 + cOpts.interesting = C.VipsInteresting(*opts.Interesting) + } + if opts.Premultiplied != nil { + cOpts.has_premultiplied = 1 + cOpts.premultiplied = C.int(boolToInt(*opts.Premultiplied)) + } + } + + ret := C.gen_vips_smartcrop(input, C.int(width), C.int(height), &out_attentionX, &out_out, &out_attentionY, &cOpts) + if ret != 0 { + return 0, nil, 0, handleImageError(out_out) + } + + return int(out_attentionX), out_out, int(out_attentionY), nil +} + +// vipsGenSobel calls the vips sobel operation. +// Sobel edge detector +func vipsGenSobel(input *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("sobel") + + var out_out *C.VipsImage + + ret := C.gen_vips_sobel(input, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenSpcor calls the vips spcor operation. +// spatial correlation +func vipsGenSpcor(input *C.VipsImage, ref *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("spcor") + + var out_out *C.VipsImage + + ret := C.gen_vips_spcor(input, ref, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenSpectrum calls the vips spectrum operation. +// make displayable power spectrum +func vipsGenSpectrum(input *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("spectrum") + + var out_out *C.VipsImage + + ret := C.gen_vips_spectrum(input, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenStats calls the vips stats operation. +// find many image stats +func vipsGenStats(input *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("stats") + + var out_out *C.VipsImage + + ret := C.gen_vips_stats(input, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// StdifOptions are optional parameters for stdif. +type StdifOptions struct { + S0 *float64 + B *float64 + M0 *float64 + A *float64 +} + +// vipsGenStdif calls the vips stdif operation. +// statistical difference +func vipsGenStdif(input *C.VipsImage, width int, height int, opts *StdifOptions) (*C.VipsImage, error) { + incOpCounter("stdif") + + var out_out *C.VipsImage + + var cOpts C.GenStdifOpts + if opts != nil { + if opts.S0 != nil { + cOpts.has_s0 = 1 + cOpts.s0 = C.double(*opts.S0) + } + if opts.B != nil { + cOpts.has_b = 1 + cOpts.b = C.double(*opts.B) + } + if opts.M0 != nil { + cOpts.has_m0 = 1 + cOpts.m0 = C.double(*opts.M0) + } + if opts.A != nil { + cOpts.has_a = 1 + cOpts.a = C.double(*opts.A) + } + } + + ret := C.gen_vips_stdif(input, C.int(width), C.int(height), &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// SubsampleOptions are optional parameters for subsample. +type SubsampleOptions struct { + Point *bool +} + +// vipsGenSubsample calls the vips subsample operation. +// subsample an image +func vipsGenSubsample(input *C.VipsImage, xfac int, yfac int, opts *SubsampleOptions) (*C.VipsImage, error) { + incOpCounter("subsample") + + var out_out *C.VipsImage + + var cOpts C.GenSubsampleOpts + if opts != nil { + if opts.Point != nil { + cOpts.has_point = 1 + cOpts.point = C.int(boolToInt(*opts.Point)) + } + } + + ret := C.gen_vips_subsample(input, C.int(xfac), C.int(yfac), &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenSubtract calls the vips subtract operation. +// subtract two images +func vipsGenSubtract(left *C.VipsImage, right *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("subtract") + + var out_out *C.VipsImage + + ret := C.gen_vips_subtract(left, right, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenSum calls the vips sum operation. +// sum an array of images +func vipsGenSum(input []*C.VipsImage) (*C.VipsImage, error) { + incOpCounter("sum") + + var out_out *C.VipsImage + + ret := C.gen_vips_sum((**C.VipsImage)(unsafe.Pointer(&input[0])), C.int(len(input)), &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// TilecacheOptions are optional parameters for tilecache. +type TilecacheOptions struct { + TileWidth *int + TileHeight *int + MaxTiles *int + Access *int + Threaded *bool + Persistent *bool +} + +// vipsGenTilecache calls the vips tilecache operation. +// cache an image as a set of tiles +func vipsGenTilecache(input *C.VipsImage, opts *TilecacheOptions) (*C.VipsImage, error) { + incOpCounter("tilecache") + + var out_out *C.VipsImage + + var cOpts C.GenTilecacheOpts + if opts != nil { + if opts.TileWidth != nil { + cOpts.has_tileWidth = 1 + cOpts.tileWidth = C.int(*opts.TileWidth) + } + if opts.TileHeight != nil { + cOpts.has_tileHeight = 1 + cOpts.tileHeight = C.int(*opts.TileHeight) + } + if opts.MaxTiles != nil { + cOpts.has_maxTiles = 1 + cOpts.maxTiles = C.int(*opts.MaxTiles) + } + if opts.Access != nil { + cOpts.has_access = 1 + cOpts.access = C.VipsAccess(*opts.Access) + } + if opts.Threaded != nil { + cOpts.has_threaded = 1 + cOpts.threaded = C.int(boolToInt(*opts.Threaded)) + } + if opts.Persistent != nil { + cOpts.has_persistent = 1 + cOpts.persistent = C.int(boolToInt(*opts.Persistent)) + } + } + + ret := C.gen_vips_tilecache(input, &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// TonelutOptions are optional parameters for tonelut. +type TonelutOptions struct { + InMax *int + OutMax *int + Lb *float64 + Lw *float64 + Ps *float64 + Pm *float64 + Ph *float64 + S *float64 + M *float64 + H *float64 +} + +// vipsGenTonelut calls the vips tonelut operation. +// build a look-up table +func vipsGenTonelut(opts *TonelutOptions) (*C.VipsImage, error) { + incOpCounter("tonelut") + + var out_out *C.VipsImage + + var cOpts C.GenTonelutOpts + if opts != nil { + if opts.InMax != nil { + cOpts.has_inMax = 1 + cOpts.inMax = C.int(*opts.InMax) + } + if opts.OutMax != nil { + cOpts.has_outMax = 1 + cOpts.outMax = C.int(*opts.OutMax) + } + if opts.Lb != nil { + cOpts.has_Lb = 1 + cOpts.Lb = C.double(*opts.Lb) + } + if opts.Lw != nil { + cOpts.has_Lw = 1 + cOpts.Lw = C.double(*opts.Lw) + } + if opts.Ps != nil { + cOpts.has_Ps = 1 + cOpts.Ps = C.double(*opts.Ps) + } + if opts.Pm != nil { + cOpts.has_Pm = 1 + cOpts.Pm = C.double(*opts.Pm) + } + if opts.Ph != nil { + cOpts.has_Ph = 1 + cOpts.Ph = C.double(*opts.Ph) + } + if opts.S != nil { + cOpts.has_S = 1 + cOpts.S = C.double(*opts.S) + } + if opts.M != nil { + cOpts.has_M = 1 + cOpts.M = C.double(*opts.M) + } + if opts.H != nil { + cOpts.has_H = 1 + cOpts.H = C.double(*opts.H) + } + } + + ret := C.gen_vips_tonelut(&out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// Transpose3dOptions are optional parameters for transpose3d. +type Transpose3dOptions struct { + PageHeight *int +} + +// vipsGenTranspose3d calls the vips transpose3d operation. +// transpose3d an image +func vipsGenTranspose3d(input *C.VipsImage, opts *Transpose3dOptions) (*C.VipsImage, error) { + incOpCounter("transpose3d") + + var out_out *C.VipsImage + + var cOpts C.GenTranspose3dOpts + if opts != nil { + if opts.PageHeight != nil { + cOpts.has_pageHeight = 1 + cOpts.pageHeight = C.int(*opts.PageHeight) + } + } + + ret := C.gen_vips_transpose3d(input, &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenUhdr2scRGB calls the vips uhdr2scRGB operation. +// transform uhdr to scRGB +func vipsGenUhdr2scRGB(input *C.VipsImage) (*C.VipsImage, error) { + incOpCounter("uhdr2scRGB") + + var out_out *C.VipsImage + + ret := C.gen_vips_uhdr2scRGB(input, &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// UnpremultiplyOptions are optional parameters for unpremultiply. +type UnpremultiplyOptions struct { + MaxAlpha *float64 + AlphaBand *int +} + +// vipsGenUnpremultiply calls the vips unpremultiply operation. +// unpremultiply image alpha +func vipsGenUnpremultiply(input *C.VipsImage, opts *UnpremultiplyOptions) (*C.VipsImage, error) { + incOpCounter("unpremultiply") + + var out_out *C.VipsImage + + var cOpts C.GenUnpremultiplyOpts + if opts != nil { + if opts.MaxAlpha != nil { + cOpts.has_maxAlpha = 1 + cOpts.maxAlpha = C.double(*opts.MaxAlpha) + } + if opts.AlphaBand != nil { + cOpts.has_alphaBand = 1 + cOpts.alphaBand = C.int(*opts.AlphaBand) + } + } + + ret := C.gen_vips_unpremultiply(input, &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// WorleyOptions are optional parameters for worley. +type WorleyOptions struct { + CellSize *int + Seed *int +} + +// vipsGenWorley calls the vips worley operation. +// make a worley noise image +func vipsGenWorley(width int, height int, opts *WorleyOptions) (*C.VipsImage, error) { + incOpCounter("worley") + + var out_out *C.VipsImage + + var cOpts C.GenWorleyOpts + if opts != nil { + if opts.CellSize != nil { + cOpts.has_cellSize = 1 + cOpts.cellSize = C.int(*opts.CellSize) + } + if opts.Seed != nil { + cOpts.has_seed = 1 + cOpts.seed = C.int(*opts.Seed) + } + } + + ret := C.gen_vips_worley(C.int(width), C.int(height), &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// WrapOptions are optional parameters for wrap. +type WrapOptions struct { + X *int + Y *int +} + +// vipsGenWrap calls the vips wrap operation. +// wrap image origin +func vipsGenWrap(input *C.VipsImage, opts *WrapOptions) (*C.VipsImage, error) { + incOpCounter("wrap") + + var out_out *C.VipsImage + + var cOpts C.GenWrapOpts + if opts != nil { + if opts.X != nil { + cOpts.has_x = 1 + cOpts.x = C.int(*opts.X) + } + if opts.Y != nil { + cOpts.has_y = 1 + cOpts.y = C.int(*opts.Y) + } + } + + ret := C.gen_vips_wrap(input, &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// XyzOptions are optional parameters for xyz. +type XyzOptions struct { + Csize *int + Dsize *int + Esize *int +} + +// vipsGenXyz calls the vips xyz operation. +// make an image where pixel values are coordinates +func vipsGenXyz(width int, height int, opts *XyzOptions) (*C.VipsImage, error) { + incOpCounter("xyz") + + var out_out *C.VipsImage + + var cOpts C.GenXyzOpts + if opts != nil { + if opts.Csize != nil { + cOpts.has_csize = 1 + cOpts.csize = C.int(*opts.Csize) + } + if opts.Dsize != nil { + cOpts.has_dsize = 1 + cOpts.dsize = C.int(*opts.Dsize) + } + if opts.Esize != nil { + cOpts.has_esize = 1 + cOpts.esize = C.int(*opts.Esize) + } + } + + ret := C.gen_vips_xyz(C.int(width), C.int(height), &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// ZoneOptions are optional parameters for zone. +type ZoneOptions struct { + Uchar *bool +} + +// vipsGenZone calls the vips zone operation. +// make a zone plate +func vipsGenZone(width int, height int, opts *ZoneOptions) (*C.VipsImage, error) { + incOpCounter("zone") + + var out_out *C.VipsImage + + var cOpts C.GenZoneOpts + if opts != nil { + if opts.Uchar != nil { + cOpts.has_uchar = 1 + cOpts.uchar = C.int(boolToInt(*opts.Uchar)) + } + } + + ret := C.gen_vips_zone(C.int(width), C.int(height), &out_out, &cOpts) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + +// vipsGenZoom calls the vips zoom operation. +// zoom an image +func vipsGenZoom(input *C.VipsImage, xfac int, yfac int) (*C.VipsImage, error) { + incOpCounter("zoom") + + var out_out *C.VipsImage + + ret := C.gen_vips_zoom(input, C.int(xfac), C.int(yfac), &out_out) + if ret != 0 { + return nil, handleImageError(out_out) + } + + return out_out, nil +} + diff --git a/vendor/github.com/davidbyttow/govips/v2/vips/generated.h b/vendor/github.com/davidbyttow/govips/v2/vips/generated.h new file mode 100644 index 0000000000..930eccb5eb --- /dev/null +++ b/vendor/github.com/davidbyttow/govips/v2/vips/generated.h @@ -0,0 +1,1181 @@ +// Code generated by vipsgen. DO NOT EDIT. +#ifndef GENERATED_H +#define GENERATED_H + +#include +#include + +int gen_vips_CMC2LCh(VipsImage * input, VipsImage ** out_out); + +int gen_vips_CMYK2XYZ(VipsImage * input, VipsImage ** out_out); + +int gen_vips_HSV2sRGB(VipsImage * input, VipsImage ** out_out); + +int gen_vips_LCh2CMC(VipsImage * input, VipsImage ** out_out); + +int gen_vips_LCh2Lab(VipsImage * input, VipsImage ** out_out); + +int gen_vips_Lab2LCh(VipsImage * input, VipsImage ** out_out); + +int gen_vips_Lab2LabQ(VipsImage * input, VipsImage ** out_out); + +int gen_vips_Lab2LabS(VipsImage * input, VipsImage ** out_out); + +typedef struct { + int has_temp; + double *temp; int temp_n; +} GenLab2XYZOpts; + +int gen_vips_Lab2XYZ(VipsImage * input, VipsImage ** out_out, GenLab2XYZOpts *opts); + +int gen_vips_LabQ2Lab(VipsImage * input, VipsImage ** out_out); + +int gen_vips_LabQ2LabS(VipsImage * input, VipsImage ** out_out); + +int gen_vips_LabQ2sRGB(VipsImage * input, VipsImage ** out_out); + +int gen_vips_LabS2Lab(VipsImage * input, VipsImage ** out_out); + +int gen_vips_LabS2LabQ(VipsImage * input, VipsImage ** out_out); + +int gen_vips_Oklab2Oklch(VipsImage * input, VipsImage ** out_out); + +int gen_vips_Oklab2XYZ(VipsImage * input, VipsImage ** out_out); + +int gen_vips_Oklch2Oklab(VipsImage * input, VipsImage ** out_out); + +int gen_vips_XYZ2CMYK(VipsImage * input, VipsImage ** out_out); + +typedef struct { + int has_temp; + double *temp; int temp_n; +} GenXYZ2LabOpts; + +int gen_vips_XYZ2Lab(VipsImage * input, VipsImage ** out_out, GenXYZ2LabOpts *opts); + +int gen_vips_XYZ2Oklab(VipsImage * input, VipsImage ** out_out); + +int gen_vips_XYZ2Yxy(VipsImage * input, VipsImage ** out_out); + +int gen_vips_XYZ2scRGB(VipsImage * input, VipsImage ** out_out); + +int gen_vips_Yxy2XYZ(VipsImage * input, VipsImage ** out_out); + +int gen_vips_abs(VipsImage * input, VipsImage ** out_out); + +int gen_vips_add(VipsImage * left, VipsImage * right, VipsImage ** out_out); + +typedef struct { + int has_interpolate; + VipsInterpolate *interpolate; + int has_oarea; + int *oarea; int oarea_n; + int has_odx; + double odx; + int has_ody; + double ody; + int has_idx; + double idx; + int has_idy; + double idy; + int has_background; + double *background; int background_n; + int has_premultiplied; + int premultiplied; + int has_extend; + VipsExtend extend; +} GenAffineOpts; + +int gen_vips_affine(VipsImage * input, double * matrix, int matrix_n, VipsImage ** out_out, GenAffineOpts *opts); + +typedef struct { + int has_across; + int across; + int has_shim; + int shim; + int has_background; + double *background; int background_n; + int has_halign; + VipsAlign halign; + int has_valign; + VipsAlign valign; + int has_hspacing; + int hspacing; + int has_vspacing; + int vspacing; +} GenArrayjoinOpts; + +int gen_vips_arrayjoin(VipsImage **input, int input_n, VipsImage ** out_out, GenArrayjoinOpts *opts); + +int gen_vips_autorot(VipsImage * input, VipsImage ** out_out, int * out_angle, int * out_flip); + +int gen_vips_avg(VipsImage * input, double * out_out); + +int gen_vips_bandbool(VipsImage * input, VipsOperationBoolean boolean, VipsImage ** out_out); + +typedef struct { + int has_factor; + int factor; +} GenBandfoldOpts; + +int gen_vips_bandfold(VipsImage * input, VipsImage ** out_out, GenBandfoldOpts *opts); + +int gen_vips_bandjoin(VipsImage **input, int input_n, VipsImage ** out_out); + +int gen_vips_bandjoin_const(VipsImage * input, double * c, int c_n, VipsImage ** out_out); + +int gen_vips_bandmean(VipsImage * input, VipsImage ** out_out); + +typedef struct { + int has_index; + int index; +} GenBandrankOpts; + +int gen_vips_bandrank(VipsImage **input, int input_n, VipsImage ** out_out, GenBandrankOpts *opts); + +typedef struct { + int has_factor; + int factor; +} GenBandunfoldOpts; + +int gen_vips_bandunfold(VipsImage * input, VipsImage ** out_out, GenBandunfoldOpts *opts); + +typedef struct { + int has_bands; + int bands; +} GenBlackOpts; + +int gen_vips_black(int width, int height, VipsImage ** out_out, GenBlackOpts *opts); + +int gen_vips_boolean(VipsImage * left, VipsImage * right, VipsOperationBoolean boolean, VipsImage ** out_out); + +int gen_vips_boolean_const(VipsImage * input, VipsOperationBoolean boolean, double * c, int c_n, VipsImage ** out_out); + +int gen_vips_buildlut(VipsImage * input, VipsImage ** out_out); + +int gen_vips_byteswap(VipsImage * input, VipsImage ** out_out); + +typedef struct { + int has_maxTiles; + int maxTiles; + int has_tileHeight; + int tileHeight; + int has_tileWidth; + int tileWidth; +} GenCacheOpts; + +int gen_vips_cache(VipsImage * input, VipsImage ** out_out, GenCacheOpts *opts); + +typedef struct { + int has_sigma; + double sigma; + int has_precision; + VipsPrecision precision; +} GenCannyOpts; + +int gen_vips_canny(VipsImage * input, VipsImage ** out_out, GenCannyOpts *opts); + +typedef struct { + int has_shift; + int shift; +} GenCastOpts; + +int gen_vips_cast(VipsImage * input, VipsBandFormat format, VipsImage ** out_out, GenCastOpts *opts); + +typedef struct { + int has_min; + double min; + int has_max; + double max; +} GenClampOpts; + +int gen_vips_clamp(VipsImage * input, VipsImage ** out_out, GenClampOpts *opts); + +typedef struct { + int has_times; + int times; + int has_angle; + VipsAngle45 angle; + int has_combine; + VipsCombine combine; + int has_precision; + VipsPrecision precision; + int has_layers; + int layers; + int has_cluster; + int cluster; +} GenCompassOpts; + +int gen_vips_compass(VipsImage * input, VipsImage * mask, VipsImage ** out_out, GenCompassOpts *opts); + +int gen_vips_complex(VipsImage * input, VipsOperationComplex cmplx, VipsImage ** out_out); + +int gen_vips_complex2(VipsImage * left, VipsImage * right, VipsOperationComplex2 cmplx, VipsImage ** out_out); + +int gen_vips_complexform(VipsImage * left, VipsImage * right, VipsImage ** out_out); + +int gen_vips_complexget(VipsImage * input, VipsOperationComplexget get, VipsImage ** out_out); + +typedef struct { + int has_x; + int x; + int has_y; + int y; + int has_compositingSpace; + VipsInterpretation compositingSpace; + int has_premultiplied; + int premultiplied; +} GenComposite2Opts; + +int gen_vips_composite2(VipsImage * base, VipsImage * overlay, VipsBlendMode mode, VipsImage ** out_out, GenComposite2Opts *opts); + +typedef struct { + int has_precision; + VipsPrecision precision; + int has_layers; + int layers; + int has_cluster; + int cluster; +} GenConvOpts; + +int gen_vips_conv(VipsImage * input, VipsImage * mask, VipsImage ** out_out, GenConvOpts *opts); + +typedef struct { + int has_layers; + int layers; + int has_cluster; + int cluster; +} GenConvaOpts; + +int gen_vips_conva(VipsImage * input, VipsImage * mask, VipsImage ** out_out, GenConvaOpts *opts); + +typedef struct { + int has_layers; + int layers; +} GenConvasepOpts; + +int gen_vips_convasep(VipsImage * input, VipsImage * mask, VipsImage ** out_out, GenConvasepOpts *opts); + +int gen_vips_convf(VipsImage * input, VipsImage * mask, VipsImage ** out_out); + +int gen_vips_convi(VipsImage * input, VipsImage * mask, VipsImage ** out_out); + +typedef struct { + int has_precision; + VipsPrecision precision; + int has_layers; + int layers; + int has_cluster; + int cluster; +} GenConvsepOpts; + +int gen_vips_convsep(VipsImage * input, VipsImage * mask, VipsImage ** out_out, GenConvsepOpts *opts); + +typedef struct { + int has_width; + int width; + int has_height; + int height; + int has_bands; + int bands; + int has_format; + VipsBandFormat format; + int has_coding; + VipsCoding coding; + int has_interpretation; + VipsInterpretation interpretation; + int has_xres; + double xres; + int has_yres; + double yres; + int has_xoffset; + int xoffset; + int has_yoffset; + int yoffset; +} GenCopyOpts; + +int gen_vips_copy(VipsImage * input, VipsImage ** out_out, GenCopyOpts *opts); + +int gen_vips_countlines(VipsImage * input, VipsDirection direction, double * out_nolines); + +int gen_vips_dE00(VipsImage * left, VipsImage * right, VipsImage ** out_out); + +int gen_vips_dE76(VipsImage * left, VipsImage * right, VipsImage ** out_out); + +int gen_vips_dECMC(VipsImage * left, VipsImage * right, VipsImage ** out_out); + +int gen_vips_deviate(VipsImage * input, double * out_out); + +int gen_vips_divide(VipsImage * left, VipsImage * right, VipsImage ** out_out); + +int gen_vips_extract_area(VipsImage * input, int left, int top, int width, int height, VipsImage ** out_out); + +typedef struct { + int has_n; + int n; +} GenExtractBandOpts; + +int gen_vips_extract_band(VipsImage * input, int band, VipsImage ** out_out, GenExtractBandOpts *opts); + +typedef struct { + int has_uchar; + int uchar; + int has_factor; + double factor; +} GenEyeOpts; + +int gen_vips_eye(int width, int height, VipsImage ** out_out, GenEyeOpts *opts); + +int gen_vips_falsecolour(VipsImage * input, VipsImage ** out_out); + +int gen_vips_fastcor(VipsImage * input, VipsImage * ref, VipsImage ** out_out); + +int gen_vips_fill_nearest(VipsImage * input, VipsImage ** out_out, VipsImage ** out_distance); + +typedef struct { + int has_background; + double *background; int background_n; + int has_maxAlpha; + double maxAlpha; +} GenFlattenOpts; + +int gen_vips_flatten(VipsImage * input, VipsImage ** out_out, GenFlattenOpts *opts); + +int gen_vips_flip(VipsImage * input, VipsDirection direction, VipsImage ** out_out); + +int gen_vips_float2rad(VipsImage * input, VipsImage ** out_out); + +int gen_vips_fractsurf(int width, int height, double fractalDimension, VipsImage ** out_out); + +int gen_vips_freqmult(VipsImage * input, VipsImage * mask, VipsImage ** out_out); + +int gen_vips_fwfft(VipsImage * input, VipsImage ** out_out); + +typedef struct { + int has_exponent; + double exponent; +} GenGammaOpts; + +int gen_vips_gamma(VipsImage * input, VipsImage ** out_out, GenGammaOpts *opts); + +typedef struct { + int has_minAmpl; + double minAmpl; + int has_precision; + VipsPrecision precision; +} GenGaussblurOpts; + +int gen_vips_gaussblur(VipsImage * input, double sigma, VipsImage ** out_out, GenGaussblurOpts *opts); + +typedef struct { + int has_separable; + int separable; + int has_precision; + VipsPrecision precision; +} GenGaussmatOpts; + +int gen_vips_gaussmat(double sigma, double minAmpl, VipsImage ** out_out, GenGaussmatOpts *opts); + +typedef struct { + int has_sigma; + double sigma; + int has_mean; + double mean; + int has_seed; + int seed; +} GenGaussnoiseOpts; + +int gen_vips_gaussnoise(int width, int height, VipsImage ** out_out, GenGaussnoiseOpts *opts); + +typedef struct { + int has_gamma; + double gamma; + int has_intOutput; + int intOutput; +} GenGlobalbalanceOpts; + +int gen_vips_globalbalance(VipsImage * input, VipsImage ** out_out, GenGlobalbalanceOpts *opts); + +typedef struct { + int has_extend; + VipsExtend extend; + int has_background; + double *background; int background_n; +} GenGravityOpts; + +int gen_vips_gravity(VipsImage * input, VipsCompassDirection direction, int width, int height, VipsImage ** out_out, GenGravityOpts *opts); + +typedef struct { + int has_uchar; + int uchar; +} GenGreyOpts; + +int gen_vips_grey(int width, int height, VipsImage ** out_out, GenGreyOpts *opts); + +int gen_vips_grid(VipsImage * input, int tileHeight, int across, int down, VipsImage ** out_out); + +int gen_vips_hist_cum(VipsImage * input, VipsImage ** out_out); + +int gen_vips_hist_entropy(VipsImage * input, double * out_out); + +typedef struct { + int has_band; + int band; +} GenHistEqualOpts; + +int gen_vips_hist_equal(VipsImage * input, VipsImage ** out_out, GenHistEqualOpts *opts); + +typedef struct { + int has_band; + int band; +} GenHistFindOpts; + +int gen_vips_hist_find(VipsImage * input, VipsImage ** out_out, GenHistFindOpts *opts); + +typedef struct { + int has_combine; + VipsCombine combine; +} GenHistFindIndexedOpts; + +int gen_vips_hist_find_indexed(VipsImage * input, VipsImage * index, VipsImage ** out_out, GenHistFindIndexedOpts *opts); + +typedef struct { + int has_bins; + int bins; +} GenHistFindNdimOpts; + +int gen_vips_hist_find_ndim(VipsImage * input, VipsImage ** out_out, GenHistFindNdimOpts *opts); + +int gen_vips_hist_ismonotonic(VipsImage * input, int * out_monotonic); + +typedef struct { + int has_maxSlope; + int maxSlope; +} GenHistLocalOpts; + +int gen_vips_hist_local(VipsImage * input, int width, int height, VipsImage ** out_out, GenHistLocalOpts *opts); + +int gen_vips_hist_match(VipsImage * input, VipsImage * ref, VipsImage ** out_out); + +int gen_vips_hist_norm(VipsImage * input, VipsImage ** out_out); + +int gen_vips_hist_plot(VipsImage * input, VipsImage ** out_out); + +typedef struct { + int has_scale; + int scale; + int has_minRadius; + int minRadius; + int has_maxRadius; + int maxRadius; +} GenHoughCircleOpts; + +int gen_vips_hough_circle(VipsImage * input, VipsImage ** out_out, GenHoughCircleOpts *opts); + +typedef struct { + int has_width; + int width; + int has_height; + int height; +} GenHoughLineOpts; + +int gen_vips_hough_line(VipsImage * input, VipsImage ** out_out, GenHoughLineOpts *opts); + +typedef struct { + int has_pcs; + VipsPCS pcs; + int has_intent; + VipsIntent intent; + int has_blackPointCompensation; + int blackPointCompensation; + int has_outputProfile; + const char *outputProfile; + int has_depth; + int depth; +} GenIccExportOpts; + +int gen_vips_icc_export(VipsImage * input, VipsImage ** out_out, GenIccExportOpts *opts); + +typedef struct { + int has_pcs; + VipsPCS pcs; + int has_intent; + VipsIntent intent; + int has_blackPointCompensation; + int blackPointCompensation; + int has_embedded; + int embedded; + int has_inputProfile; + const char *inputProfile; +} GenIccImportOpts; + +int gen_vips_icc_import(VipsImage * input, VipsImage ** out_out, GenIccImportOpts *opts); + +typedef struct { + int has_bands; + int bands; + int has_ushort; + int ushort; + int has_size; + int size; +} GenIdentityOpts; + +int gen_vips_identity(VipsImage ** out_out, GenIdentityOpts *opts); + +typedef struct { + int has_blend; + int blend; +} GenIfthenelseOpts; + +int gen_vips_ifthenelse(VipsImage * cond, VipsImage * in1, VipsImage * in2, VipsImage ** out_out, GenIfthenelseOpts *opts); + +typedef struct { + int has_expand; + int expand; + int has_background; + double *background; int background_n; +} GenInsertOpts; + +int gen_vips_insert(VipsImage * main, VipsImage * sub, int x, int y, VipsImage ** out_out, GenInsertOpts *opts); + +int gen_vips_invert(VipsImage * input, VipsImage ** out_out); + +typedef struct { + int has_size; + int size; +} GenInvertlutOpts; + +int gen_vips_invertlut(VipsImage * input, VipsImage ** out_out, GenInvertlutOpts *opts); + +typedef struct { + int has_real; + int real; +} GenInvfftOpts; + +int gen_vips_invfft(VipsImage * input, VipsImage ** out_out, GenInvfftOpts *opts); + +typedef struct { + int has_expand; + int expand; + int has_shim; + int shim; + int has_background; + double *background; int background_n; + int has_align; + VipsAlign align; +} GenJoinOpts; + +int gen_vips_join(VipsImage * in1, VipsImage * in2, VipsDirection direction, VipsImage ** out_out, GenJoinOpts *opts); + +int gen_vips_labelregions(VipsImage * input, VipsImage ** out_mask, int * out_segments); + +typedef struct { + int has_uchar; + int uchar; +} GenLinearOpts; + +int gen_vips_linear(VipsImage * input, double * a, int a_n, double * b, int b_n, VipsImage ** out_out, GenLinearOpts *opts); + +typedef struct { + int has_tileHeight; + int tileHeight; + int has_access; + VipsAccess access; + int has_threaded; + int threaded; + int has_persistent; + int persistent; +} GenLinecacheOpts; + +int gen_vips_linecache(VipsImage * input, VipsImage ** out_out, GenLinecacheOpts *opts); + +typedef struct { + int has_separable; + int separable; + int has_precision; + VipsPrecision precision; +} GenLogmatOpts; + +int gen_vips_logmat(double sigma, double minAmpl, VipsImage ** out_out, GenLogmatOpts *opts); + +typedef struct { + int has_interpolate; + VipsInterpolate *interpolate; + int has_background; + double *background; int background_n; + int has_premultiplied; + int premultiplied; + int has_extend; + VipsExtend extend; +} GenMapimOpts; + +int gen_vips_mapim(VipsImage * input, VipsImage * index, VipsImage ** out_out, GenMapimOpts *opts); + +typedef struct { + int has_band; + int band; +} GenMaplutOpts; + +int gen_vips_maplut(VipsImage * input, VipsImage * lut, VipsImage ** out_out, GenMaplutOpts *opts); + +typedef struct { + int has_uchar; + int uchar; + int has_nodc; + int nodc; + int has_reject; + int reject; + int has_optical; + int optical; +} GenMaskButterworthOpts; + +int gen_vips_mask_butterworth(int width, int height, double order, double frequencyCutoff, double amplitudeCutoff, VipsImage ** out_out, GenMaskButterworthOpts *opts); + +typedef struct { + int has_uchar; + int uchar; + int has_nodc; + int nodc; + int has_reject; + int reject; + int has_optical; + int optical; +} GenMaskButterworthBandOpts; + +int gen_vips_mask_butterworth_band(int width, int height, double order, double frequencyCutoffX, double frequencyCutoffY, double radius, double amplitudeCutoff, VipsImage ** out_out, GenMaskButterworthBandOpts *opts); + +typedef struct { + int has_uchar; + int uchar; + int has_nodc; + int nodc; + int has_reject; + int reject; + int has_optical; + int optical; +} GenMaskButterworthRingOpts; + +int gen_vips_mask_butterworth_ring(int width, int height, double order, double frequencyCutoff, double amplitudeCutoff, double ringwidth, VipsImage ** out_out, GenMaskButterworthRingOpts *opts); + +typedef struct { + int has_uchar; + int uchar; + int has_nodc; + int nodc; + int has_reject; + int reject; + int has_optical; + int optical; +} GenMaskFractalOpts; + +int gen_vips_mask_fractal(int width, int height, double fractalDimension, VipsImage ** out_out, GenMaskFractalOpts *opts); + +typedef struct { + int has_uchar; + int uchar; + int has_nodc; + int nodc; + int has_reject; + int reject; + int has_optical; + int optical; +} GenMaskGaussianOpts; + +int gen_vips_mask_gaussian(int width, int height, double frequencyCutoff, double amplitudeCutoff, VipsImage ** out_out, GenMaskGaussianOpts *opts); + +typedef struct { + int has_uchar; + int uchar; + int has_nodc; + int nodc; + int has_reject; + int reject; + int has_optical; + int optical; +} GenMaskGaussianBandOpts; + +int gen_vips_mask_gaussian_band(int width, int height, double frequencyCutoffX, double frequencyCutoffY, double radius, double amplitudeCutoff, VipsImage ** out_out, GenMaskGaussianBandOpts *opts); + +typedef struct { + int has_uchar; + int uchar; + int has_nodc; + int nodc; + int has_reject; + int reject; + int has_optical; + int optical; +} GenMaskGaussianRingOpts; + +int gen_vips_mask_gaussian_ring(int width, int height, double frequencyCutoff, double amplitudeCutoff, double ringwidth, VipsImage ** out_out, GenMaskGaussianRingOpts *opts); + +typedef struct { + int has_uchar; + int uchar; + int has_nodc; + int nodc; + int has_reject; + int reject; + int has_optical; + int optical; +} GenMaskIdealOpts; + +int gen_vips_mask_ideal(int width, int height, double frequencyCutoff, VipsImage ** out_out, GenMaskIdealOpts *opts); + +typedef struct { + int has_uchar; + int uchar; + int has_nodc; + int nodc; + int has_reject; + int reject; + int has_optical; + int optical; +} GenMaskIdealBandOpts; + +int gen_vips_mask_ideal_band(int width, int height, double frequencyCutoffX, double frequencyCutoffY, double radius, VipsImage ** out_out, GenMaskIdealBandOpts *opts); + +typedef struct { + int has_uchar; + int uchar; + int has_nodc; + int nodc; + int has_reject; + int reject; + int has_optical; + int optical; +} GenMaskIdealRingOpts; + +int gen_vips_mask_ideal_ring(int width, int height, double frequencyCutoff, double ringwidth, VipsImage ** out_out, GenMaskIdealRingOpts *opts); + +typedef struct { + int has_hwindow; + int hwindow; + int has_harea; + int harea; + int has_search; + int search; + int has_interpolate; + VipsInterpolate *interpolate; +} GenMatchOpts; + +int gen_vips_match(VipsImage * ref, VipsImage * sec, int xr1, int yr1, int xs1, int ys1, int xr2, int yr2, int xs2, int ys2, VipsImage ** out_out, GenMatchOpts *opts); + +int gen_vips_math(VipsImage * input, VipsOperationMath math, VipsImage ** out_out); + +int gen_vips_math2(VipsImage * left, VipsImage * right, VipsOperationMath2 math2, VipsImage ** out_out); + +int gen_vips_math2_const(VipsImage * input, VipsOperationMath2 math2, double * c, int c_n, VipsImage ** out_out); + +int gen_vips_matrixinvert(VipsImage * input, VipsImage ** out_out); + +int gen_vips_matrixmultiply(VipsImage * left, VipsImage * right, VipsImage ** out_out); + +int gen_vips_maxpair(VipsImage * left, VipsImage * right, VipsImage ** out_out); + +typedef struct { + int has_mblend; + int mblend; +} GenMergeOpts; + +int gen_vips_merge(VipsImage * ref, VipsImage * sec, VipsDirection direction, int dx, int dy, VipsImage ** out_out, GenMergeOpts *opts); + +int gen_vips_minpair(VipsImage * left, VipsImage * right, VipsImage ** out_out); + +int gen_vips_morph(VipsImage * input, VipsImage * mask, VipsOperationMorphology morph, VipsImage ** out_out); + +typedef struct { + int has_hwindow; + int hwindow; + int has_harea; + int harea; + int has_mblend; + int mblend; + int has_bandno; + int bandno; +} GenMosaicOpts; + +int gen_vips_mosaic(VipsImage * ref, VipsImage * sec, VipsDirection direction, int xref, int yref, int xsec, int ysec, VipsImage ** out_out, int * out_dx0, int * out_dy0, double * out_scale1, double * out_angle1, double * out_dy1, double * out_dx1, GenMosaicOpts *opts); + +typedef struct { + int has_hwindow; + int hwindow; + int has_harea; + int harea; + int has_search; + int search; + int has_interpolate; + VipsInterpolate *interpolate; + int has_mblend; + int mblend; +} GenMosaic1Opts; + +int gen_vips_mosaic1(VipsImage * ref, VipsImage * sec, VipsDirection direction, int xr1, int yr1, int xs1, int ys1, int xr2, int yr2, int xs2, int ys2, VipsImage ** out_out, GenMosaic1Opts *opts); + +typedef struct { + int has_band; + int band; +} GenMsbOpts; + +int gen_vips_msb(VipsImage * input, VipsImage ** out_out, GenMsbOpts *opts); + +int gen_vips_multiply(VipsImage * left, VipsImage * right, VipsImage ** out_out); + +int gen_vips_percent(VipsImage * input, double percent, int * out_threshold); + +typedef struct { + int has_cellSize; + int cellSize; + int has_uchar; + int uchar; + int has_seed; + int seed; +} GenPerlinOpts; + +int gen_vips_perlin(int width, int height, VipsImage ** out_out, GenPerlinOpts *opts); + +int gen_vips_phasecor(VipsImage * input, VipsImage * in2, VipsImage ** out_out); + +typedef struct { + int has_maxAlpha; + double maxAlpha; +} GenPremultiplyOpts; + +int gen_vips_premultiply(VipsImage * input, VipsImage ** out_out, GenPremultiplyOpts *opts); + +int gen_vips_prewitt(VipsImage * input, VipsImage ** out_out); + +int gen_vips_profile(VipsImage * input, VipsImage ** out_columns, VipsImage ** out_rows); + +int gen_vips_project(VipsImage * input, VipsImage ** out_columns, VipsImage ** out_rows); + +typedef struct { + int has_interpolate; + VipsInterpolate *interpolate; +} GenQuadraticOpts; + +int gen_vips_quadratic(VipsImage * input, VipsImage * coeff, VipsImage ** out_out, GenQuadraticOpts *opts); + +int gen_vips_rad2float(VipsImage * input, VipsImage ** out_out); + +int gen_vips_rank(VipsImage * input, int width, int height, int index, VipsImage ** out_out); + +int gen_vips_recomb(VipsImage * input, VipsImage * m, VipsImage ** out_out); + +typedef struct { + int has_kernel; + VipsKernel kernel; + int has_gap; + double gap; +} GenReduceOpts; + +int gen_vips_reduce(VipsImage * input, double hshrink, double vshrink, VipsImage ** out_out, GenReduceOpts *opts); + +typedef struct { + int has_kernel; + VipsKernel kernel; + int has_gap; + double gap; +} GenReducehOpts; + +int gen_vips_reduceh(VipsImage * input, double hshrink, VipsImage ** out_out, GenReducehOpts *opts); + +typedef struct { + int has_kernel; + VipsKernel kernel; + int has_gap; + double gap; +} GenReducevOpts; + +int gen_vips_reducev(VipsImage * input, double vshrink, VipsImage ** out_out, GenReducevOpts *opts); + +int gen_vips_relational(VipsImage * left, VipsImage * right, VipsOperationRelational relational, VipsImage ** out_out); + +int gen_vips_relational_const(VipsImage * input, VipsOperationRelational relational, double * c, int c_n, VipsImage ** out_out); + +int gen_vips_remainder(VipsImage * left, VipsImage * right, VipsImage ** out_out); + +int gen_vips_remainder_const(VipsImage * input, double * c, int c_n, VipsImage ** out_out); + +int gen_vips_remosaic(VipsImage * input, const char * oldStr, const char * newStr, VipsImage ** out_out); + +int gen_vips_replicate(VipsImage * input, int across, int down, VipsImage ** out_out); + +int gen_vips_rot(VipsImage * input, VipsAngle angle, VipsImage ** out_out); + +typedef struct { + int has_angle; + VipsAngle45 angle; +} GenRot45Opts; + +int gen_vips_rot45(VipsImage * input, VipsImage ** out_out, GenRot45Opts *opts); + +typedef struct { + int has_interpolate; + VipsInterpolate *interpolate; + int has_background; + double *background; int background_n; + int has_odx; + double odx; + int has_ody; + double ody; + int has_idx; + double idx; + int has_idy; + double idy; +} GenRotateOpts; + +int gen_vips_rotate(VipsImage * input, double angle, VipsImage ** out_out, GenRotateOpts *opts); + +int gen_vips_round(VipsImage * input, VipsOperationRound round, VipsImage ** out_out); + +int gen_vips_sRGB2HSV(VipsImage * input, VipsImage ** out_out); + +int gen_vips_sRGB2scRGB(VipsImage * input, VipsImage ** out_out); + +typedef struct { + int has_depth; + int depth; +} GenScRGB2BWOpts; + +int gen_vips_scRGB2BW(VipsImage * input, VipsImage ** out_out, GenScRGB2BWOpts *opts); + +int gen_vips_scRGB2XYZ(VipsImage * input, VipsImage ** out_out); + +typedef struct { + int has_depth; + int depth; +} GenScRGB2sRGBOpts; + +int gen_vips_scRGB2sRGB(VipsImage * input, VipsImage ** out_out, GenScRGB2sRGBOpts *opts); + +typedef struct { + int has_exp; + double exp; + int has_log; + int log; +} GenScaleOpts; + +int gen_vips_scale(VipsImage * input, VipsImage ** out_out, GenScaleOpts *opts); + +int gen_vips_scharr(VipsImage * input, VipsImage ** out_out); + +typedef struct { + int has_tileHeight; + int tileHeight; +} GenSequentialOpts; + +int gen_vips_sequential(VipsImage * input, VipsImage ** out_out, GenSequentialOpts *opts); + +typedef struct { + int has_sigma; + double sigma; + int has_x1; + double x1; + int has_y2; + double y2; + int has_y3; + double y3; + int has_m1; + double m1; + int has_m2; + double m2; +} GenSharpenOpts; + +int gen_vips_sharpen(VipsImage * input, VipsImage ** out_out, GenSharpenOpts *opts); + +typedef struct { + int has_ceil; + int ceil; +} GenShrinkOpts; + +int gen_vips_shrink(VipsImage * input, double hshrink, double vshrink, VipsImage ** out_out, GenShrinkOpts *opts); + +typedef struct { + int has_ceil; + int ceil; +} GenShrinkhOpts; + +int gen_vips_shrinkh(VipsImage * input, int hshrink, VipsImage ** out_out, GenShrinkhOpts *opts); + +typedef struct { + int has_ceil; + int ceil; +} GenShrinkvOpts; + +int gen_vips_shrinkv(VipsImage * input, int vshrink, VipsImage ** out_out, GenShrinkvOpts *opts); + +int gen_vips_sign(VipsImage * input, VipsImage ** out_out); + +typedef struct { + int has_scale; + double scale; + int has_angle; + double angle; + int has_interpolate; + VipsInterpolate *interpolate; + int has_background; + double *background; int background_n; + int has_odx; + double odx; + int has_ody; + double ody; + int has_idx; + double idx; + int has_idy; + double idy; +} GenSimilarityOpts; + +int gen_vips_similarity(VipsImage * input, VipsImage ** out_out, GenSimilarityOpts *opts); + +typedef struct { + int has_uchar; + int uchar; + int has_hfreq; + double hfreq; + int has_vfreq; + double vfreq; +} GenSinesOpts; + +int gen_vips_sines(int width, int height, VipsImage ** out_out, GenSinesOpts *opts); + +typedef struct { + int has_interesting; + VipsInteresting interesting; + int has_premultiplied; + int premultiplied; +} GenSmartcropOpts; + +int gen_vips_smartcrop(VipsImage * input, int width, int height, int * out_attentionX, VipsImage ** out_out, int * out_attentionY, GenSmartcropOpts *opts); + +int gen_vips_sobel(VipsImage * input, VipsImage ** out_out); + +int gen_vips_spcor(VipsImage * input, VipsImage * ref, VipsImage ** out_out); + +int gen_vips_spectrum(VipsImage * input, VipsImage ** out_out); + +int gen_vips_stats(VipsImage * input, VipsImage ** out_out); + +typedef struct { + int has_s0; + double s0; + int has_b; + double b; + int has_m0; + double m0; + int has_a; + double a; +} GenStdifOpts; + +int gen_vips_stdif(VipsImage * input, int width, int height, VipsImage ** out_out, GenStdifOpts *opts); + +typedef struct { + int has_point; + int point; +} GenSubsampleOpts; + +int gen_vips_subsample(VipsImage * input, int xfac, int yfac, VipsImage ** out_out, GenSubsampleOpts *opts); + +int gen_vips_subtract(VipsImage * left, VipsImage * right, VipsImage ** out_out); + +int gen_vips_sum(VipsImage **input, int input_n, VipsImage ** out_out); + +typedef struct { + int has_tileWidth; + int tileWidth; + int has_tileHeight; + int tileHeight; + int has_maxTiles; + int maxTiles; + int has_access; + VipsAccess access; + int has_threaded; + int threaded; + int has_persistent; + int persistent; +} GenTilecacheOpts; + +int gen_vips_tilecache(VipsImage * input, VipsImage ** out_out, GenTilecacheOpts *opts); + +typedef struct { + int has_inMax; + int inMax; + int has_outMax; + int outMax; + int has_Lb; + double Lb; + int has_Lw; + double Lw; + int has_Ps; + double Ps; + int has_Pm; + double Pm; + int has_Ph; + double Ph; + int has_S; + double S; + int has_M; + double M; + int has_H; + double H; +} GenTonelutOpts; + +int gen_vips_tonelut(VipsImage ** out_out, GenTonelutOpts *opts); + +typedef struct { + int has_pageHeight; + int pageHeight; +} GenTranspose3dOpts; + +int gen_vips_transpose3d(VipsImage * input, VipsImage ** out_out, GenTranspose3dOpts *opts); + +int gen_vips_uhdr2scRGB(VipsImage * input, VipsImage ** out_out); + +typedef struct { + int has_maxAlpha; + double maxAlpha; + int has_alphaBand; + int alphaBand; +} GenUnpremultiplyOpts; + +int gen_vips_unpremultiply(VipsImage * input, VipsImage ** out_out, GenUnpremultiplyOpts *opts); + +typedef struct { + int has_cellSize; + int cellSize; + int has_seed; + int seed; +} GenWorleyOpts; + +int gen_vips_worley(int width, int height, VipsImage ** out_out, GenWorleyOpts *opts); + +typedef struct { + int has_x; + int x; + int has_y; + int y; +} GenWrapOpts; + +int gen_vips_wrap(VipsImage * input, VipsImage ** out_out, GenWrapOpts *opts); + +typedef struct { + int has_csize; + int csize; + int has_dsize; + int dsize; + int has_esize; + int esize; +} GenXyzOpts; + +int gen_vips_xyz(int width, int height, VipsImage ** out_out, GenXyzOpts *opts); + +typedef struct { + int has_uchar; + int uchar; +} GenZoneOpts; + +int gen_vips_zone(int width, int height, VipsImage ** out_out, GenZoneOpts *opts); + +int gen_vips_zoom(VipsImage * input, int xfac, int yfac, VipsImage ** out_out); + +#endif diff --git a/vendor/github.com/davidbyttow/govips/v2/vips/govips.go b/vendor/github.com/davidbyttow/govips/v2/vips/govips.go index 2036ebbe01..37b1f54416 100644 --- a/vendor/github.com/davidbyttow/govips/v2/vips/govips.go +++ b/vendor/github.com/davidbyttow/govips/v2/vips/govips.go @@ -6,6 +6,7 @@ package vips // #include "govips.h" import "C" import ( + "errors" "fmt" "os" "runtime" @@ -56,9 +57,9 @@ type Config struct { // Startup sets up the libvips support and ensures the versions are correct. Pass in nil for // default configuration. -func Startup(config *Config) { +func Startup(config *Config) error { if hasShutdown { - panic("govips cannot be stopped and restarted") + return errors.New("govips cannot be stopped and restarted") } initLock.Lock() @@ -69,15 +70,15 @@ func Startup(config *Config) { if running { govipsLog("govips", LogLevelInfo, "warning libvips already started") - return + return nil } if MajorVersion < 8 { - panic("govips requires libvips version 8.10+") + return errors.New("govips requires libvips version 8.10+") } if MajorVersion == 8 && MinorVersion < 10 { - panic("govips requires libvips version 8.10+") + return errors.New("govips requires libvips version 8.10+") } cName := C.CString("govips") @@ -93,7 +94,7 @@ func Startup(config *Config) { err := C.vips_init(cName) if err != 0 { - panic(fmt.Sprintf("Failed to start vips code=%v", err)) + return fmt.Errorf("failed to start vips code=%v", err) } running = true @@ -147,6 +148,7 @@ func Startup(config *Config) { int(C.vips_cache_get_max()))) initTypes() + return nil } func enableLogging() { @@ -234,7 +236,9 @@ func ReadVipsMemStats(stats *MemoryStats) { func startupIfNeeded() { if !running { govipsLog("govips", LogLevelInfo, "libvips was forcibly started automatically, consider calling Startup/Shutdown yourself") - Startup(nil) + if err := Startup(nil); err != nil { + panic(err) + } } } diff --git a/vendor/github.com/davidbyttow/govips/v2/vips/header.c b/vendor/github.com/davidbyttow/govips/v2/vips/header.c deleted file mode 100644 index 6744c840d7..0000000000 --- a/vendor/github.com/davidbyttow/govips/v2/vips/header.c +++ /dev/null @@ -1,122 +0,0 @@ -#include "header.h" - -#include - -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; -} \ No newline at end of file diff --git a/vendor/github.com/davidbyttow/govips/v2/vips/header.go b/vendor/github.com/davidbyttow/govips/v2/vips/header.go deleted file mode 100644 index a85e47c516..0000000000 --- a/vendor/github.com/davidbyttow/govips/v2/vips/header.go +++ /dev/null @@ -1,289 +0,0 @@ -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 "" -} diff --git a/vendor/github.com/davidbyttow/govips/v2/vips/header.h b/vendor/github.com/davidbyttow/govips/v2/vips/header.h deleted file mode 100644 index 9a4983e2e4..0000000000 --- a/vendor/github.com/davidbyttow/govips/v2/vips/header.h +++ /dev/null @@ -1,41 +0,0 @@ -// https://libvips.github.io/libvips/API/current/libvips-header.html - -#include -#include - -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); \ No newline at end of file diff --git a/vendor/github.com/davidbyttow/govips/v2/vips/icc_profiles.go b/vendor/github.com/davidbyttow/govips/v2/vips/icc_profiles.go index 94f467bb4b..8d5c55fb00 100644 --- a/vendor/github.com/davidbyttow/govips/v2/vips/icc_profiles.go +++ b/vendor/github.com/davidbyttow/govips/v2/vips/icc_profiles.go @@ -677,16 +677,14 @@ func ensureLoadICCPath(name *string) (err error) { return } +var tempDirOnce sync.Once +var tempDirErr error + func getTemporaryDirectory() (string, error) { - if temporaryDirectory != "" { - return temporaryDirectory, nil - } - var err error - temporaryDirectory, err = os.MkdirTemp("", "govips-") - if err != nil { - return "", err - } - return temporaryDirectory, nil + tempDirOnce.Do(func() { + temporaryDirectory, tempDirErr = os.MkdirTemp("", "govips-") + }) + return temporaryDirectory, tempDirErr } var lockIcc sync.Mutex diff --git a/vendor/github.com/davidbyttow/govips/v2/vips/image.c b/vendor/github.com/davidbyttow/govips/v2/vips/image.c index 6352f0d184..a9046f1eb6 100644 --- a/vendor/github.com/davidbyttow/govips/v2/vips/image.c +++ b/vendor/github.com/davidbyttow/govips/v2/vips/image.c @@ -7,3 +7,10 @@ void clear_image(VipsImage **image) { // https://docs.gtk.org/gobject/method.Object.unref.html if (G_IS_OBJECT(*image)) g_object_unref(*image); } + +VipsImage *create_image_from_memory_copy(const void *data, size_t size, + int width, int height, int bands, + VipsBandFormat format) { + return vips_image_new_from_memory_copy(data, size, width, height, bands, + format); +} diff --git a/vendor/github.com/davidbyttow/govips/v2/vips/image.go b/vendor/github.com/davidbyttow/govips/v2/vips/image.go index 1eb1d6fdba..f36f2f1c94 100644 --- a/vendor/github.com/davidbyttow/govips/v2/vips/image.go +++ b/vendor/github.com/davidbyttow/govips/v2/vips/image.go @@ -8,7 +8,9 @@ import ( "errors" "fmt" "image" + "image/draw" _ "image/gif" + "math" _ "image/jpeg" _ "image/png" "io" @@ -18,6 +20,8 @@ import ( "strings" "sync" "unsafe" + + _ "golang.org/x/image/webp" ) const GaussBlurDefaultMinAMpl = 0.2 @@ -113,6 +117,7 @@ type ImportParams struct { JpegShrinkFactor IntParameter HeifThumbnail BoolParameter SvgUnlimited BoolParameter + Access IntParameter } // NewImportParams creates default ImportParams @@ -149,6 +154,9 @@ func (i *ImportParams) OptionString() string { if v := i.HeifThumbnail; v.IsSet() { values = append(values, "thumbnail="+boolToStr(v.Get())) } + if v := i.Access; v.IsSet() { + values = append(values, "access="+strconv.Itoa(v.Get())) + } return strings.Join(values, ",") } @@ -325,16 +333,24 @@ func NewTiffExportParams() *TiffExportParams { } } -// GifExportParams are options when exporting a GIF to file or buffer -// Please note that if vips version is above 8.12, then `vips_gifsave_buffer` is used, and only `Dither`, `Effort`, `Bitdepth` is used. -// If vips version is below 8.12, then `vips_magicksave_buffer` is used, and only `Bitdepth`, `Quality` is used. -// StripMetadata does nothing to Gif images. +// GifExportParams are options when exporting a GIF to file or buffer. +// +// For vips 8.12+, native gifsave is used. The relevant parameters are Dither, +// Effort, and Bitdepth. Quality is ignored because native gifsave does not +// support a quality parameter. +// +// For vips below 8.12, magicksave is used as a fallback. The relevant +// parameters are Quality and Bitdepth. +// +// StripMetadata has no effect on GIF images. type GifExportParams struct { StripMetadata bool - Quality int - Dither float64 - Effort int - Bitdepth int + // Quality is only used with vips < 8.12 (magicksave fallback). + // Ignored by native gifsave in vips 8.12+. + Quality int + Dither float64 + Effort int + Bitdepth int } // NewGifExportParams creates default values for an export of a GIF image. @@ -424,6 +440,22 @@ func NewJxlExportParams() *JxlExportParams { } } +// MagickExportParams are options when exporting an image to file or buffer by ImageMagick. +type MagickExportParams struct { + Quality int + Format string + OptimizeGifFrames bool + OptimizeGifTransparency bool + BitDepth int +} + +// NewMagickExportParams creates default values for an export of an image by ImageMagick. +func NewMagickExportParams() *MagickExportParams { + return &MagickExportParams{ + Quality: 75, + } +} + // NewImageFromReader loads an ImageRef from the given reader func NewImageFromReader(r io.Reader) (*ImageRef, error) { buf, err := io.ReadAll(r) @@ -538,7 +570,7 @@ func (r *ImageRef) Metadata() *ImageMetadata { // Copy creates a new copy of the given image. func (r *ImageRef) Copy() (*ImageRef, error) { - out, err := vipsCopyImage(r.image) + out, err := vipsGenCopy(r.image, nil) if err != nil { return nil, err } @@ -548,7 +580,7 @@ func (r *ImageRef) Copy() (*ImageRef, error) { // Copy creates a new copy of the given image with the new X and Y resolution (PPI). func (r *ImageRef) CopyChangingResolution(xres, yres float64) (*ImageRef, error) { - out, err := vipsCopyImageChangingResolution(r.image, xres, yres) + out, err := vipsGenCopy(r.image, &CopyOptions{Xres: &xres, Yres: &yres}) if err != nil { return nil, err } @@ -558,7 +590,7 @@ func (r *ImageRef) CopyChangingResolution(xres, yres float64) (*ImageRef, error) // Copy creates a new copy of the given image with the interpretation. func (r *ImageRef) CopyChangingInterpretation(interpretation Interpretation) (*ImageRef, error) { - out, err := vipsCopyImageChangingInterpretation(r.image, interpretation) + out, err := vipsGenCopy(r.image, &CopyOptions{Interpretation: &interpretation}) if err != nil { return nil, err } @@ -569,20 +601,20 @@ func (r *ImageRef) CopyChangingInterpretation(interpretation Interpretation) (*I // XYZ creates a two-band uint32 image where the elements in the first band have the value of their x coordinate // and elements in the second band have their y coordinate. func XYZ(width, height int) (*ImageRef, error) { - vipsImage, err := vipsXYZ(width, height) + vipsImage, err := vipsGenXyz(width, height, nil) return newImageRef(vipsImage, ImageTypeUnknown, ImageTypeUnknown, nil), err } // Identity creates an identity lookup table, which will leave an image unchanged when applied with Maplut. // Each entry in the table has a value equal to its position. func Identity(ushort bool) (*ImageRef, error) { - img, err := vipsIdentity(ushort) + img, err := vipsGenIdentity(&IdentityOptions{Ushort: &ushort}) return newImageRef(img, ImageTypeUnknown, ImageTypeUnknown, nil), err } // Black creates a new black image of the specified size func Black(width, height int) (*ImageRef, error) { - vipsImage, err := vipsBlack(width, height) + vipsImage, err := vipsGenBlack(width, height, nil) imageRef := &ImageRef{ image: vipsImage, } @@ -590,6 +622,44 @@ func Black(width, height int) (*ImageRef, error) { return imageRef, err } +// Grey creates a horizontal gradient image (ramp from black to white). +// When uchar is true, pixel values are 0-255 uint8; when false, 0.0-1.0 float. +// Useful for creating gradient overlays when combined with rotation, BandJoin, and Composite. +func Grey(width, height int, uchar bool) (*ImageRef, error) { + img, err := vipsGenGrey(width, height, &GreyOptions{Uchar: &uchar}) + if err != nil { + return nil, err + } + return newImageRef(img, ImageTypeUnknown, ImageTypeUnknown, nil), nil +} + +// NewTransparentCanvas creates a fully transparent RGBA image of the given dimensions. +// The image is in sRGB color space with 4 bands (RGBA), all channels set to 0. +func NewTransparentCanvas(width, height int) (*ImageRef, error) { + ref, err := Black(width, height) + if err != nil { + return nil, err + } + + if err := ref.ToColorSpace(InterpretationSRGB); err != nil { + ref.Close() + return nil, err + } + + if err := ref.BandJoinConst([]float64{0}); err != nil { + ref.Close() + return nil, err + } + + return ref, nil +} + +// Text draws the string text to an image. +func Text(params *TextParams) (*ImageRef, error) { + img, err := vipsText(params) + return newImageRef(img, ImageTypeUnknown, ImageTypeUnknown, nil), err +} + func newImageRef(vipsImage *C.VipsImage, currentFormat ImageType, originalFormat ImageType, buf []byte) *ImageRef { imageRef := &ImageRef{ image: vipsImage, @@ -653,6 +723,7 @@ func (r *ImageRef) Bands() int { // HasProfile returns if the image has an ICC profile embedded. func (r *ImageRef) HasProfile() bool { + defer runtime.KeepAlive(r) return vipsHasICCProfile(r.image) } @@ -663,16 +734,19 @@ func (r *ImageRef) HasICCProfile() bool { // HasIPTC returns a boolean whether the image in question has IPTC data associated with it. func (r *ImageRef) HasIPTC() bool { + defer runtime.KeepAlive(r) return vipsHasIPTC(r.image) } // HasAlpha returns if the image has an alpha layer. func (r *ImageRef) HasAlpha() bool { + defer runtime.KeepAlive(r) return vipsHasAlpha(r.image) } // Orientation returns the orientation number as it appears in the EXIF, if present func (r *ImageRef) Orientation() int { + defer runtime.KeepAlive(r) return vipsGetMetaOrientation(r.image) } @@ -683,7 +757,7 @@ func (r *ImageRef) GetOrientation() int { // SetOrientation sets the orientation in the EXIF header of the associated image. func (r *ImageRef) SetOrientation(orientation int) error { - out, err := vipsCopyImage(r.image) + out, err := vipsGenCopy(r.image, nil) if err != nil { return err } @@ -696,7 +770,7 @@ func (r *ImageRef) SetOrientation(orientation int) error { // RemoveOrientation removes the EXIF orientation information of the image. func (r *ImageRef) RemoveOrientation() error { - out, err := vipsCopyImage(r.image) + out, err := vipsGenCopy(r.image, nil) if err != nil { return err } @@ -749,6 +823,7 @@ func (r *ImageRef) ColorSpace() Interpretation { // IsColorSpaceSupported returns a boolean whether the image's color space is supported by libvips. func (r *ImageRef) IsColorSpaceSupported() bool { + defer runtime.KeepAlive(r) return vipsIsColorSpaceSupported(r.image) } @@ -761,6 +836,7 @@ func (r *ImageRef) Pages() int { return 1 } + defer runtime.KeepAlive(r) return vipsGetImageNPages(r.image) } @@ -772,7 +848,7 @@ func (r *ImageRef) GetPages() int { // SetPages sets the number of pages in the Image // For animated images this corresponds to the number of frames func (r *ImageRef) SetPages(pages int) error { - out, err := vipsCopyImage(r.image) + out, err := vipsGenCopy(r.image, nil) if err != nil { return err } @@ -785,19 +861,21 @@ func (r *ImageRef) SetPages(pages int) error { // PageHeight return the height of a single page func (r *ImageRef) PageHeight() int { + defer runtime.KeepAlive(r) return vipsGetPageHeight(r.image) } // GetPageHeight return the height of a single page // Deprecated use PageHeight() instead func (r *ImageRef) GetPageHeight() int { + defer runtime.KeepAlive(r) return vipsGetPageHeight(r.image) } // SetPageHeight set the height of a page // For animated images this is used when "unrolling" back to frames func (r *ImageRef) SetPageHeight(height int) error { - out, err := vipsCopyImage(r.image) + out, err := vipsGenCopy(r.image, nil) if err != nil { return err } @@ -810,6 +888,7 @@ func (r *ImageRef) SetPageHeight(height int) error { // PageDelay get the page delay array for animation func (r *ImageRef) PageDelay() ([]int, error) { + defer runtime.KeepAlive(r) n := vipsGetImageNPages(r.image) if n <= 1 { // should not call if not multi page @@ -820,6 +899,7 @@ func (r *ImageRef) PageDelay() ([]int, error) { // SetPageDelay set the page delay array for animation func (r *ImageRef) SetPageDelay(delay []int) error { + defer runtime.KeepAlive(r) var data []C.int for _, d := range delay { data = append(data, C.int(d)) @@ -827,6 +907,31 @@ func (r *ImageRef) SetPageDelay(delay []int) error { return vipsImageSetDelay(r.image, data) } +// Loop returns the loop count for animated images. +// A value of 0 means infinite looping. +func (r *ImageRef) Loop() int { + defer runtime.KeepAlive(r) + return vipsImageGetLoop(r.image) +} + +// SetLoop sets the loop count for animated images. +// A value of 0 means infinite looping. +func (r *ImageRef) SetLoop(loop int) error { + defer runtime.KeepAlive(r) + vipsImageSetLoop(r.image, loop) + return nil +} + +// Background get the background of image. +func (r *ImageRef) Background() ([]float64, error) { + defer runtime.KeepAlive(r) + out, err := vipsImageGetBackground(r.image) + if err != nil { + return nil, err + } + return out, nil +} + // Export creates a byte array of the image for use. // The function returns a byte array that can be written to a file e.g. via os.WriteFile(). // N.B. govips does not currently have built-in support for directly exporting to a file. @@ -1060,6 +1165,21 @@ func (r *ImageRef) ExportJxl(params *JxlExportParams) ([]byte, *ImageMetadata, e return buf, r.newMetadata(ImageTypeJXL), nil } +// ExportMagick exports the image as Format set in param to a buffer. +func (r *ImageRef) ExportMagick(params *MagickExportParams) ([]byte, *ImageMetadata, error) { + if params == nil { + params = NewMagickExportParams() + params.Format = "JPG" + } + + buf, err := vipsSaveMagickToBuffer(r.image, *params) + if err != nil { + return nil, nil, err + } + + return buf, r.newMetadata(ImageTypeMagick), nil +} + // CompositeMulti composites the given overlay image on top of the associated image with provided blending mode. func (r *ImageRef) CompositeMulti(ins []*ImageComposite) error { out, err := vipsComposite(toVipsCompositeStructs(r, ins)) @@ -1072,7 +1192,7 @@ func (r *ImageRef) CompositeMulti(ins []*ImageComposite) error { // Composite composites the given overlay image on top of the associated image with provided blending mode. func (r *ImageRef) Composite(overlay *ImageRef, mode BlendMode, x, y int) error { - out, err := vipsComposite2(r.image, overlay.image, mode, x, y) + out, err := vipsGenComposite2(r.image, overlay.image, mode, &Composite2Options{X: &x, Y: &y}) if err != nil { return err } @@ -1082,7 +1202,11 @@ func (r *ImageRef) Composite(overlay *ImageRef, mode BlendMode, x, y int) error // Insert draws the image on top of the associated image at the given coordinates. func (r *ImageRef) Insert(sub *ImageRef, x, y int, expand bool, background *ColorRGBA) error { - out, err := vipsInsert(r.image, sub.image, x, y, expand, background) + insertOpts := &InsertOptions{Expand: &expand} + if background != nil { + insertOpts.Background = []float64{float64(background.R), float64(background.G), float64(background.B), float64(background.A)} + } + out, err := vipsGenInsert(r.image, sub.image, x, y, insertOpts) if err != nil { return err } @@ -1107,7 +1231,7 @@ func (r *ImageRef) ArrayJoin(images []*ImageRef, across int) error { for i := range inputs { inputs[i] = allImages[i].image } - out, err := vipsArrayJoin(inputs, across) + out, err := vipsGenArrayjoin(inputs, &ArrayjoinOptions{Across: &across}) if err != nil { return err } @@ -1117,7 +1241,7 @@ func (r *ImageRef) ArrayJoin(images []*ImageRef, across int) error { // Mapim resamples an image using index to look up pixels func (r *ImageRef) Mapim(index *ImageRef) error { - out, err := vipsMapim(r.image, index.image) + out, err := vipsGenMapim(r.image, index.image, nil) if err != nil { return err } @@ -1127,7 +1251,7 @@ func (r *ImageRef) Mapim(index *ImageRef) error { // Maplut maps an image through another image acting as a LUT (Look Up Table) func (r *ImageRef) Maplut(lut *ImageRef) error { - out, err := vipsMaplut(r.image, lut.image) + out, err := vipsGenMaplut(r.image, lut.image, nil) if err != nil { return err } @@ -1137,7 +1261,7 @@ func (r *ImageRef) Maplut(lut *ImageRef) error { // ExtractBand extracts one or more bands out of the image (replacing the associated ImageRef) func (r *ImageRef) ExtractBand(band int, num int) error { - out, err := vipsExtractBand(r.image, band, num) + out, err := vipsGenExtractBand(r.image, band, &ExtractBandOptions{N: &num}) if err != nil { return err } @@ -1147,7 +1271,8 @@ func (r *ImageRef) ExtractBand(band int, num int) error { // ExtractBandToImage extracts one or more bands out of the image to a new image func (r *ImageRef) ExtractBandToImage(band int, num int) (*ImageRef, error) { - out, err := vipsExtractBand(r.image, band, num) + defer runtime.KeepAlive(r) + out, err := vipsGenExtractBand(r.image, band, &ExtractBandOptions{N: &num}) if err != nil { return nil, err } @@ -1161,7 +1286,7 @@ func (r *ImageRef) BandJoin(images ...*ImageRef) error { vipsImages = append(vipsImages, vipsImage.image) } - out, err := vipsBandJoin(vipsImages) + out, err := vipsGenBandjoin(vipsImages) if err != nil { return err } @@ -1171,9 +1296,11 @@ func (r *ImageRef) BandJoin(images ...*ImageRef) error { // BandSplit split an n-band image into n separate images.. func (r *ImageRef) BandSplit() ([]*ImageRef, error) { + defer runtime.KeepAlive(r) var out []*ImageRef + n := 1 for i := 0; i < r.Bands(); i++ { - img, err := vipsExtractBand(r.image, i, 1) + img, err := vipsGenExtractBand(r.image, i, &ExtractBandOptions{N: &n}) if err != nil { return out, err } @@ -1184,7 +1311,10 @@ func (r *ImageRef) BandSplit() ([]*ImageRef, error) { // BandJoinConst appends a set of constant bands to an image. func (r *ImageRef) BandJoinConst(constants []float64) error { - out, err := vipsBandJoinConst(r.image, constants) + if len(constants) == 0 { + return errors.New("BandJoinConst: empty constants slice") + } + out, err := vipsGenBandjoinConst(r.image, constants) if err != nil { return err } @@ -1215,7 +1345,7 @@ func (r *ImageRef) PremultiplyAlpha() error { band := r.BandFormat() - out, err := vipsPremultiplyAlpha(r.image) + out, err := vipsGenPremultiply(r.image, nil) if err != nil { return err } @@ -1233,13 +1363,13 @@ func (r *ImageRef) UnpremultiplyAlpha() error { return nil } - unpremultiplied, err := vipsUnpremultiplyAlpha(r.image) + unpremultiplied, err := vipsGenUnpremultiply(r.image, nil) if err != nil { return err } defer clearImage(unpremultiplied) - out, err := vipsCast(unpremultiplied, r.preMultiplication.bandFormat) + out, err := vipsGenCast(unpremultiplied, r.preMultiplication.bandFormat, nil) if err != nil { return err } @@ -1251,7 +1381,7 @@ func (r *ImageRef) UnpremultiplyAlpha() error { // Cast converts the image to a target band format func (r *ImageRef) Cast(format BandFormat) error { - out, err := vipsCast(r.image, format) + out, err := vipsGenCast(r.image, format, nil) if err != nil { return err } @@ -1261,7 +1391,7 @@ func (r *ImageRef) Cast(format BandFormat) error { // Add calculates a sum of the image + addend and stores it back in the image func (r *ImageRef) Add(addend *ImageRef) error { - out, err := vipsAdd(r.image, addend.image) + out, err := vipsGenAdd(r.image, addend.image) if err != nil { return err } @@ -1271,7 +1401,7 @@ func (r *ImageRef) Add(addend *ImageRef) error { // Multiply calculates the product of the image * multiplier and stores it back in the image func (r *ImageRef) Multiply(multiplier *ImageRef) error { - out, err := vipsMultiply(r.image, multiplier.image) + out, err := vipsGenMultiply(r.image, multiplier.image) if err != nil { return err } @@ -1281,7 +1411,7 @@ func (r *ImageRef) Multiply(multiplier *ImageRef) error { // Divide calculates the product of the image / denominator and stores it back in the image func (r *ImageRef) Divide(denominator *ImageRef) error { - out, err := vipsDivide(r.image, denominator.image) + out, err := vipsGenDivide(r.image, denominator.image) if err != nil { return err } @@ -1296,7 +1426,7 @@ func (r *ImageRef) Linear(a, b []float64) error { return errors.New("a and b must be of same length") } - out, err := vipsLinear(r.image, a, b, len(a)) + out, err := vipsGenLinear(r.image, a, b, nil) if err != nil { return err } @@ -1307,7 +1437,7 @@ func (r *ImageRef) Linear(a, b []float64) error { // Linear1 runs Linear() with a single constant. // See https://libvips.github.io/libvips/API/current/libvips-arithmetic.html#vips-linear1 func (r *ImageRef) Linear1(a, b float64) error { - out, err := vipsLinear1(r.image, a, b) + out, err := vipsGenLinear(r.image, []float64{a}, []float64{b}, nil) if err != nil { return err } @@ -1318,7 +1448,7 @@ func (r *ImageRef) Linear1(a, b float64) error { // Adjusts the image's gamma value. // See https://www.libvips.org/API/current/libvips-conversion.html#vips-gamma func (r *ImageRef) Gamma(gamma float64) error { - out, err := vipsGamma(r.image, gamma) + out, err := vipsGenGamma(r.image, &GammaOptions{Exponent: &gamma}) if err != nil { return err } @@ -1352,7 +1482,7 @@ func GetRotationAngleFromExif(orientation int) (Angle, bool) { // Thus, calling AutoRotate for HEIF images is not needed. // todo: use https://www.libvips.org/API/current/libvips-conversion.html#vips-autorot-remove-angle func (r *ImageRef) AutoRotate() error { - out, err := vipsAutoRotate(r.image) + out, _, _, err := vipsGenAutorot(r.image) if err != nil { return err } @@ -1381,6 +1511,7 @@ func (r *ImageRef) ExtractArea(left, top, width, height int) error { // GetICCProfile retrieves the ICC profile data (if any) from the image. func (r *ImageRef) GetICCProfile() []byte { + defer runtime.KeepAlive(r) bytes, _ := vipsGetICCProfile(r.image) return bytes } @@ -1388,7 +1519,7 @@ func (r *ImageRef) GetICCProfile() []byte { // RemoveICCProfile removes the ICC Profile information from the image. // Typically, browsers and other software assume images without profile to be in the sRGB color space. func (r *ImageRef) RemoveICCProfile() error { - out, err := vipsCopyImage(r.image) + out, err := vipsGenCopy(r.image, nil) if err != nil { return err } @@ -1469,7 +1600,7 @@ func (r *ImageRef) OptimizeICCProfile() error { // N.B. this function won't remove the ICC profile, orientation and pages metadata // because govips needs it to correctly display the image. func (r *ImageRef) RemoveMetadata(keep ...string) error { - out, err := vipsCopyImage(r.image) + out, err := vipsGenCopy(r.image, nil) if err != nil { return err } @@ -1486,42 +1617,52 @@ func (r *ImageRef) ImageFields() []string { } func (r *ImageRef) GetFields() []string { + defer runtime.KeepAlive(r) return vipsImageGetFields(r.image) } func (r *ImageRef) SetBlob(name string, data []byte) { + defer runtime.KeepAlive(r) vipsImageSetBlob(r.image, name, data) } func (r *ImageRef) GetBlob(name string) []byte { + defer runtime.KeepAlive(r) return vipsImageGetBlob(r.image, name) } func (r *ImageRef) SetDouble(name string, f float64) { + defer runtime.KeepAlive(r) vipsImageSetDouble(r.image, name, f) } func (r *ImageRef) GetDouble(name string) float64 { + defer runtime.KeepAlive(r) return vipsImageGetDouble(r.image, name) } func (r *ImageRef) SetInt(name string, i int) { + defer runtime.KeepAlive(r) vipsImageSetInt(r.image, name, i) } func (r *ImageRef) GetInt(name string) int { + defer runtime.KeepAlive(r) return vipsImageGetInt(r.image, name) } func (r *ImageRef) SetString(name string, str string) { + defer runtime.KeepAlive(r) vipsImageSetString(r.image, name, str) } func (r *ImageRef) GetString(name string) string { + defer runtime.KeepAlive(r) return vipsImageGetString(r.image, name) } func (r *ImageRef) GetAsString(name string) string { + defer runtime.KeepAlive(r) return vipsImageGetAsString(r.image, name) } @@ -1536,6 +1677,7 @@ func (r *ImageRef) HasExif() bool { } func (r *ImageRef) GetExif() map[string]string { + defer runtime.KeepAlive(r) return vipsImageGetExifData(r.image) } @@ -1551,7 +1693,11 @@ func (r *ImageRef) ToColorSpace(interpretation Interpretation) error { // Flatten removes the alpha channel from the image and replaces it with the background color func (r *ImageRef) Flatten(backgroundColor *Color) error { - out, err := vipsFlatten(r.image, backgroundColor) + opts := &FlattenOptions{} + if backgroundColor != nil { + opts.Background = []float64{float64(backgroundColor.R), float64(backgroundColor.G), float64(backgroundColor.B)} + } + out, err := vipsGenFlatten(r.image, opts) if err != nil { return err } @@ -1569,7 +1715,7 @@ func (r *ImageRef) GaussianBlur(sigmas ...float64) error { if len(sigmas) >= 2 { minAmpl = sigmas[1] } - out, err := vipsGaussianBlur(r.image, sigma, minAmpl) + out, err := vipsGenGaussblur(r.image, sigma, &GaussblurOptions{MinAmpl: &minAmpl}) if err != nil { return err } @@ -1582,7 +1728,7 @@ func (r *ImageRef) GaussianBlur(sigmas ...float64) error { // x1: flat/jaggy threshold // m2: slope for jaggy areas func (r *ImageRef) Sharpen(sigma float64, x1 float64, m2 float64) error { - out, err := vipsSharpen(r.image, sigma, x1, m2) + out, err := vipsGenSharpen(r.image, &SharpenOptions{Sigma: &sigma, X1: &x1, M2: &m2}) if err != nil { return err } @@ -1592,7 +1738,7 @@ func (r *ImageRef) Sharpen(sigma float64, x1 float64, m2 float64) error { // Apply Sobel edge detector to the image. func (r *ImageRef) Sobel() error { - out, err := vipsSobel(r.image) + out, err := vipsGenSobel(r.image) if err != nil { return err } @@ -1676,7 +1822,7 @@ func (r *ImageRef) ModulateHSV(brightness, saturation float64, hue int) error { // Invert inverts the image func (r *ImageRef) Invert() error { - out, err := vipsInvert(r.image) + out, err := vipsGenInvert(r.image) if err != nil { return err } @@ -1686,7 +1832,8 @@ func (r *ImageRef) Invert() error { // Average finds the average value in an image func (r *ImageRef) Average() (float64, error) { - out, err := vipsAverage(r.image) + defer runtime.KeepAlive(r) + out, err := vipsGenAvg(r.image) if err != nil { return 0, err } @@ -1696,12 +1843,14 @@ func (r *ImageRef) Average() (float64, error) { // FindTrim returns the bounding box of the non-border part of the image // Returned values are left, top, width, height func (r *ImageRef) FindTrim(threshold float64, backgroundColor *Color) (int, int, int, int, error) { + defer runtime.KeepAlive(r) return vipsFindTrim(r.image, threshold, backgroundColor) } // GetPoint reads a single pixel on an image. // The pixel values are returned in a slice of length n. func (r *ImageRef) GetPoint(x int, y int) ([]float64, error) { + defer runtime.KeepAlive(r) n := 3 if vipsHasAlpha(r.image) { n = 4 @@ -1719,7 +1868,7 @@ func (r *ImageRef) GetPoint(x int, y int) ([]float64, error) { // // If there is more than one maxima or minima, one of them will be chosen at random. func (r *ImageRef) Stats() error { - out, err := vipsStats(r.image) + out, err := vipsGenStats(r.image) if err != nil { return err } @@ -1731,7 +1880,7 @@ func (r *ImageRef) Stats() error { // Find the histogram for all bands (producing a one-band histogram). // char and uchar images are cast to uchar before histogramming, all other image types are cast to ushort. func (r *ImageRef) HistogramFind() error { - out, err := vipsHistFind(r.image) + out, err := vipsGenHistFind(r.image, nil) if err != nil { return err } @@ -1741,7 +1890,7 @@ func (r *ImageRef) HistogramFind() error { // HistogramCumulative form cumulative histogram. func (r *ImageRef) HistogramCumulative() error { - out, err := vipsHistCum(r.image) + out, err := vipsGenHistCum(r.image) if err != nil { return err } @@ -1753,7 +1902,7 @@ func (r *ImageRef) HistogramCumulative() error { // The maximum of each band becomes equal to the maximum index, so for example the max for a uchar // image becomes 255. Normalise each band separately. func (r *ImageRef) HistogramNormalise() error { - out, err := vipsHistNorm(r.image) + out, err := vipsGenHistNorm(r.image) if err != nil { return err } @@ -1765,11 +1914,13 @@ func (r *ImageRef) HistogramNormalise() error { // `-sum(p * log2(p))` // where p is histogram-value / sum-of-histogram-values. func (r *ImageRef) HistogramEntropy() (float64, error) { - return vipsHistEntropy(r.image) + defer runtime.KeepAlive(r) + return vipsGenHistEntropy(r.image) } // DrawRect draws an (optionally filled) rectangle with a single colour func (r *ImageRef) DrawRect(ink ColorRGBA, left int, top int, width int, height int, fill bool) error { + defer runtime.KeepAlive(r) err := vipsDrawRect(r.image, ink, left, top, width, height, fill) if err != nil { return err @@ -1777,11 +1928,50 @@ func (r *ImageRef) DrawRect(ink ColorRGBA, left int, top int, width int, height return nil } +// Subtract calculate subtract operation between two images. +func (r *ImageRef) Subtract(in2 *ImageRef) error { + out, err := vipsGenSubtract(r.image, in2.image) + if err != nil { + return err + } + + r.setImage(out) + return nil +} + +// Abs calculate abs operation. +func (r *ImageRef) Abs() error { + out, err := vipsGenAbs(r.image) + if err != nil { + return err + } + + r.setImage(out) + return nil +} + +// Project calculate project operation. +func (r *ImageRef) Project() (*ImageRef, *ImageRef, error) { + defer runtime.KeepAlive(r) + col, row, err := vipsGenProject(r.image) + if err != nil { + return nil, nil, err + } + + return newImageRef(col, r.format, r.originalFormat, nil), newImageRef(row, r.format, r.originalFormat, nil), nil +} + +// Min finds the minimum value in an image. +func (r *ImageRef) Min() (float64, int, int, error) { + defer runtime.KeepAlive(r) + return vipsMin(r.image) +} + // Rank does rank filtering on an image. A window of size width by height is passed over the image. // At each position, the pixels inside the window are sorted into ascending order and the pixel at position // index is output. index numbers from 0. func (r *ImageRef) Rank(width int, height int, index int) error { - out, err := vipsRank(r.image, width, height, index) + out, err := vipsGenRank(r.image, width, height, index) if err != nil { return err } @@ -1815,7 +2005,7 @@ func (r *ImageRef) ResizeWithVScale(hScale, vScale float64, kernel Kernel) error if vScale != -1 { scale = vScale } - newPageHeight := int(float64(pageHeight)*scale + 0.5) + newPageHeight := int(math.Round(float64(pageHeight) * scale)) if err := r.SetPageHeight(newPageHeight); err != nil { return err } @@ -1909,7 +2099,7 @@ func (r *ImageRef) EmbedBackgroundRGBA(left, top, width, height int, backgroundC // Zoom zooms the image by repeating pixels (fast nearest-neighbour) func (r *ImageRef) Zoom(xFactor int, yFactor int) error { - out, err := vipsZoom(r.image, xFactor, yFactor) + out, err := vipsGenZoom(r.image, xFactor, yFactor) if err != nil { return err } @@ -1917,6 +2107,16 @@ func (r *ImageRef) Zoom(xFactor int, yFactor int) error { return nil } +func (r *ImageRef) Gravity(gravity Gravity, width int, height int) error { + out, err := vipsGenGravity(r.image, gravity, width, height, nil) + if err != nil { + return err + } + + r.setImage(out) + return nil +} + // Flip flips the image either horizontally or vertically based on the parameter func (r *ImageRef) Flip(direction Direction) error { out, err := vipsFlip(r.image, direction) @@ -1945,7 +2145,7 @@ func (r *ImageRef) Recomb(matrix [][]float64) error { } // Flatten the matrix - var matrixValues []float64 + matrixValues := make([]float64, 0, numBands*numBands) for _, row := range matrix { for _, value := range row { matrixValues = append(matrixValues, value) @@ -1958,6 +2158,7 @@ func (r *ImageRef) Recomb(matrix [][]float64) error { // Create a VipsImage from the matrix in memory matrixImage := C.vips_image_new_from_memory(matrixPtr, matrixSize, C.int(numBands), C.int(numBands), 1, C.VIPS_FORMAT_DOUBLE) + defer clearImage(matrixImage) // Check for any Vips errors errMsg := C.GoString(C.vips_error_buffer()) @@ -1967,7 +2168,8 @@ func (r *ImageRef) Recomb(matrix [][]float64) error { } // Recombine the image using the matrix - out, err := vipsRecomb(r.image, matrixImage) + out, err := vipsGenRecomb(r.image, matrixImage) + runtime.KeepAlive(matrixValues) if err != nil { return err } @@ -1999,7 +2201,7 @@ func (r *ImageRef) Rotate(angle Angle) error { } - out, err := vipsRotate(r.image, angle) + out, err := vipsGenRot(r.image, angle) if err != nil { return err } @@ -2029,7 +2231,7 @@ func (r *ImageRef) Similarity(scale float64, angle float64, backgroundColor *Col // Grid tiles the image pages into a matrix across*down func (r *ImageRef) Grid(tileHeight, across, down int) error { - out, err := vipsGrid(r.image, tileHeight, across, down) + out, err := vipsGenGrid(r.image, tileHeight, across, down) if err != nil { return err } @@ -2069,7 +2271,7 @@ func (r *ImageRef) Label(labelParams *LabelParams) error { // Replicate repeats an image many times across and down func (r *ImageRef) Replicate(across int, down int) error { - out, err := vipsReplicate(r.image, across, down) + out, err := vipsGenReplicate(r.image, across, down) if err != nil { return err } @@ -2079,6 +2281,7 @@ func (r *ImageRef) Replicate(across int, down int) error { // ToBytes writes the image to memory in VIPs format and returns the raw bytes, useful for storage. func (r *ImageRef) ToBytes() ([]byte, error) { + defer runtime.KeepAlive(r) var cSize C.size_t cData := C.vips_image_write_to_memory(r.image, &cSize) if cData == nil { @@ -2092,7 +2295,9 @@ func (r *ImageRef) ToBytes() ([]byte, error) { func (r *ImageRef) determineInputICCProfile() (inputProfile string) { if r.Interpretation() == InterpretationCMYK { - inputProfile = "cmyk" + if !r.HasICCProfile() { + inputProfile = "cmyk" + } } return } @@ -2113,6 +2318,139 @@ func (r *ImageRef) ToImage(params *ExportParams) (image.Image, error) { return img, nil } +// ToGoImage converts a vips image directly to a Go image.Image without encoding. +// This is significantly faster than ToImage() which round-trips through JPEG/PNG. +// The resulting image will be in sRGB color space with 8-bit depth. +func (r *ImageRef) ToGoImage() (image.Image, error) { + defer runtime.KeepAlive(r) + + // Work on a copy to avoid mutating the receiver + tmp, err := vipsGenCopy(r.image, nil) + if err != nil { + return nil, err + } + defer clearImage(tmp) + + // Convert to sRGB if needed (keep B_W for grayscale) + interp := Interpretation(int(tmp.Type)) + if interp != InterpretationSRGB && interp != InterpretationBW { + out, err := vipsToColorSpace(tmp, InterpretationSRGB) + if err != nil { + return nil, err + } + clearImage(tmp) + tmp = out + } + + // Cast to uchar if needed + if BandFormat(int(tmp.BandFmt)) != BandFormatUchar { + out, err := vipsGenCast(tmp, BandFormatUchar, nil) + if err != nil { + return nil, err + } + clearImage(tmp) + tmp = out + } + + // Extract raw pixel data + var cSize C.size_t + cData := C.vips_image_write_to_memory(tmp, &cSize) + if cData == nil { + return nil, errors.New("failed to write image to memory") + } + defer C.free(cData) + + width := int(tmp.Xsize) + height := int(tmp.Ysize) + bands := int(tmp.Bands) + pixels := C.GoBytes(unsafe.Pointer(cData), C.int(cSize)) + + switch bands { + case 1: + img := image.NewGray(image.Rect(0, 0, width, height)) + copy(img.Pix, pixels) + return img, nil + case 2: + // Grayscale + alpha + img := image.NewNRGBA(image.Rect(0, 0, width, height)) + srcIdx := 0 + dstIdx := 0 + for srcIdx+1 < len(pixels) { + v := pixels[srcIdx] + img.Pix[dstIdx] = v + img.Pix[dstIdx+1] = v + img.Pix[dstIdx+2] = v + img.Pix[dstIdx+3] = pixels[srcIdx+1] + srcIdx += 2 + dstIdx += 4 + } + return img, nil + case 3: + // RGB, add opaque alpha + img := image.NewNRGBA(image.Rect(0, 0, width, height)) + srcIdx := 0 + dstIdx := 0 + for srcIdx+2 < len(pixels) { + img.Pix[dstIdx] = pixels[srcIdx] + img.Pix[dstIdx+1] = pixels[srcIdx+1] + img.Pix[dstIdx+2] = pixels[srcIdx+2] + img.Pix[dstIdx+3] = 255 + srcIdx += 3 + dstIdx += 4 + } + return img, nil + case 4: + img := image.NewNRGBA(image.Rect(0, 0, width, height)) + copy(img.Pix, pixels) + return img, nil + default: + return nil, fmt.Errorf("unsupported number of bands: %d", bands) + } +} + +// NewImageFromGoImage creates a new ImageRef from a Go image.Image. +// The image is normalized to NRGBA (non-premultiplied RGBA, 8-bit) and +// imported into libvips in sRGB color space. +func NewImageFromGoImage(img image.Image) (*ImageRef, error) { + startupIfNeeded() + + bounds := img.Bounds() + width := bounds.Dx() + height := bounds.Dy() + + if width == 0 || height == 0 { + return nil, errors.New("image has zero dimensions") + } + + // Normalize to NRGBA + var nrgba *image.NRGBA + if n, ok := img.(*image.NRGBA); ok && n.Rect.Min.X == 0 && n.Rect.Min.Y == 0 && n.Stride == width*4 { + nrgba = n + } else { + nrgba = image.NewNRGBA(image.Rect(0, 0, width, height)) + draw.Draw(nrgba, nrgba.Bounds(), img, bounds.Min, draw.Src) + } + + // Create vips image from pixel data (copies data, safe for Go GC) + vipsImage := C.create_image_from_memory_copy( + unsafe.Pointer(&nrgba.Pix[0]), + C.size_t(len(nrgba.Pix)), + C.int(width), + C.int(height), + 4, + C.VIPS_FORMAT_UCHAR, + ) + runtime.KeepAlive(nrgba) + if vipsImage == nil { + return nil, errors.New("failed to create vips image from memory") + } + + // Set interpretation to sRGB + vipsImage.Type = C.VIPS_INTERPRETATION_sRGB + + return newImageRef(vipsImage, ImageTypeUnknown, ImageTypeUnknown, nil), nil +} + // setImage resets the image for this image and frees the previous one func (r *ImageRef) setImage(image *C.VipsImage) { r.lock.Lock() diff --git a/vendor/github.com/davidbyttow/govips/v2/vips/image.h b/vendor/github.com/davidbyttow/govips/v2/vips/image.h index 0a116f0082..e8c8aa5be0 100644 --- a/vendor/github.com/davidbyttow/govips/v2/vips/image.h +++ b/vendor/github.com/davidbyttow/govips/v2/vips/image.h @@ -6,3 +6,7 @@ int has_alpha_channel(VipsImage *image); void clear_image(VipsImage **image); + +VipsImage *create_image_from_memory_copy(const void *data, size_t size, + int width, int height, int bands, + VipsBandFormat format); diff --git a/vendor/github.com/davidbyttow/govips/v2/vips/interpolate.go b/vendor/github.com/davidbyttow/govips/v2/vips/interpolate.go new file mode 100644 index 0000000000..4854f2346a --- /dev/null +++ b/vendor/github.com/davidbyttow/govips/v2/vips/interpolate.go @@ -0,0 +1,20 @@ +package vips + +// #include +import "C" + +import "unsafe" + +// NewInterpolate creates a VipsInterpolate from a name string. +// Common names: "nearest", "bilinear", "bicubic", "nohalo", "vsqbs", "lbb". +// The caller should call g_object_unref on the result when done, or pass it +// to a generated operation (which does not take ownership). +func NewInterpolate(name string) (*C.VipsInterpolate, error) { + cName := C.CString(name) + defer C.free(unsafe.Pointer(cName)) + interp := C.vips_interpolate_new(cName) + if interp == nil { + return nil, handleVipsError() + } + return interp, nil +} diff --git a/vendor/github.com/davidbyttow/govips/v2/vips/label.c b/vendor/github.com/davidbyttow/govips/v2/vips/label.c deleted file mode 100644 index 01de813438..0000000000 --- a/vendor/github.com/davidbyttow/govips/v2/vips/label.c +++ /dev/null @@ -1,37 +0,0 @@ -#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; -} diff --git a/vendor/github.com/davidbyttow/govips/v2/vips/label.go b/vendor/github.com/davidbyttow/govips/v2/vips/label.go deleted file mode 100644 index 84320b6340..0000000000 --- a/vendor/github.com/davidbyttow/govips/v2/vips/label.go +++ /dev/null @@ -1,84 +0,0 @@ -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 -} diff --git a/vendor/github.com/davidbyttow/govips/v2/vips/label.h b/vendor/github.com/davidbyttow/govips/v2/vips/label.h deleted file mode 100644 index 332a5da30f..0000000000 --- a/vendor/github.com/davidbyttow/govips/v2/vips/label.h +++ /dev/null @@ -1,21 +0,0 @@ -#include -#include - -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); diff --git a/vendor/github.com/davidbyttow/govips/v2/vips/lang.go b/vendor/github.com/davidbyttow/govips/v2/vips/lang.go index 6889b798bf..56ce86a3b0 100644 --- a/vendor/github.com/davidbyttow/govips/v2/vips/lang.go +++ b/vendor/github.com/davidbyttow/govips/v2/vips/lang.go @@ -47,3 +47,16 @@ func fromCArrayInt(out *C.int, n int) []int { } return result } + +func fromCArrayDouble(out *C.double, n int) []float64 { + if out == nil || n <= 0 { + return nil + } + + data := make([]float64, n) + for i := 0; i < n; i++ { + data[i] = float64(*(*C.double)(unsafe.Pointer(uintptr(unsafe.Pointer(out)) + uintptr(i)*unsafe.Sizeof(C.double(0))))) + } + + return data +} diff --git a/vendor/github.com/davidbyttow/govips/v2/vips/lang.h b/vendor/github.com/davidbyttow/govips/v2/vips/lang.h index 27c81384b6..089d58e795 100644 --- a/vendor/github.com/davidbyttow/govips/v2/vips/lang.h +++ b/vendor/github.com/davidbyttow/govips/v2/vips/lang.h @@ -1,4 +1,2 @@ #include #include - -#define INT_TO_GBOOLEAN(bool) (bool > 0 ? TRUE : FALSE) diff --git a/vendor/github.com/davidbyttow/govips/v2/vips/morphology.c b/vendor/github.com/davidbyttow/govips/v2/vips/morphology.c deleted file mode 100644 index b57fdd9192..0000000000 --- a/vendor/github.com/davidbyttow/govips/v2/vips/morphology.c +++ /dev/null @@ -1,6 +0,0 @@ -#include "morphology.h" - -int rank(VipsImage *in, VipsImage **out, int width, int height, int index) { - return vips_rank(in, out, width, height, index, NULL); -} - diff --git a/vendor/github.com/davidbyttow/govips/v2/vips/morphology.go b/vendor/github.com/davidbyttow/govips/v2/vips/morphology.go deleted file mode 100644 index 75e8668b9d..0000000000 --- a/vendor/github.com/davidbyttow/govips/v2/vips/morphology.go +++ /dev/null @@ -1,17 +0,0 @@ -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 -} diff --git a/vendor/github.com/davidbyttow/govips/v2/vips/morphology.h b/vendor/github.com/davidbyttow/govips/v2/vips/morphology.h deleted file mode 100644 index fe8e9e1a04..0000000000 --- a/vendor/github.com/davidbyttow/govips/v2/vips/morphology.h +++ /dev/null @@ -1,6 +0,0 @@ -// https://libvips.github.io/libvips/API/current/libvips-morphology.html - -#include -#include - -int rank(VipsImage *in, VipsImage **out, int width, int height, int index); diff --git a/vendor/github.com/davidbyttow/govips/v2/vips/operations.c b/vendor/github.com/davidbyttow/govips/v2/vips/operations.c new file mode 100644 index 0000000000..6ae1002573 --- /dev/null +++ b/vendor/github.com/davidbyttow/govips/v2/vips/operations.c @@ -0,0 +1,503 @@ +// operations.c - Hand-written C bridge functions for libvips operations + +#include "lang.h" +#include "operations.h" + +#include + +static int is_16bit(VipsInterpretation interpretation); + +// Arithmetic + +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 minOp(VipsImage *in, double *out, int *x, int *y, int size) { + return vips_min(in, out, "x", x, "y", y, "size", size, NULL); +} + +// Color + +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); +} + +// Conversion + +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 **embedded_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], &embedded_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(embedded_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 **embedded_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], &embedded_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(embedded_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 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 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 **cropped_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], &cropped_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(cropped_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; +} + +static int is_16bit(VipsInterpretation interpretation) { + return interpretation == VIPS_INTERPRETATION_RGB16 || + interpretation == VIPS_INTERPRETATION_GREY16; +} + +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 join(VipsImage *in1, VipsImage *in2, VipsImage **out, int direction) { + return vips_join(in1, in2, out, direction, NULL); +} + +int add_alpha(VipsImage *in, VipsImage **out) { + return vips_addalpha(in, out, NULL); +} + +// Create + +// https://libvips.github.io/libvips/API/current/libvips-create.html#vips-text +int text(VipsImage **out, TextOptions *o) { + return vips_text(out, o->Text, "font", o->Font, "width", o->Width, "height", o->Height, "align", o->Align, + "dpi", o->DPI, "rgba", o->RGBA, "justify", o->Justify, "spacing", o->Spacing, "wrap", o->Wrap, NULL); +} + +// Draw + +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); + } +} + +// Header + +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_background(VipsImage *in, double **out, int *n) { + return vips_image_get_array_double(in, "background", out, n); +} + +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); +} + +int get_image_loop(VipsImage *in) { + int loop = 0; + if (vips_image_get_typeof(in, "loop") != 0) { + vips_image_get_int(in, "loop", &loop); + } + return loop; +} + +void set_image_loop(VipsImage *in, int loop) { + vips_image_set_int(in, "loop", loop); +} + +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; +} + +// Label + +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; +} + +// Resample + +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); +} diff --git a/vendor/github.com/davidbyttow/govips/v2/vips/operations.go b/vendor/github.com/davidbyttow/govips/v2/vips/operations.go new file mode 100644 index 0000000000..0e60206f8d --- /dev/null +++ b/vendor/github.com/davidbyttow/govips/v2/vips/operations.go @@ -0,0 +1,1062 @@ +package vips + +// #cgo CFLAGS: -std=c99 +// #include "operations.h" +import "C" +import ( + "errors" + "os" + "runtime" + "strings" + "unsafe" +) + +// Arithmetic + +// 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-min +func vipsMin(in *C.VipsImage) (float64, int, int, error) { + incOpCounter("min") + var out C.double + var x, y C.int + + if err := C.minOp(in, &out, &x, &y, C.int(1)); err != 0 { + return 0, 0, 0, handleVipsError() + } + + return float64(out), int(x), int(y), nil +} + +// Color + +// 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 +} + +// Composite + +// 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 +} + +// Conversion + +// 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 +) + +// Gravity represents VIPS_GRAVITY type +type Gravity int + +// Gravity enum +const ( + GravityCentre Gravity = C.VIPS_COMPASS_DIRECTION_CENTRE + GravityNorth Gravity = C.VIPS_COMPASS_DIRECTION_NORTH + GravityEast Gravity = C.VIPS_COMPASS_DIRECTION_EAST + GravitySouth Gravity = C.VIPS_COMPASS_DIRECTION_SOUTH + GravityWest Gravity = C.VIPS_COMPASS_DIRECTION_WEST + GravityNorthEast Gravity = C.VIPS_COMPASS_DIRECTION_NORTH_EAST + GravityNorthWest Gravity = C.VIPS_COMPASS_DIRECTION_NORTH_WEST + GravitySouthEast Gravity = C.VIPS_COMPASS_DIRECTION_SOUTH_EAST + GravitySouthWest Gravity = C.VIPS_COMPASS_DIRECTION_SOUTH_WEST +) + +// 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 +) + +// 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) { + return vipsGenFlip(in, direction) +} + +// 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) { + return vipsGenExtractArea(in, left, top, width, height) +} + +func vipsExtractAreaMultiPage(in *C.VipsImage, left, top, width, height int) (*C.VipsImage, error) { + incOpCounter("extractAreaMultiPage") + + pageHeight := vipsGetPageHeight(in) + nPages := int(in.Ysize) / pageHeight + + pages := make([]*C.VipsImage, nPages) + for i := 0; i < nPages; i++ { + page, err := vipsGenExtractArea(in, left, pageHeight*i+top, width, height) + if err != nil { + for j := 0; j < i; j++ { + clearImage(pages[j]) + } + return nil, err + } + pages[i] = page + } + + across := 1 + joined, err := vipsGenArrayjoin(pages, &ArrayjoinOptions{Across: &across}) + for _, p := range pages { + clearImage(p) + } + if err != nil { + return nil, err + } + + out, err := vipsGenCopy(joined, nil) + clearImage(joined) + if err != nil { + return nil, err + } + + vipsSetPageHeight(out, height) + 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) { + _, out, _, err := vipsGenSmartcrop(in, width, height, &SmartcropOptions{Interesting: &interesting}) + return out, err +} + +// 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-composite +func vipsComposite(ins []*C.VipsImage, modes []C.int, xs, ys []C.int) (*C.VipsImage, error) { + if len(ins) == 0 || len(modes) == 0 || len(xs) == 0 || len(ys) == 0 { + return nil, errors.New("vipsComposite: empty input slice") + } + 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-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 +} + +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 +} + +// Create + +type TextWrap int + +type TextParams struct { + Text string + Font string + Width int + Height int + Alignment Align + DPI int + RGBA bool + Justify bool + Spacing int + Wrap TextWrap +} + +type vipsTextOptions struct { + Text *C.char + Font *C.char + Width C.int + Height C.int + DPI C.int + RGBA C.gboolean + Justify C.gboolean + Spacing C.int + Alignment C.VipsAlign + Wrap C.VipsTextWrap +} + +// TextWrap enum +const ( + TextWrapWord TextWrap = C.VIPS_TEXT_WRAP_WORD + TextWrapChar TextWrap = C.VIPS_TEXT_WRAP_CHAR + TextWrapWordChar TextWrap = C.VIPS_TEXT_WRAP_WORD_CHAR + TextWrapNone TextWrap = C.VIPS_TEXT_WRAP_NONE +) + +// https://libvips.github.io/libvips/API/current/libvips-create.html#vips-text +func vipsText(params *TextParams) (*C.VipsImage, error) { + var out *C.VipsImage + + text := C.CString(params.Text) + defer freeCString(text) + + font := C.CString(params.Font) + defer freeCString(font) + + opts := vipsTextOptions{ + Text: text, + Font: font, + Width: C.int(params.Width), + Height: C.int(params.Height), + DPI: C.int(params.DPI), + Alignment: C.VipsAlign(params.Alignment), + Spacing: C.int(params.Spacing), + Wrap: C.VipsTextWrap(params.Wrap), + } + + if params.RGBA { + opts.RGBA = C.TRUE + } + + if params.Justify { + opts.Justify = C.TRUE + } + + err := C.text(&out, (*C.TextOptions)(unsafe.Pointer(&opts))) + if err != 0 { + return nil, handleImageError(out) + } + + return out, nil +} + +// Draw + +// 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 +} + +// Header + +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, + "delay", + "loop", +} + +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 +} + +func vipsImageGetLoop(in *C.VipsImage) int { + return int(C.get_image_loop(in)) +} + +func vipsImageSetLoop(in *C.VipsImage, loop int) { + C.set_image_loop(in, C.int(loop)) +} + +func vipsImageGetBackground(in *C.VipsImage) ([]float64, error) { + incOpCounter("imageGetBackground") + var out *C.double + var n C.int + defer gFreePointer(unsafe.Pointer(out)) + + if err := C.get_background(in, &out, &n); err != 0 { + return nil, handleVipsError() + } + return fromCArrayDouble(out, int(n)), 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 "" +} + +// Label + +// 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 +} + +// Resample + +// 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 { + return vipsThumbnailFromBuffer(src, 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) + return nil, ImageTypeUnknown, err + } + + imageType := vipsDetermineImageTypeFromMetaLoader(out) + return out, imageType, nil +} diff --git a/vendor/github.com/davidbyttow/govips/v2/vips/operations.h b/vendor/github.com/davidbyttow/govips/v2/vips/operations.h new file mode 100644 index 0000000000..e2fe167d9b --- /dev/null +++ b/vendor/github.com/davidbyttow/govips/v2/vips/operations.h @@ -0,0 +1,149 @@ +// operations.h - Hand-written C bridge functions for libvips operations + +#ifndef OPERATIONS_H +#define OPERATIONS_H + +#include +#include +#include + +// Arithmetic +// https://libvips.github.io/libvips/API/current/libvips-arithmetic.html + +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 minOp(VipsImage *in, double *out, int *x, int *y, int size); + +// Color +// https://libvips.github.io/libvips/API/current/libvips-colour.html + +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); + +// Conversion +// https://libvips.github.io/libvips/API/current/libvips-conversion.html + +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 crop(VipsImage *in, VipsImage **out, int left, int top, int width, + int height); +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 composite_image(VipsImage **in, VipsImage **out, int n, int *mode, int *x, + int *y); +int join(VipsImage *in1, VipsImage *in2, VipsImage **out, int direction); +int add_alpha(VipsImage *in, VipsImage **out); + +// Create +// https://libvips.github.io/libvips/API/current/libvips-create.html + +typedef struct { + const char *Text; + const char *Font; + int Width; + int Height; + int DPI; + gboolean RGBA; + gboolean Justify; + int Spacing; + VipsAlign Align; + VipsTextWrap Wrap; +} TextOptions; + +int text(VipsImage **out, TextOptions *o); + +// Draw +// https://libvips.github.io/libvips/API/current/libvips-draw.html + +int draw_rect(VipsImage *in, double r, double g, double b, double a, int left, + int top, int width, int height, int fill); + +// Header +// https://libvips.github.io/libvips/API/current/libvips-header.html + +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); +int get_image_loop(VipsImage *in); +void set_image_loop(VipsImage *in, int loop); +int get_background(VipsImage *in, double **out, 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); + +// Label + +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); + +// Resample +// https://libvips.github.io/libvips/API/current/libvips-resample.html + +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); + +#endif // OPERATIONS_H diff --git a/vendor/github.com/davidbyttow/govips/v2/vips/resample.c b/vendor/github.com/davidbyttow/govips/v2/vips/resample.c deleted file mode 100644 index aabc4102a9..0000000000 --- a/vendor/github.com/davidbyttow/govips/v2/vips/resample.c +++ /dev/null @@ -1,61 +0,0 @@ -#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); -} - diff --git a/vendor/github.com/davidbyttow/govips/v2/vips/resample.go b/vendor/github.com/davidbyttow/govips/v2/vips/resample.go deleted file mode 100644 index 9998d52327..0000000000 --- a/vendor/github.com/davidbyttow/govips/v2/vips/resample.go +++ /dev/null @@ -1,146 +0,0 @@ -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 -} diff --git a/vendor/github.com/davidbyttow/govips/v2/vips/resample.h b/vendor/github.com/davidbyttow/govips/v2/vips/resample.h deleted file mode 100644 index 9df5e132c9..0000000000 --- a/vendor/github.com/davidbyttow/govips/v2/vips/resample.h +++ /dev/null @@ -1,24 +0,0 @@ -// https://libvips.github.io/libvips/API/current/libvips-resample.html - -#include -#include - -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); diff --git a/vendor/modules.txt b/vendor/modules.txt index c59cabe4c7..e251a21961 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -358,8 +358,8 @@ github.com/cyphar/filepath-securejoin/pathrs-lite/procfs # github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc ## explicit github.com/davecgh/go-spew/spew -# github.com/davidbyttow/govips/v2 v2.16.0 -## explicit; go 1.15 +# github.com/davidbyttow/govips/v2 v2.17.0 +## explicit; go 1.23.0 github.com/davidbyttow/govips/v2/vips # github.com/deckarep/golang-set v1.8.0 ## explicit; go 1.17