Compare commits
4 Commits
event-trig
...
release/se
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2979e6ccf4 | ||
|
|
ab890d8593 | ||
|
|
ee2d9763f7 | ||
|
|
f7ea20db61 |
@@ -250,7 +250,7 @@ func traefik(subdomain, projectName string, port uint, dotnhostfolder string) (*
|
||||
}
|
||||
|
||||
return &Service{
|
||||
Image: "traefik:v3.1",
|
||||
Image: "traefik:v3.6",
|
||||
DependsOn: nil,
|
||||
EntryPoint: nil,
|
||||
Command: []string{
|
||||
|
||||
@@ -4191,32 +4191,34 @@ type Plans struct {
|
||||
// An array relationship
|
||||
Organizations []*Organizations `json:"organizations"`
|
||||
Price int64 `json:"price"`
|
||||
SLALevel SLALevelEnum `json:"slaLevel"`
|
||||
Sort int64 `json:"sort"`
|
||||
UpatedAt time.Time `json:"upatedAt"`
|
||||
}
|
||||
|
||||
// Boolean expression to filter rows from the table "plans". All fields are combined with a logical 'AND'.
|
||||
type PlansBoolExp struct {
|
||||
And []*PlansBoolExp `json:"_and,omitempty"`
|
||||
Not *PlansBoolExp `json:"_not,omitempty"`
|
||||
Or []*PlansBoolExp `json:"_or,omitempty"`
|
||||
Apps *AppsBoolExp `json:"apps,omitempty"`
|
||||
CreatedAt *TimestamptzComparisonExp `json:"createdAt,omitempty"`
|
||||
Deprecated *BooleanComparisonExp `json:"deprecated,omitempty"`
|
||||
FeatureBackupEnabled *BooleanComparisonExp `json:"featureBackupEnabled,omitempty"`
|
||||
FeatureCustomDomainsEnabled *BooleanComparisonExp `json:"featureCustomDomainsEnabled,omitempty"`
|
||||
FeatureCustomEmailTemplatesEnabled *BooleanComparisonExp `json:"featureCustomEmailTemplatesEnabled,omitempty"`
|
||||
FeatureMaxDbSize *IntComparisonExp `json:"featureMaxDbSize,omitempty"`
|
||||
ID *UUIDComparisonExp `json:"id,omitempty"`
|
||||
Individual *BooleanComparisonExp `json:"individual,omitempty"`
|
||||
IsDefault *BooleanComparisonExp `json:"isDefault,omitempty"`
|
||||
IsFree *BooleanComparisonExp `json:"isFree,omitempty"`
|
||||
IsPublic *BooleanComparisonExp `json:"isPublic,omitempty"`
|
||||
Name *StringComparisonExp `json:"name,omitempty"`
|
||||
Organizations *OrganizationsBoolExp `json:"organizations,omitempty"`
|
||||
Price *IntComparisonExp `json:"price,omitempty"`
|
||||
Sort *IntComparisonExp `json:"sort,omitempty"`
|
||||
UpatedAt *TimestamptzComparisonExp `json:"upatedAt,omitempty"`
|
||||
And []*PlansBoolExp `json:"_and,omitempty"`
|
||||
Not *PlansBoolExp `json:"_not,omitempty"`
|
||||
Or []*PlansBoolExp `json:"_or,omitempty"`
|
||||
Apps *AppsBoolExp `json:"apps,omitempty"`
|
||||
CreatedAt *TimestamptzComparisonExp `json:"createdAt,omitempty"`
|
||||
Deprecated *BooleanComparisonExp `json:"deprecated,omitempty"`
|
||||
FeatureBackupEnabled *BooleanComparisonExp `json:"featureBackupEnabled,omitempty"`
|
||||
FeatureCustomDomainsEnabled *BooleanComparisonExp `json:"featureCustomDomainsEnabled,omitempty"`
|
||||
FeatureCustomEmailTemplatesEnabled *BooleanComparisonExp `json:"featureCustomEmailTemplatesEnabled,omitempty"`
|
||||
FeatureMaxDbSize *IntComparisonExp `json:"featureMaxDbSize,omitempty"`
|
||||
ID *UUIDComparisonExp `json:"id,omitempty"`
|
||||
Individual *BooleanComparisonExp `json:"individual,omitempty"`
|
||||
IsDefault *BooleanComparisonExp `json:"isDefault,omitempty"`
|
||||
IsFree *BooleanComparisonExp `json:"isFree,omitempty"`
|
||||
IsPublic *BooleanComparisonExp `json:"isPublic,omitempty"`
|
||||
Name *StringComparisonExp `json:"name,omitempty"`
|
||||
Organizations *OrganizationsBoolExp `json:"organizations,omitempty"`
|
||||
Price *IntComparisonExp `json:"price,omitempty"`
|
||||
SLALevel *SLALevelEnumComparisonExp `json:"slaLevel,omitempty"`
|
||||
Sort *IntComparisonExp `json:"sort,omitempty"`
|
||||
UpatedAt *TimestamptzComparisonExp `json:"upatedAt,omitempty"`
|
||||
}
|
||||
|
||||
// Ordering options when selecting data from "plans".
|
||||
@@ -4236,6 +4238,7 @@ type PlansOrderBy struct {
|
||||
Name *OrderBy `json:"name,omitempty"`
|
||||
OrganizationsAggregate *OrganizationsAggregateOrderBy `json:"organizations_aggregate,omitempty"`
|
||||
Price *OrderBy `json:"price,omitempty"`
|
||||
SLALevel *OrderBy `json:"slaLevel,omitempty"`
|
||||
Sort *OrderBy `json:"sort,omitempty"`
|
||||
UpatedAt *OrderBy `json:"upatedAt,omitempty"`
|
||||
}
|
||||
@@ -4250,21 +4253,22 @@ type PlansStreamCursorInput struct {
|
||||
|
||||
// Initial value of the column from where the streaming should start
|
||||
type PlansStreamCursorValueInput struct {
|
||||
CreatedAt *time.Time `json:"createdAt,omitempty"`
|
||||
Deprecated *bool `json:"deprecated,omitempty"`
|
||||
FeatureBackupEnabled *bool `json:"featureBackupEnabled,omitempty"`
|
||||
FeatureCustomDomainsEnabled *bool `json:"featureCustomDomainsEnabled,omitempty"`
|
||||
FeatureCustomEmailTemplatesEnabled *bool `json:"featureCustomEmailTemplatesEnabled,omitempty"`
|
||||
FeatureMaxDbSize *int64 `json:"featureMaxDbSize,omitempty"`
|
||||
ID *string `json:"id,omitempty"`
|
||||
Individual *bool `json:"individual,omitempty"`
|
||||
IsDefault *bool `json:"isDefault,omitempty"`
|
||||
IsFree *bool `json:"isFree,omitempty"`
|
||||
IsPublic *bool `json:"isPublic,omitempty"`
|
||||
Name *string `json:"name,omitempty"`
|
||||
Price *int64 `json:"price,omitempty"`
|
||||
Sort *int64 `json:"sort,omitempty"`
|
||||
UpatedAt *time.Time `json:"upatedAt,omitempty"`
|
||||
CreatedAt *time.Time `json:"createdAt,omitempty"`
|
||||
Deprecated *bool `json:"deprecated,omitempty"`
|
||||
FeatureBackupEnabled *bool `json:"featureBackupEnabled,omitempty"`
|
||||
FeatureCustomDomainsEnabled *bool `json:"featureCustomDomainsEnabled,omitempty"`
|
||||
FeatureCustomEmailTemplatesEnabled *bool `json:"featureCustomEmailTemplatesEnabled,omitempty"`
|
||||
FeatureMaxDbSize *int64 `json:"featureMaxDbSize,omitempty"`
|
||||
ID *string `json:"id,omitempty"`
|
||||
Individual *bool `json:"individual,omitempty"`
|
||||
IsDefault *bool `json:"isDefault,omitempty"`
|
||||
IsFree *bool `json:"isFree,omitempty"`
|
||||
IsPublic *bool `json:"isPublic,omitempty"`
|
||||
Name *string `json:"name,omitempty"`
|
||||
Price *int64 `json:"price,omitempty"`
|
||||
SLALevel *SLALevelEnum `json:"slaLevel,omitempty"`
|
||||
Sort *int64 `json:"sort,omitempty"`
|
||||
UpatedAt *time.Time `json:"upatedAt,omitempty"`
|
||||
}
|
||||
|
||||
type QueryRoot struct {
|
||||
@@ -4694,6 +4698,15 @@ type RunServiceStreamCursorValueInput struct {
|
||||
UpdatedAt *time.Time `json:"updatedAt,omitempty"`
|
||||
}
|
||||
|
||||
// Boolean expression to compare columns of type "sla_level_enum". All fields are combined with logical 'AND'.
|
||||
type SLALevelEnumComparisonExp struct {
|
||||
Eq *SLALevelEnum `json:"_eq,omitempty"`
|
||||
In []SLALevelEnum `json:"_in,omitempty"`
|
||||
IsNull *bool `json:"_is_null,omitempty"`
|
||||
Neq *SLALevelEnum `json:"_neq,omitempty"`
|
||||
Nin []SLALevelEnum `json:"_nin,omitempty"`
|
||||
}
|
||||
|
||||
// Boolean expression to compare columns of type "software_type_enum". All fields are combined with logical 'AND'.
|
||||
type SoftwareTypeEnumComparisonExp struct {
|
||||
Eq *SoftwareTypeEnum `json:"_eq,omitempty"`
|
||||
@@ -8542,6 +8555,8 @@ const (
|
||||
// column name
|
||||
PlansSelectColumnPrice PlansSelectColumn = "price"
|
||||
// column name
|
||||
PlansSelectColumnSLALevel PlansSelectColumn = "slaLevel"
|
||||
// column name
|
||||
PlansSelectColumnSort PlansSelectColumn = "sort"
|
||||
// column name
|
||||
PlansSelectColumnUpatedAt PlansSelectColumn = "upatedAt"
|
||||
@@ -8561,13 +8576,14 @@ var AllPlansSelectColumn = []PlansSelectColumn{
|
||||
PlansSelectColumnIsPublic,
|
||||
PlansSelectColumnName,
|
||||
PlansSelectColumnPrice,
|
||||
PlansSelectColumnSLALevel,
|
||||
PlansSelectColumnSort,
|
||||
PlansSelectColumnUpatedAt,
|
||||
}
|
||||
|
||||
func (e PlansSelectColumn) IsValid() bool {
|
||||
switch e {
|
||||
case PlansSelectColumnCreatedAt, PlansSelectColumnDeprecated, PlansSelectColumnFeatureBackupEnabled, PlansSelectColumnFeatureCustomDomainsEnabled, PlansSelectColumnFeatureCustomEmailTemplatesEnabled, PlansSelectColumnFeatureMaxDbSize, PlansSelectColumnID, PlansSelectColumnIndividual, PlansSelectColumnIsDefault, PlansSelectColumnIsFree, PlansSelectColumnIsPublic, PlansSelectColumnName, PlansSelectColumnPrice, PlansSelectColumnSort, PlansSelectColumnUpatedAt:
|
||||
case PlansSelectColumnCreatedAt, PlansSelectColumnDeprecated, PlansSelectColumnFeatureBackupEnabled, PlansSelectColumnFeatureCustomDomainsEnabled, PlansSelectColumnFeatureCustomEmailTemplatesEnabled, PlansSelectColumnFeatureMaxDbSize, PlansSelectColumnID, PlansSelectColumnIndividual, PlansSelectColumnIsDefault, PlansSelectColumnIsFree, PlansSelectColumnIsPublic, PlansSelectColumnName, PlansSelectColumnPrice, PlansSelectColumnSLALevel, PlansSelectColumnSort, PlansSelectColumnUpatedAt:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
@@ -8954,6 +8970,66 @@ func (e RunServiceSelectColumn) MarshalJSON() ([]byte, error) {
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
type SLALevelEnum string
|
||||
|
||||
const (
|
||||
// No SLA
|
||||
SLALevelEnumNone SLALevelEnum = "none"
|
||||
// Premium SLA
|
||||
SLALevelEnumPremium SLALevelEnum = "premium"
|
||||
// Standard SLA
|
||||
SLALevelEnumStandard SLALevelEnum = "standard"
|
||||
)
|
||||
|
||||
var AllSLALevelEnum = []SLALevelEnum{
|
||||
SLALevelEnumNone,
|
||||
SLALevelEnumPremium,
|
||||
SLALevelEnumStandard,
|
||||
}
|
||||
|
||||
func (e SLALevelEnum) IsValid() bool {
|
||||
switch e {
|
||||
case SLALevelEnumNone, SLALevelEnumPremium, SLALevelEnumStandard:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (e SLALevelEnum) String() string {
|
||||
return string(e)
|
||||
}
|
||||
|
||||
func (e *SLALevelEnum) UnmarshalGQL(v any) error {
|
||||
str, ok := v.(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("enums must be strings")
|
||||
}
|
||||
|
||||
*e = SLALevelEnum(str)
|
||||
if !e.IsValid() {
|
||||
return fmt.Errorf("%s is not a valid sla_level_enum", str)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e SLALevelEnum) MarshalGQL(w io.Writer) {
|
||||
fmt.Fprint(w, strconv.Quote(e.String()))
|
||||
}
|
||||
|
||||
func (e *SLALevelEnum) UnmarshalJSON(b []byte) error {
|
||||
s, err := strconv.Unquote(string(b))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return e.UnmarshalGQL(s)
|
||||
}
|
||||
|
||||
func (e SLALevelEnum) MarshalJSON() ([]byte, error) {
|
||||
var buf bytes.Buffer
|
||||
e.MarshalGQL(&buf)
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
type SoftwareTypeEnum string
|
||||
|
||||
const (
|
||||
|
||||
@@ -220,7 +220,8 @@
|
||||
"pages": [
|
||||
"/products/graphql/guides/react-apollo",
|
||||
"/products/graphql/guides/react-query",
|
||||
"/products/graphql/guides/react-urql"
|
||||
"/products/graphql/guides/react-urql",
|
||||
"/products/graphql/guides/codegen-nhost"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1326,10 +1326,9 @@ After we complete the next tutorial on user authentication, you will be able to
|
||||
|
||||
1. **Server-Side Helpers**: Utilities for handling authentication in Next.js server components and middleware
|
||||
2. **Middleware Route Protection**: Next.js middleware runs before any page renders, automatically redirecting unauthenticated users from protected routes and refreshing tokens
|
||||
3. **AuthProvider**: Client-side provider that manages authentication state using Nhost's client with cookie-based storage for server/client synchronization
|
||||
4. **Protected Pages**: Server components can assume authentication since middleware handles protection, focusing purely on rendering authenticated content
|
||||
5. **Navigation**: Server-side navigation component that adapts its links based on authentication status
|
||||
6. **Automatic Redirects**: All route protection and redirects are handled at the middleware level for optimal performance and security
|
||||
3. **Protected Pages**: Server components can assume authentication since middleware handles protection, focusing purely on rendering authenticated content
|
||||
4. **Navigation**: Server-side navigation component that adapts its links based on authentication status
|
||||
5. **Automatic Redirects**: All route protection and redirects are handled at the middleware level for optimal performance and security
|
||||
|
||||
## Key Features Demonstrated
|
||||
|
||||
|
||||
9
docs/products/graphql/guides/codegen-nhost.mdx
Normal file
9
docs/products/graphql/guides/codegen-nhost.mdx
Normal file
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: "Codegen + Nhost"
|
||||
description: "How to use The Guild's codegen with Nhost"
|
||||
icon: U
|
||||
---
|
||||
|
||||
You can use [The Guild's codegen](https://the-guild.dev/graphql/codegen) to generate types and document nodes for your GraphQL operations and use them directly with Nhost's GraphQL client.
|
||||
|
||||
You can find a working example with instructions in our [GitHub repository](https://github.com/nhost/nhost/blob/main/examples/guides/codegen-nhost/README.md).
|
||||
@@ -792,7 +792,7 @@ Maximum height to resize image to while maintaining aspect ratio. Only applies t
|
||||
optional q: number;
|
||||
```
|
||||
|
||||
Image quality (1-100). Only applies to JPEG, WebP and PNG files
|
||||
Image quality (1-100). Only applies to JPEG, WebP, PNG and HEIC files
|
||||
|
||||
#### w?
|
||||
|
||||
@@ -842,7 +842,7 @@ Maximum height to resize image to while maintaining aspect ratio. Only applies t
|
||||
optional q: number;
|
||||
```
|
||||
|
||||
Image quality (1-100). Only applies to JPEG, WebP and PNG files
|
||||
Image quality (1-100). Only applies to JPEG, WebP, PNG and HEIC files
|
||||
|
||||
#### w?
|
||||
|
||||
@@ -1068,7 +1068,7 @@ buildVersion: string
|
||||
## OutputImageFormat
|
||||
|
||||
```ts
|
||||
type OutputImageFormat = 'auto' | 'same' | 'jpeg' | 'webp' | 'png' | 'avif'
|
||||
type OutputImageFormat = 'auto' | 'same' | 'jpeg' | 'webp' | 'png' | 'avif' | 'heic'
|
||||
```
|
||||
|
||||
Output format for image files. Use 'auto' for content negotiation based on Accept header
|
||||
|
||||
@@ -148,7 +148,7 @@ paths:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RFC2822Date'
|
||||
- name: q
|
||||
description: "Image quality (1-100). Only applies to JPEG, WebP and PNG files"
|
||||
description: "Image quality (1-100). Only applies to JPEG, WebP, PNG and HEIC files"
|
||||
in: query
|
||||
schema:
|
||||
type: integer
|
||||
@@ -332,7 +332,7 @@ paths:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RFC2822Date'
|
||||
- name: q
|
||||
description: "Image quality (1-100). Only applies to JPEG, WebP and PNG files"
|
||||
description: "Image quality (1-100). Only applies to JPEG, WebP, PNG and HEIC files"
|
||||
in: query
|
||||
schema:
|
||||
type: integer
|
||||
@@ -614,7 +614,7 @@ paths:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RFC2822Date'
|
||||
- name: q
|
||||
description: "Image quality (1-100). Only applies to JPEG, WebP and PNG files"
|
||||
description: "Image quality (1-100). Only applies to JPEG, WebP, PNG and HEIC files"
|
||||
in: query
|
||||
schema:
|
||||
type: integer
|
||||
@@ -1178,4 +1178,5 @@ components:
|
||||
- webp
|
||||
- png
|
||||
- avif
|
||||
- heic
|
||||
example: same
|
||||
|
||||
25
examples/guides/codegen-nhost/.gitignore
vendored
Normal file
25
examples/guides/codegen-nhost/.gitignore
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
.DS_Store
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
.vite
|
||||
443
examples/guides/codegen-nhost/README.md
Normal file
443
examples/guides/codegen-nhost/README.md
Normal file
@@ -0,0 +1,443 @@
|
||||
# GraphQL Code Generation with Nhost SDK
|
||||
|
||||
This guide demonstrates how to use GraphQL Code Generator with TypedDocumentNode to get full type safety when working with the Nhost SDK.
|
||||
|
||||
Note: While the project uses React to illustrate usage, the generated types and documents can be used in any JavaScript/TypeScript environment.
|
||||
|
||||
## Overview
|
||||
|
||||
The Nhost SDK's GraphQL client supports `TypedDocumentNode` from `@graphql-typed-document-node/core`, allowing you to use generated types and documents for type-safe GraphQL operations. This guide shows you how to set up GraphQL Code Generator to work seamlessly with Nhost.
|
||||
|
||||
## Setup
|
||||
|
||||
### 1. Install Dependencies
|
||||
|
||||
```bash
|
||||
npm install @nhost/nhost-js graphql graphql-typed-document-node/core
|
||||
# or
|
||||
yarn add @nhost/nhost-js graphql graphql-typed-document-node/core
|
||||
# or
|
||||
pnpm add @nhost/nhost-js graphql graphql-typed-document-node/core
|
||||
```
|
||||
|
||||
### 2. Install GraphQL CodeGen
|
||||
|
||||
Install the necessary code generation packages:
|
||||
|
||||
```bash
|
||||
npm install -D @graphql-codegen/cli @graphql-codegen/client-preset @graphql-codegen/schema-ast
|
||||
# or
|
||||
pnpm add -D @graphql-codegen/cli @graphql-codegen/client-preset @graphql-codegen/schema-ast
|
||||
```
|
||||
|
||||
### 3. Configure GraphQL CodeGen
|
||||
|
||||
Create a `codegen.ts` file with the client preset configuration:
|
||||
|
||||
```typescript
|
||||
import type { CodegenConfig } from "@graphql-codegen/cli";
|
||||
|
||||
const config: CodegenConfig = {
|
||||
schema: [
|
||||
{
|
||||
"https://local.graphql.local.nhost.run/v1": {
|
||||
headers: {
|
||||
"x-hasura-admin-secret": "nhost-admin-secret",
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
documents: ["src/lib/graphql/**/*.graphql"],
|
||||
ignoreNoDocuments: true,
|
||||
generates: {
|
||||
"./src/lib/graphql/__generated__/": {
|
||||
preset: "client",
|
||||
presetConfig: {
|
||||
persistedDocuments: false,
|
||||
},
|
||||
plugins: [
|
||||
{
|
||||
"./add-query-source-plugin.cjs": {},
|
||||
},
|
||||
],
|
||||
config: {
|
||||
scalars: {
|
||||
UUID: "string",
|
||||
uuid: "string",
|
||||
timestamptz: "string",
|
||||
jsonb: "Record<string, any>",
|
||||
bigint: "number",
|
||||
bytea: "Buffer",
|
||||
citext: "string",
|
||||
},
|
||||
useTypeImports: true,
|
||||
},
|
||||
},
|
||||
"./schema.graphql": {
|
||||
plugins: ["schema-ast"],
|
||||
config: {
|
||||
includeDirectives: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default config;
|
||||
```
|
||||
|
||||
### 4. Create the Custom Plugin
|
||||
|
||||
The Nhost SDK expects documents to have a `loc.source.body` property containing the query string. Create a custom plugin to add this:
|
||||
|
||||
**add-query-source-plugin.cjs:**
|
||||
|
||||
```javascript
|
||||
// Custom GraphQL Codegen plugin to add loc.source.body to generated documents
|
||||
// This allows the Nhost SDK to extract the query string without needing the graphql package
|
||||
|
||||
const { print } = require("graphql");
|
||||
|
||||
/**
|
||||
* @type {import('@graphql-codegen/plugin-helpers').PluginFunction}
|
||||
*/
|
||||
const plugin = (_schema, documents, _config) => {
|
||||
let output = "";
|
||||
|
||||
for (const doc of documents) {
|
||||
if (!doc.document) continue;
|
||||
|
||||
for (const definition of doc.document.definitions) {
|
||||
if (definition.kind === "OperationDefinition" && definition.name) {
|
||||
const operationName = definition.name.value;
|
||||
const documentName = `${operationName}Document`;
|
||||
|
||||
// Create a document with just this operation
|
||||
const singleOpDocument = {
|
||||
kind: "Document",
|
||||
definitions: [definition],
|
||||
};
|
||||
|
||||
// Use graphql print to convert AST to string
|
||||
const source = print(singleOpDocument);
|
||||
|
||||
output += `
|
||||
// Add query source to ${documentName}
|
||||
if (${documentName}) {
|
||||
Object.assign(${documentName}, {
|
||||
loc: { source: { body: ${JSON.stringify(source)} } }
|
||||
});
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
};
|
||||
|
||||
module.exports = { plugin };
|
||||
```
|
||||
|
||||
## Integration Guide
|
||||
|
||||
### 1. Create an Auth Provider
|
||||
|
||||
Create an authentication context to manage the Nhost client and user session:
|
||||
|
||||
```typescript
|
||||
// src/lib/nhost/AuthProvider.tsx
|
||||
import {
|
||||
createContext,
|
||||
useContext,
|
||||
useEffect,
|
||||
useState,
|
||||
useMemo,
|
||||
type ReactNode,
|
||||
} from "react";
|
||||
import { createClient, type NhostClient } from "@nhost/nhost-js";
|
||||
import { type Session } from "@nhost/nhost-js/auth";
|
||||
|
||||
interface AuthContextType {
|
||||
user: Session["user"] | null;
|
||||
session: Session | null;
|
||||
isAuthenticated: boolean;
|
||||
isLoading: boolean;
|
||||
nhost: NhostClient;
|
||||
}
|
||||
|
||||
const AuthContext = createContext<AuthContextType | null>(null);
|
||||
|
||||
export const AuthProvider = ({ children }: { children: ReactNode }) => {
|
||||
const [user, setUser] = useState<Session["user"] | null>(null);
|
||||
const [session, setSession] = useState<Session | null>(null);
|
||||
const [isLoading, setIsLoading] = useState<boolean>(true);
|
||||
const [isAuthenticated, setIsAuthenticated] = useState<boolean>(false);
|
||||
|
||||
// Create the nhost client
|
||||
const nhost = useMemo(
|
||||
() =>
|
||||
createClient({
|
||||
region: import.meta.env.VITE_NHOST_REGION || "local",
|
||||
subdomain: import.meta.env.VITE_NHOST_SUBDOMAIN || "local",
|
||||
}),
|
||||
[],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
setIsLoading(true);
|
||||
const currentSession = nhost.getUserSession();
|
||||
setUser(currentSession?.user || null);
|
||||
setSession(currentSession);
|
||||
setIsAuthenticated(!!currentSession);
|
||||
setIsLoading(false);
|
||||
|
||||
const unsubscribe = nhost.sessionStorage.onChange((currentSession) => {
|
||||
setUser(currentSession?.user || null);
|
||||
setSession(currentSession);
|
||||
setIsAuthenticated(!!currentSession);
|
||||
});
|
||||
|
||||
return () => {
|
||||
unsubscribe();
|
||||
};
|
||||
}, [nhost]);
|
||||
|
||||
const value: AuthContextType = {
|
||||
user,
|
||||
session,
|
||||
isAuthenticated,
|
||||
isLoading,
|
||||
nhost,
|
||||
};
|
||||
|
||||
return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
|
||||
};
|
||||
|
||||
export const useAuth = (): AuthContextType => {
|
||||
const context = useContext(AuthContext);
|
||||
if (!context) {
|
||||
throw new Error("useAuth must be used within an AuthProvider");
|
||||
}
|
||||
return context;
|
||||
};
|
||||
```
|
||||
|
||||
### 2. Set Up Your App Providers
|
||||
|
||||
Wrap your application with the Auth provider:
|
||||
|
||||
```tsx
|
||||
// src/main.tsx
|
||||
import React from "react";
|
||||
import { createRoot } from "react-dom/client";
|
||||
import "./index.css";
|
||||
import App from "./App";
|
||||
import { AuthProvider } from "./lib/nhost/AuthProvider";
|
||||
|
||||
const Root = () => (
|
||||
<React.StrictMode>
|
||||
<AuthProvider>
|
||||
<App />
|
||||
</AuthProvider>
|
||||
</React.StrictMode>
|
||||
);
|
||||
|
||||
const rootElement = document.getElementById("root");
|
||||
if (!rootElement) throw new Error("Root element not found");
|
||||
|
||||
createRoot(rootElement).render(<Root />);
|
||||
```
|
||||
|
||||
### 3. Define GraphQL Operations
|
||||
|
||||
Create GraphQL files with your queries and mutations:
|
||||
|
||||
```graphql
|
||||
# src/lib/graphql/operations.graphql
|
||||
query GetNinjaTurtlesWithComments {
|
||||
ninjaTurtles {
|
||||
id
|
||||
name
|
||||
description
|
||||
createdAt
|
||||
updatedAt
|
||||
comments {
|
||||
id
|
||||
comment
|
||||
createdAt
|
||||
user {
|
||||
id
|
||||
displayName
|
||||
email
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mutation AddComment($ninjaTurtleId: uuid!, $comment: String!) {
|
||||
insertComment(object: { ninjaTurtleId: $ninjaTurtleId, comment: $comment }) {
|
||||
id
|
||||
comment
|
||||
createdAt
|
||||
ninjaTurtleId
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Generate TypeScript Types
|
||||
|
||||
Run the code generator:
|
||||
|
||||
```bash
|
||||
npx graphql-codegen
|
||||
```
|
||||
|
||||
You can also add a script to your `package.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"scripts": {
|
||||
"generate": "graphql-codegen --config codegen.ts"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Then run:
|
||||
|
||||
```bash
|
||||
npm run generate
|
||||
# or
|
||||
pnpm generate
|
||||
```
|
||||
|
||||
### 5. Use in Components
|
||||
|
||||
Use the generated types and documents with the Nhost SDK:
|
||||
|
||||
```tsx
|
||||
// src/pages/Home.tsx
|
||||
import { type JSX, useCallback, useEffect, useState } from "react";
|
||||
import {
|
||||
AddCommentDocument,
|
||||
GetNinjaTurtlesWithCommentsDocument,
|
||||
type GetNinjaTurtlesWithCommentsQuery,
|
||||
} from "../lib/graphql/__generated__/graphql";
|
||||
import { useAuth } from "../lib/nhost/AuthProvider";
|
||||
|
||||
export default function Home(): JSX.Element {
|
||||
const { isLoading, nhost } = useAuth();
|
||||
const [activeCommentId, setActiveCommentId] = useState<string | null>(null);
|
||||
const [commentText, setCommentText] = useState("");
|
||||
const [activeTabId, setActiveTabId] = useState<string | null>(null);
|
||||
|
||||
const [data, setData] = useState<GetNinjaTurtlesWithCommentsQuery | null>(
|
||||
null,
|
||||
);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState<Error | null>(null);
|
||||
|
||||
// Fetch ninja turtles data
|
||||
const fetchNinjaTurtles = useCallback(async () => {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
try {
|
||||
const result = await nhost.graphql.request(
|
||||
GetNinjaTurtlesWithCommentsDocument,
|
||||
{},
|
||||
);
|
||||
|
||||
if (result.body.errors) {
|
||||
throw new Error(result.body.errors[0]?.message);
|
||||
}
|
||||
|
||||
setData(result.body.data ?? null);
|
||||
} catch (err) {
|
||||
setError(err as Error);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, [nhost.graphql]);
|
||||
|
||||
// Load data on mount
|
||||
useEffect(() => {
|
||||
if (!isLoading) {
|
||||
fetchNinjaTurtles();
|
||||
}
|
||||
}, [isLoading, fetchNinjaTurtles]);
|
||||
|
||||
const addComment = async (ninjaTurtleId: string, comment: string) => {
|
||||
try {
|
||||
const result = await nhost.graphql.request(AddCommentDocument, {
|
||||
ninjaTurtleId,
|
||||
comment,
|
||||
});
|
||||
|
||||
if (result.body.errors) {
|
||||
throw new Error(result.body.errors[0]?.message);
|
||||
}
|
||||
|
||||
// Clear form and refetch data
|
||||
setCommentText("");
|
||||
setActiveCommentId(null);
|
||||
await fetchNinjaTurtles();
|
||||
} catch (err) {
|
||||
console.error("Error adding comment:", err);
|
||||
}
|
||||
};
|
||||
|
||||
// ... rest of component
|
||||
}
|
||||
```
|
||||
|
||||
## Key Points
|
||||
|
||||
### Type-Safe GraphQL Requests
|
||||
|
||||
The Nhost SDK's `graphql.request()` method has overloads that support `TypedDocumentNode`:
|
||||
|
||||
```typescript
|
||||
// Type inference works automatically
|
||||
const result = await nhost.graphql.request(
|
||||
GetNinjaTurtlesWithCommentsDocument,
|
||||
{}, // Variables are type-checked
|
||||
);
|
||||
|
||||
// result.body.data is typed as GetNinjaTurtlesWithCommentsQuery | undefined
|
||||
```
|
||||
|
||||
### How It Works
|
||||
|
||||
1. **GraphQL Code Generator** creates `TypedDocumentNode` types and documents using the client preset
|
||||
2. **Custom Plugin** adds the `loc.source.body` property to each document at runtime
|
||||
3. **Nhost SDK** detects the `TypedDocumentNode`, extracts the query string from `loc.source.body`, and executes the request
|
||||
4. **TypeScript** infers response types automatically based on the document types
|
||||
|
||||
### Benefits
|
||||
|
||||
- ✅ Full type safety for queries, mutations, and variables
|
||||
- ✅ Automatic type inference - no manual type annotations needed
|
||||
- ✅ Type-checked variables prevent runtime errors
|
||||
- ✅ IntelliSense support in your IDE
|
||||
- ✅ Compile-time errors for invalid queries or mismatched types
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "not a valid graphql query" Error
|
||||
|
||||
If you see this error, make sure:
|
||||
1. The custom plugin (`add-query-source-plugin.cjs`) is in place
|
||||
2. The plugin is configured in your `codegen.ts`
|
||||
3. You've run `pnpm generate` after adding the plugin
|
||||
|
||||
### TypeScript Errors
|
||||
|
||||
If you get type errors:
|
||||
1. Make sure you're not passing explicit generic type parameters to `nhost.graphql.request()`
|
||||
2. Let TypeScript infer types from the document
|
||||
3. Pass an empty object `{}` for queries without variables
|
||||
|
||||
## Additional Resources
|
||||
|
||||
- [GraphQL Code Generator Docs](https://the-guild.dev/graphql/codegen)
|
||||
- [Nhost Documentation](https://docs.nhost.io)
|
||||
- [TypedDocumentNode](https://github.com/dotansimha/graphql-typed-document-node)
|
||||
44
examples/guides/codegen-nhost/add-query-source-plugin.cjs
Normal file
44
examples/guides/codegen-nhost/add-query-source-plugin.cjs
Normal file
@@ -0,0 +1,44 @@
|
||||
// Custom GraphQL Codegen plugin to add loc.source.body to generated documents
|
||||
// This allows the Nhost SDK to extract the query string without needing the graphql package
|
||||
|
||||
const { print } = require("graphql");
|
||||
|
||||
/**
|
||||
* @type {import('@graphql-codegen/plugin-helpers').PluginFunction}
|
||||
*/
|
||||
const plugin = (_schema, documents, _config) => {
|
||||
let output = "";
|
||||
|
||||
for (const doc of documents) {
|
||||
if (!doc.document) continue;
|
||||
|
||||
for (const definition of doc.document.definitions) {
|
||||
if (definition.kind === "OperationDefinition" && definition.name) {
|
||||
const operationName = definition.name.value;
|
||||
const documentName = `${operationName}Document`;
|
||||
|
||||
// Create a document with just this operation
|
||||
const singleOpDocument = {
|
||||
kind: "Document",
|
||||
definitions: [definition],
|
||||
};
|
||||
|
||||
// Use graphql print to convert AST to string
|
||||
const source = print(singleOpDocument);
|
||||
|
||||
output += `
|
||||
// Add query source to ${documentName}
|
||||
if (${documentName}) {
|
||||
Object.assign(${documentName}, {
|
||||
loc: { source: { body: ${JSON.stringify(source)} } }
|
||||
});
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
};
|
||||
|
||||
module.exports = { plugin };
|
||||
7
examples/guides/codegen-nhost/biome.json
Normal file
7
examples/guides/codegen-nhost/biome.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"root": false,
|
||||
"extends": "//",
|
||||
"linter": {
|
||||
"includes": ["**", "!src/lib/graphql/__generated__/*.ts"]
|
||||
}
|
||||
}
|
||||
27
examples/guides/codegen-nhost/codegen-wrapper.sh
Executable file
27
examples/guides/codegen-nhost/codegen-wrapper.sh
Executable file
@@ -0,0 +1,27 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
echo "Running GraphQL code generator..."
|
||||
pnpm graphql-codegen --config codegen.ts
|
||||
|
||||
GENERATED_TS_FILE="src/lib/graphql/__generated__/"
|
||||
GENERATED_SCHEMA_FILE="schema.graphql"
|
||||
|
||||
if [ -d "$GENERATED_TS_FILE" ]; then
|
||||
echo "Formatting $GENERATED_TS_FILE..."
|
||||
biome check --write "$GENERATED_TS_FILE"
|
||||
else
|
||||
echo "Error: Generated TypeScript file not found at $GENERATED_TS_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
if [ -f "$GENERATED_SCHEMA_FILE" ]; then
|
||||
echo "Formatting $GENERATED_SCHEMA_FILE..."
|
||||
biome check --write "$GENERATED_SCHEMA_FILE"
|
||||
echo "Successfully formatted $GENERATED_SCHEMA_FILE"
|
||||
else
|
||||
echo "Warning: Generated schema file not found at $GENERATED_SCHEMA_FILE"
|
||||
fi
|
||||
|
||||
echo "All tasks completed successfully."
|
||||
48
examples/guides/codegen-nhost/codegen.ts
Normal file
48
examples/guides/codegen-nhost/codegen.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import type { CodegenConfig } from "@graphql-codegen/cli";
|
||||
|
||||
const config: CodegenConfig = {
|
||||
schema: [
|
||||
{
|
||||
"https://local.graphql.local.nhost.run/v1": {
|
||||
headers: {
|
||||
"x-hasura-admin-secret": "nhost-admin-secret",
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
documents: ["src/lib/graphql/**/*.graphql"],
|
||||
ignoreNoDocuments: true,
|
||||
generates: {
|
||||
"./src/lib/graphql/__generated__/": {
|
||||
preset: "client",
|
||||
presetConfig: {
|
||||
persistedDocuments: false,
|
||||
},
|
||||
plugins: [
|
||||
{
|
||||
"./add-query-source-plugin.cjs": {},
|
||||
},
|
||||
],
|
||||
config: {
|
||||
scalars: {
|
||||
UUID: "string",
|
||||
uuid: "string",
|
||||
timestamptz: "string",
|
||||
jsonb: "Record<string, any>",
|
||||
bigint: "number",
|
||||
bytea: "Buffer",
|
||||
citext: "string",
|
||||
},
|
||||
useTypeImports: true,
|
||||
},
|
||||
},
|
||||
"./schema.graphql": {
|
||||
plugins: ["schema-ast"],
|
||||
config: {
|
||||
includeDirectives: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default config;
|
||||
13
examples/guides/codegen-nhost/index.html
Normal file
13
examples/guides/codegen-nhost/index.html
Normal file
@@ -0,0 +1,13 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Vite + React</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/src/main.tsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
40
examples/guides/codegen-nhost/package.json
Normal file
40
examples/guides/codegen-nhost/package.json
Normal file
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"name": "guides/codegen-nhost",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "tsc && vite build",
|
||||
"generate": "bash codegen-wrapper.sh",
|
||||
"test": "pnpm test:typecheck && pnpm test:lint",
|
||||
"test:typecheck": "tsc --noEmit",
|
||||
"test:lint": "biome check",
|
||||
"format": "biome format --write",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@graphql-typed-document-node/core": "^3.2.0",
|
||||
"@nhost/nhost-js": "workspace:*",
|
||||
"graphql": "^16.11.0",
|
||||
"react": "^19.1.0",
|
||||
"react-dom": "^19.1.0",
|
||||
"react-router-dom": "^7.6.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@graphql-codegen/cli": "^5.0.6",
|
||||
"@graphql-codegen/client-preset": "^5.1.2",
|
||||
"@graphql-codegen/schema-ast": "^4.1.0",
|
||||
"@graphql-codegen/typescript": "^4.1.6",
|
||||
"@graphql-codegen/typescript-operations": "^4.6.1",
|
||||
"@types/node": "^22.15.17",
|
||||
"@types/react": "^19.1.2",
|
||||
"@types/react-dom": "^19.1.2",
|
||||
"@vitejs/plugin-react": "^4.4.1"
|
||||
},
|
||||
"pnpm": {
|
||||
"overrides": {
|
||||
"js-yaml@<4.1.1": ">=4.1.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
3826
examples/guides/codegen-nhost/pnpm-lock.yaml
generated
Normal file
3826
examples/guides/codegen-nhost/pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
1
examples/guides/codegen-nhost/public/vite.svg
Normal file
1
examples/guides/codegen-nhost/public/vite.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
10143
examples/guides/codegen-nhost/schema.graphql
Normal file
10143
examples/guides/codegen-nhost/schema.graphql
Normal file
File diff suppressed because it is too large
Load Diff
56
examples/guides/codegen-nhost/src/App.tsx
Normal file
56
examples/guides/codegen-nhost/src/App.tsx
Normal file
@@ -0,0 +1,56 @@
|
||||
import type { JSX } from "react";
|
||||
import {
|
||||
createBrowserRouter,
|
||||
createRoutesFromElements,
|
||||
Navigate,
|
||||
Outlet,
|
||||
Route,
|
||||
RouterProvider,
|
||||
} from "react-router-dom";
|
||||
import Navigation from "./components/Navigation";
|
||||
import ProtectedRoute from "./components/ProtectedRoute";
|
||||
import Home from "./pages/Home";
|
||||
import Profile from "./pages/Profile";
|
||||
import SignIn from "./pages/SignIn";
|
||||
import SignUp from "./pages/SignUp";
|
||||
|
||||
// Root layout component to wrap all routes
|
||||
const RootLayout = (): JSX.Element => {
|
||||
return (
|
||||
<div className="flex-col min-h-screen">
|
||||
<Navigation />
|
||||
<main className="max-w-2xl mx-auto p-6 w-full">
|
||||
<Outlet />
|
||||
</main>
|
||||
<footer>
|
||||
<p
|
||||
className="text-sm text-center"
|
||||
style={{ color: "var(--text-muted)" }}
|
||||
>
|
||||
© {new Date().getFullYear()} Nhost Demo
|
||||
</p>
|
||||
</footer>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
// Create router with routes
|
||||
const router = createBrowserRouter(
|
||||
createRoutesFromElements(
|
||||
<Route element={<RootLayout />}>
|
||||
<Route path="signin" element={<SignIn />} />
|
||||
<Route path="signup" element={<SignUp />} />
|
||||
<Route element={<ProtectedRoute />}>
|
||||
<Route path="home" element={<Home />} />
|
||||
<Route path="profile" element={<Profile />} />
|
||||
</Route>
|
||||
<Route path="*" element={<Navigate to="/" />} />
|
||||
</Route>,
|
||||
),
|
||||
);
|
||||
|
||||
const App = (): JSX.Element => {
|
||||
return <RouterProvider router={router} />;
|
||||
};
|
||||
|
||||
export default App;
|
||||
85
examples/guides/codegen-nhost/src/components/Navigation.tsx
Normal file
85
examples/guides/codegen-nhost/src/components/Navigation.tsx
Normal file
@@ -0,0 +1,85 @@
|
||||
import type { JSX } from "react";
|
||||
import { Link, useLocation } from "react-router-dom";
|
||||
import { useAuth } from "../lib/nhost/AuthProvider";
|
||||
|
||||
export default function Navigation(): JSX.Element {
|
||||
const { isAuthenticated, nhost, session } = useAuth();
|
||||
const location = useLocation();
|
||||
|
||||
// Helper function to determine if a link is active
|
||||
const isActive = (path: string): string => {
|
||||
return location.pathname === path ? "active" : "";
|
||||
};
|
||||
|
||||
return (
|
||||
<nav className="navbar">
|
||||
<div className="navbar-container">
|
||||
<div className="flex items-center">
|
||||
<span className="navbar-brand">Nhost Demo</span>
|
||||
<div className="navbar-links">
|
||||
{isAuthenticated ? (
|
||||
<>
|
||||
<Link to="/home" className={`nav-link ${isActive("/home")}`}>
|
||||
Home
|
||||
</Link>
|
||||
<Link
|
||||
to="/profile"
|
||||
className={`nav-link ${isActive("/profile")}`}
|
||||
>
|
||||
Profile
|
||||
</Link>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Link
|
||||
to="/signin"
|
||||
className={`nav-link ${isActive("/signin")}`}
|
||||
>
|
||||
Sign In
|
||||
</Link>
|
||||
<Link
|
||||
to="/signup"
|
||||
className={`nav-link ${isActive("/signup")}`}
|
||||
>
|
||||
Sign Up
|
||||
</Link>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{isAuthenticated && (
|
||||
<div>
|
||||
<button
|
||||
type="button"
|
||||
onClick={async () => {
|
||||
if (session) {
|
||||
await nhost.auth.signOut({
|
||||
refreshToken: session.refreshToken,
|
||||
});
|
||||
}
|
||||
}}
|
||||
className="icon-button"
|
||||
title="Sign Out"
|
||||
>
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
aria-label="Sign Out"
|
||||
role="img"
|
||||
>
|
||||
<path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4" />
|
||||
<polyline points="16 17 21 12 16 7" />
|
||||
<line x1="21" y1="12" x2="9" y2="12" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</nav>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import { Navigate, Outlet } from "react-router-dom";
|
||||
import { useAuth } from "../lib/nhost/AuthProvider";
|
||||
|
||||
interface ProtectedRouteProps {
|
||||
redirectTo?: string;
|
||||
}
|
||||
|
||||
export default function ProtectedRoute({
|
||||
redirectTo = "/signin",
|
||||
}: ProtectedRouteProps) {
|
||||
const { isAuthenticated, isLoading } = useAuth();
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className="loading-container">
|
||||
<p>Loading...</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (!isAuthenticated) {
|
||||
return <Navigate to={redirectTo} />;
|
||||
}
|
||||
|
||||
return <Outlet />;
|
||||
}
|
||||
552
examples/guides/codegen-nhost/src/index.css
Normal file
552
examples/guides/codegen-nhost/src/index.css
Normal file
@@ -0,0 +1,552 @@
|
||||
/* Base styles */
|
||||
:root {
|
||||
--background: #030712;
|
||||
--foreground: #ffffff;
|
||||
--card-bg: #111827;
|
||||
--card-border: #1f2937;
|
||||
--primary: #6366f1;
|
||||
--primary-hover: #4f46e5;
|
||||
--secondary: #10b981;
|
||||
--secondary-hover: #059669;
|
||||
--accent: #8b5cf6;
|
||||
--accent-hover: #7c3aed;
|
||||
--success: #22c55e;
|
||||
--error: #ef4444;
|
||||
--text-primary: #f9fafb;
|
||||
--text-secondary: #d1d5db;
|
||||
--text-muted: #9ca3af;
|
||||
--border-color: rgba(31, 41, 55, 0.7);
|
||||
--font-geist-mono:
|
||||
ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono",
|
||||
"Courier New", monospace;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
background: var(--background);
|
||||
color: var(--foreground);
|
||||
font-family: system-ui, -apple-system, sans-serif;
|
||||
line-height: 1.6;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
/* Layout */
|
||||
.flex {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.flex-col {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.items-center {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.justify-center {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.justify-between {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.min-h-screen {
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.w-full {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.max-w-2xl {
|
||||
max-width: 42rem;
|
||||
}
|
||||
|
||||
.mx-auto {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.p-6 {
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.p-8 {
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
.py-5 {
|
||||
padding-top: 1.25rem;
|
||||
padding-bottom: 1.25rem;
|
||||
}
|
||||
|
||||
.mb-6 {
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.mb-4 {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.mt-4 {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.mr-8 {
|
||||
margin-right: 2rem;
|
||||
}
|
||||
|
||||
.ml-2 {
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
|
||||
.space-y-5 > * + * {
|
||||
margin-top: 1.25rem;
|
||||
}
|
||||
|
||||
.space-x-4 > * + * {
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
/* Typography */
|
||||
h1,
|
||||
h2,
|
||||
h3 {
|
||||
font-weight: bold;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.text-3xl {
|
||||
font-size: 1.875rem;
|
||||
}
|
||||
|
||||
.text-2xl {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
.text-xl {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
.text-lg {
|
||||
font-size: 1.125rem;
|
||||
}
|
||||
|
||||
.text-sm {
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
.text-xs {
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.font-semibold {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.font-medium {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.text-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.gradient-text {
|
||||
background: linear-gradient(to right, var(--primary), var(--accent));
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
color: transparent;
|
||||
}
|
||||
|
||||
/* Components */
|
||||
.glass-card {
|
||||
background: rgba(17, 24, 39, 0.7);
|
||||
backdrop-filter: blur(8px);
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 0.5rem;
|
||||
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: inline-block;
|
||||
padding: 0.625rem 1rem;
|
||||
font-weight: 500;
|
||||
border-radius: 0.375rem;
|
||||
transition: all 0.2s ease;
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background-color: var(--primary);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-primary:hover:not(:disabled) {
|
||||
background-color: var(--primary-hover);
|
||||
box-shadow: 0 0 0 2px rgba(99, 102, 241, 0.1);
|
||||
}
|
||||
|
||||
.btn:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
background-color: var(--secondary);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-secondary:hover:not(:disabled) {
|
||||
background-color: var(--secondary-hover);
|
||||
}
|
||||
|
||||
.nav-link {
|
||||
display: inline-block;
|
||||
padding: 0.5rem 1rem;
|
||||
border-radius: 0.375rem;
|
||||
font-weight: 600;
|
||||
font-size: 0.875rem;
|
||||
transition: all 0.2s ease;
|
||||
color: var(--text-secondary);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.nav-link:hover {
|
||||
color: white;
|
||||
background-color: rgba(31, 41, 55, 0.7);
|
||||
}
|
||||
|
||||
.nav-link.active {
|
||||
background-color: var(--primary);
|
||||
color: white;
|
||||
box-shadow: 0 0 0 2px rgba(99, 102, 241, 0.3);
|
||||
}
|
||||
|
||||
input,
|
||||
textarea,
|
||||
select {
|
||||
width: 100%;
|
||||
padding: 0.625rem 0.75rem;
|
||||
background-color: rgba(31, 41, 55, 0.8);
|
||||
border: 1px solid var(--border-color);
|
||||
color: white;
|
||||
border-radius: 0.375rem;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
input:focus,
|
||||
textarea:focus,
|
||||
select:focus {
|
||||
outline: none;
|
||||
border-color: var(--primary);
|
||||
box-shadow: 0 0 0 2px rgba(99, 102, 241, 0.2);
|
||||
}
|
||||
|
||||
label {
|
||||
display: block;
|
||||
margin-bottom: 0.25rem;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 500;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.alert {
|
||||
padding: 0.75rem;
|
||||
border-radius: 0.375rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.alert-error {
|
||||
background-color: rgba(239, 68, 68, 0.2);
|
||||
border: 1px solid rgba(239, 68, 68, 0.5);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.alert-success {
|
||||
background-color: rgba(34, 197, 94, 0.2);
|
||||
border: 1px solid rgba(34, 197, 94, 0.5);
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* Navigation */
|
||||
.navbar {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 10;
|
||||
background-color: rgba(17, 24, 39, 0.8);
|
||||
backdrop-filter: blur(8px);
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
padding: 1rem 0;
|
||||
margin-bottom: 2rem;
|
||||
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.navbar-container {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
max-width: 42rem;
|
||||
margin: 0 auto;
|
||||
padding: 0 1.5rem;
|
||||
}
|
||||
|
||||
.navbar-brand {
|
||||
color: var(--primary);
|
||||
font-weight: bold;
|
||||
font-size: 1.125rem;
|
||||
margin-right: 2rem;
|
||||
}
|
||||
|
||||
.navbar-links {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
/* Tables */
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
th {
|
||||
text-align: left;
|
||||
padding: 0.75rem 1rem;
|
||||
font-size: 0.75rem;
|
||||
text-transform: uppercase;
|
||||
color: var(--text-secondary);
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 0.75rem 1rem;
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
tr:hover {
|
||||
background-color: rgba(31, 41, 55, 0.3);
|
||||
}
|
||||
|
||||
/* File upload styles */
|
||||
.file-upload {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 1.5rem;
|
||||
border: 2px dashed rgba(99, 102, 241, 0.3);
|
||||
border-radius: 0.5rem;
|
||||
background-color: rgba(31, 41, 55, 0.3);
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.file-upload:hover {
|
||||
border-color: var(--primary);
|
||||
}
|
||||
|
||||
/* Footer */
|
||||
footer {
|
||||
padding: 1.25rem 0;
|
||||
border-top: 1px solid var(--border-color);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* Link styles */
|
||||
a {
|
||||
color: var(--primary);
|
||||
text-decoration: none;
|
||||
transition: color 0.2s;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: var(--primary-hover);
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* Loading state */
|
||||
.loading-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 50vh;
|
||||
}
|
||||
|
||||
/* Code blocks */
|
||||
pre {
|
||||
background-color: rgba(31, 41, 55, 0.8);
|
||||
padding: 1rem;
|
||||
border-radius: 0.375rem;
|
||||
overflow: auto;
|
||||
font-family: monospace;
|
||||
border: 1px solid var(--border-color);
|
||||
font-size: 0.875rem;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
/* Profile data */
|
||||
.profile-item {
|
||||
padding-bottom: 0.75rem;
|
||||
margin-bottom: 0.75rem;
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
.profile-item strong {
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.action-link {
|
||||
color: var(--primary);
|
||||
font-weight: 500;
|
||||
margin-right: 0.75rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.action-link:hover {
|
||||
color: var(--primary-hover);
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.action-link-danger {
|
||||
color: var(--error);
|
||||
}
|
||||
|
||||
.action-link-danger:hover {
|
||||
color: #f05252;
|
||||
}
|
||||
|
||||
/* Icon button */
|
||||
.icon-button {
|
||||
background-color: transparent;
|
||||
color: var(--primary);
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.icon-button:hover {
|
||||
background-color: rgba(99, 102, 241, 0.1);
|
||||
color: var(--primary-hover);
|
||||
}
|
||||
|
||||
.icon-button:disabled {
|
||||
opacity: 0.6;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.icon-button svg {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
/* Table action icons */
|
||||
.table-actions {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.action-icon {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.action-icon svg {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
.action-icon:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.action-icon-view {
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
.action-icon-view:hover:not(:disabled) {
|
||||
background-color: rgba(99, 102, 241, 0.1);
|
||||
color: var(--primary-hover);
|
||||
}
|
||||
|
||||
.action-icon-delete {
|
||||
color: var(--error);
|
||||
}
|
||||
|
||||
.action-icon-delete:hover:not(:disabled) {
|
||||
background-color: rgba(239, 68, 68, 0.1);
|
||||
color: #f05252;
|
||||
}
|
||||
|
||||
/* Tab styles */
|
||||
.tabs-container {
|
||||
display: flex;
|
||||
border-radius: 0.5rem;
|
||||
overflow: hidden;
|
||||
margin-bottom: 1.5rem;
|
||||
border: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
.tab-button {
|
||||
flex: 1;
|
||||
padding: 0.75rem 1rem;
|
||||
font-weight: 500;
|
||||
transition: all 0.2s ease;
|
||||
background-color: rgba(31, 41, 55, 0.5);
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.tab-button:hover:not(.tab-active) {
|
||||
background-color: rgba(31, 41, 55, 0.8);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.tab-button.tab-active {
|
||||
background-color: var(--primary);
|
||||
color: white;
|
||||
box-shadow: 0 0 0 1px rgba(99, 102, 241, 0.3);
|
||||
}
|
||||
|
||||
.tab-button:first-child {
|
||||
border-top-left-radius: 0.5rem;
|
||||
border-bottom-left-radius: 0.5rem;
|
||||
}
|
||||
|
||||
.tab-button:last-child {
|
||||
border-top-right-radius: 0.5rem;
|
||||
border-bottom-right-radius: 0.5rem;
|
||||
}
|
||||
|
||||
.tab-content {
|
||||
margin-top: 1.5rem;
|
||||
}
|
||||
110
examples/guides/codegen-nhost/src/lib/graphql/__generated__/fragment-masking.ts
generated
Normal file
110
examples/guides/codegen-nhost/src/lib/graphql/__generated__/fragment-masking.ts
generated
Normal file
@@ -0,0 +1,110 @@
|
||||
/* eslint-disable */
|
||||
import type {
|
||||
DocumentTypeDecoration,
|
||||
ResultOf,
|
||||
TypedDocumentNode,
|
||||
} from "@graphql-typed-document-node/core";
|
||||
import type { FragmentDefinitionNode } from "graphql";
|
||||
import type { Incremental } from "./graphql";
|
||||
|
||||
export type FragmentType<
|
||||
TDocumentType extends DocumentTypeDecoration<any, any>,
|
||||
> = TDocumentType extends DocumentTypeDecoration<infer TType, any>
|
||||
? [TType] extends [{ " $fragmentName"?: infer TKey }]
|
||||
? TKey extends string
|
||||
? { " $fragmentRefs"?: { [key in TKey]: TType } }
|
||||
: never
|
||||
: never
|
||||
: never;
|
||||
|
||||
// return non-nullable if `fragmentType` is non-nullable
|
||||
export function useFragment<TType>(
|
||||
_documentNode: DocumentTypeDecoration<TType, any>,
|
||||
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>>,
|
||||
): TType;
|
||||
// return nullable if `fragmentType` is undefined
|
||||
export function useFragment<TType>(
|
||||
_documentNode: DocumentTypeDecoration<TType, any>,
|
||||
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | undefined,
|
||||
): TType | undefined;
|
||||
// return nullable if `fragmentType` is nullable
|
||||
export function useFragment<TType>(
|
||||
_documentNode: DocumentTypeDecoration<TType, any>,
|
||||
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | null,
|
||||
): TType | null;
|
||||
// return nullable if `fragmentType` is nullable or undefined
|
||||
export function useFragment<TType>(
|
||||
_documentNode: DocumentTypeDecoration<TType, any>,
|
||||
fragmentType:
|
||||
| FragmentType<DocumentTypeDecoration<TType, any>>
|
||||
| null
|
||||
| undefined,
|
||||
): TType | null | undefined;
|
||||
// return array of non-nullable if `fragmentType` is array of non-nullable
|
||||
export function useFragment<TType>(
|
||||
_documentNode: DocumentTypeDecoration<TType, any>,
|
||||
fragmentType: Array<FragmentType<DocumentTypeDecoration<TType, any>>>,
|
||||
): Array<TType>;
|
||||
// return array of nullable if `fragmentType` is array of nullable
|
||||
export function useFragment<TType>(
|
||||
_documentNode: DocumentTypeDecoration<TType, any>,
|
||||
fragmentType:
|
||||
| Array<FragmentType<DocumentTypeDecoration<TType, any>>>
|
||||
| null
|
||||
| undefined,
|
||||
): Array<TType> | null | undefined;
|
||||
// return readonly array of non-nullable if `fragmentType` is array of non-nullable
|
||||
export function useFragment<TType>(
|
||||
_documentNode: DocumentTypeDecoration<TType, any>,
|
||||
fragmentType: ReadonlyArray<FragmentType<DocumentTypeDecoration<TType, any>>>,
|
||||
): ReadonlyArray<TType>;
|
||||
// return readonly array of nullable if `fragmentType` is array of nullable
|
||||
export function useFragment<TType>(
|
||||
_documentNode: DocumentTypeDecoration<TType, any>,
|
||||
fragmentType:
|
||||
| ReadonlyArray<FragmentType<DocumentTypeDecoration<TType, any>>>
|
||||
| null
|
||||
| undefined,
|
||||
): ReadonlyArray<TType> | null | undefined;
|
||||
export function useFragment<TType>(
|
||||
_documentNode: DocumentTypeDecoration<TType, any>,
|
||||
fragmentType:
|
||||
| FragmentType<DocumentTypeDecoration<TType, any>>
|
||||
| Array<FragmentType<DocumentTypeDecoration<TType, any>>>
|
||||
| ReadonlyArray<FragmentType<DocumentTypeDecoration<TType, any>>>
|
||||
| null
|
||||
| undefined,
|
||||
): TType | Array<TType> | ReadonlyArray<TType> | null | undefined {
|
||||
return fragmentType as any;
|
||||
}
|
||||
|
||||
export function makeFragmentData<
|
||||
F extends DocumentTypeDecoration<any, any>,
|
||||
FT extends ResultOf<F>,
|
||||
>(data: FT, _fragment: F): FragmentType<F> {
|
||||
return data as FragmentType<F>;
|
||||
}
|
||||
export function isFragmentReady<TQuery, TFrag>(
|
||||
queryNode: DocumentTypeDecoration<TQuery, any>,
|
||||
fragmentNode: TypedDocumentNode<TFrag>,
|
||||
data:
|
||||
| FragmentType<TypedDocumentNode<Incremental<TFrag>, any>>
|
||||
| null
|
||||
| undefined,
|
||||
): data is FragmentType<typeof fragmentNode> {
|
||||
const deferredFields = (
|
||||
queryNode as {
|
||||
__meta__?: { deferredFields: Record<string, (keyof TFrag)[]> };
|
||||
}
|
||||
).__meta__?.deferredFields;
|
||||
|
||||
if (!deferredFields) return true;
|
||||
|
||||
const fragDef = fragmentNode.definitions[0] as
|
||||
| FragmentDefinitionNode
|
||||
| undefined;
|
||||
const fragName = fragDef?.name?.value;
|
||||
|
||||
const fields = (fragName && deferredFields[fragName]) || [];
|
||||
return fields.length > 0 && fields.every((field) => data && field in data);
|
||||
}
|
||||
51
examples/guides/codegen-nhost/src/lib/graphql/__generated__/gql.ts
generated
Normal file
51
examples/guides/codegen-nhost/src/lib/graphql/__generated__/gql.ts
generated
Normal file
@@ -0,0 +1,51 @@
|
||||
/* eslint-disable */
|
||||
|
||||
import type { TypedDocumentNode as DocumentNode } from "@graphql-typed-document-node/core";
|
||||
import * as types from "./graphql";
|
||||
|
||||
/**
|
||||
* Map of all GraphQL operations in the project.
|
||||
*
|
||||
* This map has several performance disadvantages:
|
||||
* 1. It is not tree-shakeable, so it will include all operations in the project.
|
||||
* 2. It is not minifiable, so the string of a GraphQL query will be multiple times inside the bundle.
|
||||
* 3. It does not support dead code elimination, so it will add unused operations.
|
||||
*
|
||||
* Therefore it is highly recommended to use the babel or swc plugin for production.
|
||||
* Learn more about it here: https://the-guild.dev/graphql/codegen/plugins/presets/preset-client#reducing-bundle-size
|
||||
*/
|
||||
type Documents = {
|
||||
"query GetNinjaTurtlesWithComments {\n ninjaTurtles {\n id\n name\n description\n createdAt\n updatedAt\n comments {\n id\n comment\n createdAt\n user {\n id\n displayName\n email\n }\n }\n }\n}\n\nmutation AddComment($ninjaTurtleId: uuid!, $comment: String!) {\n insertComment(object: {ninjaTurtleId: $ninjaTurtleId, comment: $comment}) {\n id\n comment\n createdAt\n ninjaTurtleId\n }\n}": typeof types.GetNinjaTurtlesWithCommentsDocument;
|
||||
};
|
||||
const documents: Documents = {
|
||||
"query GetNinjaTurtlesWithComments {\n ninjaTurtles {\n id\n name\n description\n createdAt\n updatedAt\n comments {\n id\n comment\n createdAt\n user {\n id\n displayName\n email\n }\n }\n }\n}\n\nmutation AddComment($ninjaTurtleId: uuid!, $comment: String!) {\n insertComment(object: {ninjaTurtleId: $ninjaTurtleId, comment: $comment}) {\n id\n comment\n createdAt\n ninjaTurtleId\n }\n}":
|
||||
types.GetNinjaTurtlesWithCommentsDocument,
|
||||
};
|
||||
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* const query = graphql(`query GetUser($id: ID!) { user(id: $id) { name } }`);
|
||||
* ```
|
||||
*
|
||||
* The query argument is unknown!
|
||||
* Please regenerate the types.
|
||||
*/
|
||||
export function graphql(source: string): unknown;
|
||||
|
||||
/**
|
||||
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
|
||||
*/
|
||||
export function graphql(
|
||||
source: "query GetNinjaTurtlesWithComments {\n ninjaTurtles {\n id\n name\n description\n createdAt\n updatedAt\n comments {\n id\n comment\n createdAt\n user {\n id\n displayName\n email\n }\n }\n }\n}\n\nmutation AddComment($ninjaTurtleId: uuid!, $comment: String!) {\n insertComment(object: {ninjaTurtleId: $ninjaTurtleId, comment: $comment}) {\n id\n comment\n createdAt\n ninjaTurtleId\n }\n}",
|
||||
): (typeof documents)["query GetNinjaTurtlesWithComments {\n ninjaTurtles {\n id\n name\n description\n createdAt\n updatedAt\n comments {\n id\n comment\n createdAt\n user {\n id\n displayName\n email\n }\n }\n }\n}\n\nmutation AddComment($ninjaTurtleId: uuid!, $comment: String!) {\n insertComment(object: {ninjaTurtleId: $ninjaTurtleId, comment: $comment}) {\n id\n comment\n createdAt\n ninjaTurtleId\n }\n}"];
|
||||
|
||||
export function graphql(source: string) {
|
||||
return (documents as any)[source] ?? {};
|
||||
}
|
||||
|
||||
export type DocumentType<TDocumentNode extends DocumentNode<any, any>> =
|
||||
TDocumentNode extends DocumentNode<infer TType, any> ? TType : never;
|
||||
7026
examples/guides/codegen-nhost/src/lib/graphql/__generated__/graphql.ts
generated
Normal file
7026
examples/guides/codegen-nhost/src/lib/graphql/__generated__/graphql.ts
generated
Normal file
File diff suppressed because it is too large
Load Diff
2
examples/guides/codegen-nhost/src/lib/graphql/__generated__/index.ts
generated
Normal file
2
examples/guides/codegen-nhost/src/lib/graphql/__generated__/index.ts
generated
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from "./fragment-masking";
|
||||
export * from "./gql";
|
||||
@@ -0,0 +1,28 @@
|
||||
query GetNinjaTurtlesWithComments {
|
||||
ninjaTurtles {
|
||||
id
|
||||
name
|
||||
description
|
||||
createdAt
|
||||
updatedAt
|
||||
comments {
|
||||
id
|
||||
comment
|
||||
createdAt
|
||||
user {
|
||||
id
|
||||
displayName
|
||||
email
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mutation AddComment($ninjaTurtleId: uuid!, $comment: String!) {
|
||||
insertComment(object: { ninjaTurtleId: $ninjaTurtleId, comment: $comment }) {
|
||||
id
|
||||
comment
|
||||
createdAt
|
||||
ninjaTurtleId
|
||||
}
|
||||
}
|
||||
175
examples/guides/codegen-nhost/src/lib/nhost/AuthProvider.tsx
Normal file
175
examples/guides/codegen-nhost/src/lib/nhost/AuthProvider.tsx
Normal file
@@ -0,0 +1,175 @@
|
||||
import { createClient, type NhostClient } from "@nhost/nhost-js";
|
||||
import type { Session } from "@nhost/nhost-js/auth";
|
||||
import {
|
||||
createContext,
|
||||
type ReactNode,
|
||||
useCallback,
|
||||
useContext,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
} from "react";
|
||||
|
||||
/**
|
||||
* Authentication context interface providing access to user session state and Nhost client.
|
||||
* Used throughout the React application to access authentication-related data and operations.
|
||||
*/
|
||||
interface AuthContextType {
|
||||
/** Current authenticated user object, null if not authenticated */
|
||||
user: Session["user"] | null;
|
||||
/** Current session object containing tokens and user data, null if no active session */
|
||||
session: Session | null;
|
||||
/** Boolean indicating if user is currently authenticated */
|
||||
isAuthenticated: boolean;
|
||||
/** Boolean indicating if authentication state is still loading */
|
||||
isLoading: boolean;
|
||||
/** Nhost client instance for making authenticated requests */
|
||||
nhost: NhostClient;
|
||||
}
|
||||
|
||||
// Create React context for authentication state and nhost client
|
||||
const AuthContext = createContext<AuthContextType | null>(null);
|
||||
|
||||
interface AuthProviderProps {
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* AuthProvider component that provides authentication context to the React application.
|
||||
*
|
||||
* This component handles:
|
||||
* - Initializing the Nhost client with default EventEmitterStorage
|
||||
* - Managing authentication state (user, session, loading, authenticated status)
|
||||
* - Cross-tab session synchronization using sessionStorage.onChange events
|
||||
* - Page visibility and focus event handling to maintain session consistency
|
||||
* - Client-side only session management (no server-side rendering)
|
||||
*/
|
||||
export const AuthProvider = ({ children }: AuthProviderProps) => {
|
||||
const [user, setUser] = useState<Session["user"] | null>(null);
|
||||
const [session, setSession] = useState<Session | null>(null);
|
||||
const [isLoading, setIsLoading] = useState<boolean>(true);
|
||||
const [isAuthenticated, setIsAuthenticated] = useState<boolean>(false);
|
||||
const lastRefreshTokenIdRef = useRef<string | null>(null);
|
||||
|
||||
// Initialize Nhost client with default SessionStorage (local storage)
|
||||
const nhost = useMemo(
|
||||
() =>
|
||||
createClient({
|
||||
region: import.meta.env.VITE_NHOST_REGION || "local",
|
||||
subdomain: import.meta.env.VITE_NHOST_SUBDOMAIN || "local",
|
||||
}),
|
||||
[],
|
||||
);
|
||||
|
||||
/**
|
||||
* Handles session reload when refresh token changes.
|
||||
* This detects when the session has been updated from other tabs.
|
||||
* Unlike the Next.js version, this only updates local state without server synchronization.
|
||||
*
|
||||
* @param currentRefreshTokenId - The current refresh token ID to compare against stored value
|
||||
*/
|
||||
const reloadSession = useCallback(
|
||||
(currentRefreshTokenId: string | null) => {
|
||||
if (currentRefreshTokenId !== lastRefreshTokenIdRef.current) {
|
||||
lastRefreshTokenIdRef.current = currentRefreshTokenId;
|
||||
|
||||
// Update local authentication state to match current session
|
||||
const currentSession = nhost.getUserSession();
|
||||
setUser(currentSession?.user || null);
|
||||
setSession(currentSession);
|
||||
setIsAuthenticated(!!currentSession);
|
||||
}
|
||||
},
|
||||
[nhost],
|
||||
);
|
||||
|
||||
// Initialize authentication state and set up cross-tab session synchronization
|
||||
useEffect(() => {
|
||||
setIsLoading(true);
|
||||
|
||||
// Load initial session state from Nhost client
|
||||
const currentSession = nhost.getUserSession();
|
||||
setUser(currentSession?.user || null);
|
||||
setSession(currentSession);
|
||||
setIsAuthenticated(!!currentSession);
|
||||
lastRefreshTokenIdRef.current = currentSession?.refreshTokenId ?? null;
|
||||
setIsLoading(false);
|
||||
|
||||
// Subscribe to session changes from other browser tabs
|
||||
// This enables real-time synchronization when user signs in/out in another tab
|
||||
const unsubscribe = nhost.sessionStorage.onChange((session) => {
|
||||
reloadSession(session?.refreshTokenId ?? null);
|
||||
});
|
||||
|
||||
return unsubscribe;
|
||||
}, [nhost, reloadSession]);
|
||||
|
||||
// Handle session changes from page focus events (for additional session consistency)
|
||||
useEffect(() => {
|
||||
/**
|
||||
* Checks for session changes when page becomes visible or focused.
|
||||
* In the React SPA context, this provides additional consistency checks
|
||||
* though it's less critical than in the Next.js SSR version.
|
||||
*/
|
||||
const checkSessionOnFocus = () => {
|
||||
reloadSession(nhost.getUserSession()?.refreshTokenId ?? null);
|
||||
};
|
||||
|
||||
// Monitor page visibility changes (tab switching, window minimizing)
|
||||
document.addEventListener("visibilitychange", () => {
|
||||
if (!document.hidden) {
|
||||
checkSessionOnFocus();
|
||||
}
|
||||
});
|
||||
|
||||
// Monitor window focus events (clicking back into the browser window)
|
||||
window.addEventListener("focus", checkSessionOnFocus);
|
||||
|
||||
// Cleanup event listeners on component unmount
|
||||
return () => {
|
||||
document.removeEventListener("visibilitychange", checkSessionOnFocus);
|
||||
window.removeEventListener("focus", checkSessionOnFocus);
|
||||
};
|
||||
}, [nhost, reloadSession]);
|
||||
|
||||
const value: AuthContextType = {
|
||||
user,
|
||||
session,
|
||||
isAuthenticated,
|
||||
isLoading,
|
||||
nhost,
|
||||
};
|
||||
|
||||
return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
|
||||
};
|
||||
|
||||
/**
|
||||
* Custom hook to access the authentication context.
|
||||
*
|
||||
* Must be used within a component wrapped by AuthProvider.
|
||||
* Provides access to current user session, authentication state, and Nhost client.
|
||||
*
|
||||
* @throws {Error} When used outside of AuthProvider
|
||||
* @returns {AuthContextType} Authentication context containing user, session, and client
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* function MyComponent() {
|
||||
* const { user, isAuthenticated, nhost } = useAuth();
|
||||
*
|
||||
* if (!isAuthenticated) {
|
||||
* return <div>Please sign in</div>;
|
||||
* }
|
||||
*
|
||||
* return <div>Welcome, {user?.displayName}!</div>;
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
export const useAuth = (): AuthContextType => {
|
||||
const context = useContext(AuthContext);
|
||||
if (!context) {
|
||||
throw new Error("useAuth must be used within an AuthProvider");
|
||||
}
|
||||
return context;
|
||||
};
|
||||
19
examples/guides/codegen-nhost/src/main.tsx
Normal file
19
examples/guides/codegen-nhost/src/main.tsx
Normal file
@@ -0,0 +1,19 @@
|
||||
import React from "react";
|
||||
import { createRoot } from "react-dom/client";
|
||||
import "./index.css";
|
||||
import App from "./App";
|
||||
import { AuthProvider } from "./lib/nhost/AuthProvider";
|
||||
|
||||
// Root component that sets up providers
|
||||
const Root = () => (
|
||||
<React.StrictMode>
|
||||
<AuthProvider>
|
||||
<App />
|
||||
</AuthProvider>
|
||||
</React.StrictMode>
|
||||
);
|
||||
|
||||
const rootElement = document.getElementById("root");
|
||||
if (!rootElement) throw new Error("Root element not found");
|
||||
|
||||
createRoot(rootElement).render(<Root />);
|
||||
217
examples/guides/codegen-nhost/src/pages/Home.css
Normal file
217
examples/guides/codegen-nhost/src/pages/Home.css
Normal file
@@ -0,0 +1,217 @@
|
||||
/* Custom styles for Ninja Turtles tabs interface */
|
||||
.ninja-turtles-container {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.ninja-turtles-title {
|
||||
text-align: center;
|
||||
margin-bottom: 25px;
|
||||
color: #1a9c44;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
/* Tab navigation */
|
||||
.turtle-tabs {
|
||||
display: flex;
|
||||
border-bottom: 2px solid #1a9c44;
|
||||
margin-bottom: 20px;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.turtle-tab {
|
||||
padding: 10px 20px;
|
||||
margin-right: 5px;
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
font-weight: 600;
|
||||
color: var(--text-secondary);
|
||||
transition: all 0.3s ease;
|
||||
border-top-left-radius: 6px;
|
||||
border-top-right-radius: 6px;
|
||||
position: relative;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.turtle-tab:hover {
|
||||
color: var(--text-primary);
|
||||
background: rgba(26, 156, 68, 0.1);
|
||||
}
|
||||
|
||||
.turtle-tab.active {
|
||||
color: white;
|
||||
background: #1a9c44;
|
||||
}
|
||||
|
||||
/* Turtle Card Styles */
|
||||
.turtle-card {
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
transition: all 0.3s ease;
|
||||
animation: fadeIn 0.5s;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
.turtle-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.turtle-name {
|
||||
color: #1a9c44;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.turtle-description {
|
||||
margin-bottom: 20px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.turtle-date {
|
||||
font-size: 0.85rem;
|
||||
margin-bottom: 20px;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
/* Comments section */
|
||||
.comments-section {
|
||||
margin-top: 25px;
|
||||
border-top: 1px solid var(--border-color);
|
||||
padding-top: 15px;
|
||||
}
|
||||
|
||||
.comments-title {
|
||||
font-size: 1.1rem;
|
||||
font-weight: 600;
|
||||
margin-bottom: 15px;
|
||||
color: #1a9c44;
|
||||
}
|
||||
|
||||
.comment-card {
|
||||
margin-bottom: 15px;
|
||||
padding: 12px;
|
||||
border-radius: 6px;
|
||||
background-color: rgba(26, 156, 68, 0.05);
|
||||
border: 1px solid rgba(26, 156, 68, 0.1);
|
||||
}
|
||||
|
||||
.comment-text {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.comment-meta {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 0.8rem;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
.comment-avatar {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 50%;
|
||||
background-color: #1a9c44;
|
||||
color: white;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 0.75rem;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
/* Comment form */
|
||||
.comment-form {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.comment-textarea {
|
||||
width: 100%;
|
||||
background-color: rgba(31, 41, 55, 0.8);
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 6px;
|
||||
padding: 10px;
|
||||
color: white;
|
||||
transition: all 0.2s;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.comment-textarea:focus {
|
||||
border-color: #1a9c44;
|
||||
box-shadow: 0 0 0 2px rgba(26, 156, 68, 0.2);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.comment-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.cancel-button {
|
||||
background-color: transparent;
|
||||
border: 1px solid var(--border-color);
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.cancel-button:hover {
|
||||
background-color: rgba(31, 41, 55, 0.8);
|
||||
}
|
||||
|
||||
.submit-button {
|
||||
background-color: #1a9c44;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.submit-button:hover {
|
||||
background-color: #148035;
|
||||
}
|
||||
|
||||
.add-comment-button {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
color: #1a9c44;
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 5px 0;
|
||||
font-size: 0.9rem;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.add-comment-button:hover {
|
||||
color: #148035;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.add-comment-button svg {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
/* Responsive adjustments */
|
||||
@media (max-width: 640px) {
|
||||
.turtle-tabs {
|
||||
flex-wrap: nowrap;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.turtle-tab {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
}
|
||||
237
examples/guides/codegen-nhost/src/pages/Home.tsx
Normal file
237
examples/guides/codegen-nhost/src/pages/Home.tsx
Normal file
@@ -0,0 +1,237 @@
|
||||
import { type JSX, useCallback, useEffect, useState } from "react";
|
||||
import {
|
||||
AddCommentDocument,
|
||||
GetNinjaTurtlesWithCommentsDocument,
|
||||
type GetNinjaTurtlesWithCommentsQuery,
|
||||
} from "../lib/graphql/__generated__/graphql";
|
||||
import { useAuth } from "../lib/nhost/AuthProvider";
|
||||
import "./Home.css";
|
||||
|
||||
export default function Home(): JSX.Element {
|
||||
const { isLoading, nhost } = useAuth();
|
||||
const [activeCommentId, setActiveCommentId] = useState<string | null>(null);
|
||||
const [commentText, setCommentText] = useState("");
|
||||
const [activeTabId, setActiveTabId] = useState<string | null>(null);
|
||||
|
||||
const [data, setData] = useState<GetNinjaTurtlesWithCommentsQuery | null>(
|
||||
null,
|
||||
);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState<Error | null>(null);
|
||||
|
||||
// Fetch ninja turtles data
|
||||
const fetchNinjaTurtles = useCallback(async () => {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
try {
|
||||
const result = await nhost.graphql.request(
|
||||
GetNinjaTurtlesWithCommentsDocument,
|
||||
{},
|
||||
);
|
||||
|
||||
if (result.body.errors) {
|
||||
throw new Error(result.body.errors[0]?.message);
|
||||
}
|
||||
|
||||
setData(result.body.data ?? null);
|
||||
} catch (err) {
|
||||
setError(err as Error);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, [nhost.graphql]);
|
||||
|
||||
// Load data on mount
|
||||
useEffect(() => {
|
||||
if (!isLoading) {
|
||||
fetchNinjaTurtles();
|
||||
}
|
||||
}, [isLoading, fetchNinjaTurtles]);
|
||||
|
||||
const addComment = async (ninjaTurtleId: string, comment: string) => {
|
||||
try {
|
||||
const result = await nhost.graphql.request(AddCommentDocument, {
|
||||
ninjaTurtleId,
|
||||
comment,
|
||||
});
|
||||
|
||||
if (result.body.errors) {
|
||||
throw new Error(result.body.errors[0]?.message);
|
||||
}
|
||||
|
||||
// Clear form and refetch data
|
||||
setCommentText("");
|
||||
setActiveCommentId(null);
|
||||
await fetchNinjaTurtles();
|
||||
} catch (err) {
|
||||
console.error("Error adding comment:", err);
|
||||
}
|
||||
};
|
||||
|
||||
// If authentication is still loading, show a loading state
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className="loading-container">
|
||||
<p>Loading...</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const handleAddComment = (turtleId: string) => {
|
||||
if (!commentText.trim()) return;
|
||||
|
||||
addComment(turtleId, commentText);
|
||||
};
|
||||
|
||||
if (loading)
|
||||
return (
|
||||
<div className="loading-container">
|
||||
<p>Loading ninja turtles...</p>
|
||||
</div>
|
||||
);
|
||||
if (error)
|
||||
return (
|
||||
<div className="alert alert-error">
|
||||
Error loading ninja turtles: {(error as Error).message}
|
||||
</div>
|
||||
);
|
||||
|
||||
// Access the data using the correct field name from the GraphQL response
|
||||
const ninjaTurtles = data?.ninjaTurtles || [];
|
||||
if (!ninjaTurtles || ninjaTurtles.length === 0) {
|
||||
return (
|
||||
<div className="no-turtles-container">
|
||||
<p>No ninja turtles found. Please add some!</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// Set the active tab to the first turtle if there's no active tab and there are turtles
|
||||
if (activeTabId === null) {
|
||||
setActiveTabId(ninjaTurtles[0] ? ninjaTurtles[0].id : null);
|
||||
}
|
||||
|
||||
const formatDate = (dateString: string) => {
|
||||
const date = new Date(dateString);
|
||||
return `${date.toLocaleDateString()} ${date.toLocaleTimeString()}`;
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="ninja-turtles-container">
|
||||
<h1 className="ninja-turtles-title text-3xl font-bold mb-6">
|
||||
Teenage Mutant Ninja Turtles
|
||||
</h1>
|
||||
|
||||
{/* Tabs navigation */}
|
||||
<div className="turtle-tabs">
|
||||
{ninjaTurtles.map((turtle) => (
|
||||
<button
|
||||
key={turtle.id}
|
||||
type="button"
|
||||
className={`turtle-tab ${activeTabId === turtle.id ? "active" : ""}`}
|
||||
onClick={() => setActiveTabId(turtle.id)}
|
||||
>
|
||||
{turtle.name}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Display active turtle */}
|
||||
{ninjaTurtles
|
||||
.filter((turtle) => turtle.id === activeTabId)
|
||||
.map((turtle) => (
|
||||
<div key={turtle.id} className="turtle-card glass-card p-6">
|
||||
<div className="turtle-header">
|
||||
<h2 className="turtle-name text-2xl font-semibold">
|
||||
{turtle.name}
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<p className="turtle-description">{turtle.description}</p>
|
||||
|
||||
<div className="turtle-date">
|
||||
Added on {formatDate(turtle.createdAt || turtle.createdAt)}
|
||||
</div>
|
||||
|
||||
<div className="comments-section">
|
||||
<h3 className="comments-title">
|
||||
Comments ({turtle.comments.length})
|
||||
</h3>
|
||||
|
||||
{turtle.comments.map((comment) => (
|
||||
<div key={comment.id} className="comment-card">
|
||||
<p className="comment-text">{comment.comment}</p>
|
||||
<div className="comment-meta">
|
||||
<div className="comment-avatar">
|
||||
{(comment.user?.displayName || comment.user?.email || "?")
|
||||
.charAt(0)
|
||||
.toUpperCase()}
|
||||
</div>
|
||||
<p>
|
||||
{comment.user?.displayName ||
|
||||
comment.user?.email ||
|
||||
"Anonymous"}{" "}
|
||||
- {formatDate(comment.createdAt || comment.createdAt)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
|
||||
{activeCommentId === turtle.id ? (
|
||||
<div className="comment-form">
|
||||
<textarea
|
||||
className="comment-textarea"
|
||||
value={commentText}
|
||||
onChange={(e) => setCommentText(e.target.value)}
|
||||
placeholder="Add your comment..."
|
||||
rows={3}
|
||||
/>
|
||||
<div className="comment-actions">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
setActiveCommentId(null);
|
||||
setCommentText("");
|
||||
}}
|
||||
className="btn cancel-button"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => handleAddComment(turtle.id)}
|
||||
className="btn submit-button"
|
||||
>
|
||||
Submit
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setActiveCommentId(turtle.id)}
|
||||
className="add-comment-button"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
aria-label="Add Comment"
|
||||
role="img"
|
||||
>
|
||||
<line x1="12" y1="5" x2="12" y2="19"></line>
|
||||
<line x1="5" y1="12" x2="19" y2="12"></line>
|
||||
</svg>
|
||||
Add a comment
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
66
examples/guides/codegen-nhost/src/pages/Profile.tsx
Normal file
66
examples/guides/codegen-nhost/src/pages/Profile.tsx
Normal file
@@ -0,0 +1,66 @@
|
||||
import type { JSX } from "react";
|
||||
import { useAuth } from "../lib/nhost/AuthProvider";
|
||||
|
||||
export default function Profile(): JSX.Element {
|
||||
const { user, session } = useAuth();
|
||||
|
||||
// ProtectedRoute component now handles authentication check
|
||||
// We can just focus on the component logic here
|
||||
|
||||
return (
|
||||
<div className="flex flex-col">
|
||||
<h1 className="text-3xl mb-6 gradient-text">Your Profile</h1>
|
||||
|
||||
<div className="glass-card p-8 mb-6">
|
||||
<div className="space-y-5">
|
||||
<div className="profile-item">
|
||||
<strong>Display Name:</strong>
|
||||
<span className="ml-2">{user?.displayName || "Not set"}</span>
|
||||
</div>
|
||||
|
||||
<div className="profile-item">
|
||||
<strong>Email:</strong>
|
||||
<span className="ml-2">{user?.email || "Not available"}</span>
|
||||
</div>
|
||||
|
||||
<div className="profile-item">
|
||||
<strong>User ID:</strong>
|
||||
<span
|
||||
className="ml-2"
|
||||
style={{
|
||||
fontFamily: "var(--font-geist-mono)",
|
||||
fontSize: "0.875rem",
|
||||
}}
|
||||
>
|
||||
{user?.id || "Not available"}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="profile-item">
|
||||
<strong>Roles:</strong>
|
||||
<span className="ml-2">{user?.roles?.join(", ") || "None"}</span>
|
||||
</div>
|
||||
|
||||
<div className="profile-item">
|
||||
<strong>Email Verified:</strong>
|
||||
<span className="ml-2">{user?.emailVerified ? "Yes" : "No"}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="glass-card p-8 mb-6">
|
||||
<h3 className="text-xl mb-4">Session Information</h3>
|
||||
<pre>
|
||||
{JSON.stringify(
|
||||
{
|
||||
refreshTokenId: session?.refreshTokenId,
|
||||
accessTokenExpiresIn: session?.accessTokenExpiresIn,
|
||||
},
|
||||
null,
|
||||
2,
|
||||
)}
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
120
examples/guides/codegen-nhost/src/pages/SignIn.tsx
Normal file
120
examples/guides/codegen-nhost/src/pages/SignIn.tsx
Normal file
@@ -0,0 +1,120 @@
|
||||
import type { ErrorResponse } from "@nhost/nhost-js/auth";
|
||||
import type { FetchError } from "@nhost/nhost-js/fetch";
|
||||
import { type JSX, useEffect, useId, useState } from "react";
|
||||
import { Link, useLocation, useNavigate } from "react-router-dom";
|
||||
import { useAuth } from "../lib/nhost/AuthProvider";
|
||||
|
||||
export default function SignIn(): JSX.Element {
|
||||
const { nhost, isAuthenticated } = useAuth();
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
const params = new URLSearchParams(location.search);
|
||||
const emailId = useId();
|
||||
const passwordId = useId();
|
||||
|
||||
const [email, setEmail] = useState("");
|
||||
const [password, setPassword] = useState("");
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [error, setError] = useState<string | null>(
|
||||
params.get("error") || null,
|
||||
);
|
||||
|
||||
const isVerifying = params.has("fromVerify");
|
||||
|
||||
// Use useEffect for navigation after authentication is confirmed
|
||||
useEffect(() => {
|
||||
if (isAuthenticated && !isVerifying) {
|
||||
navigate("/home");
|
||||
}
|
||||
}, [isAuthenticated, isVerifying, navigate]);
|
||||
|
||||
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
|
||||
e.preventDefault();
|
||||
setIsLoading(true);
|
||||
setError(null);
|
||||
|
||||
try {
|
||||
// Use the signIn function from auth context
|
||||
const response = await nhost.auth.signInEmailPassword({
|
||||
email,
|
||||
password,
|
||||
});
|
||||
|
||||
// Check if MFA is required
|
||||
if (response.body?.mfa) {
|
||||
navigate(`/signin/mfa?ticket=${response.body.mfa.ticket}`);
|
||||
return;
|
||||
}
|
||||
|
||||
// If we have a session, sign in was successful
|
||||
if (response.body?.session) {
|
||||
navigate("/home");
|
||||
} else {
|
||||
setError("Failed to sign in");
|
||||
}
|
||||
} catch (err) {
|
||||
const error = err as FetchError<ErrorResponse>;
|
||||
setError(`An error occurred during sign in: ${error.message}`);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex flex-col items-center justify-center">
|
||||
<h1 className="text-3xl mb-6 gradient-text">Nhost SDK Demo</h1>
|
||||
|
||||
<div className="glass-card w-full p-8 mb-6">
|
||||
<h2 className="text-2xl mb-6">Sign In</h2>
|
||||
<div>
|
||||
<div className="tabs-container">
|
||||
<button type="button" className="tab-button tab-active">
|
||||
Email + Password
|
||||
</button>
|
||||
</div>
|
||||
<div className="tab-content">
|
||||
<form onSubmit={handleSubmit} className="space-y-5">
|
||||
<div>
|
||||
<label htmlFor={emailId}>Email</label>
|
||||
<input
|
||||
id={emailId}
|
||||
type="email"
|
||||
value={email}
|
||||
onChange={(e) => setEmail(e.target.value)}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label htmlFor={passwordId}>Password</label>
|
||||
<input
|
||||
id={passwordId}
|
||||
type="password"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
{error && <div className="alert alert-error">{error}</div>}
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
className="btn btn-primary w-full"
|
||||
disabled={isLoading}
|
||||
>
|
||||
{isLoading ? "Signing In..." : "Sign In"}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-4">
|
||||
<p>
|
||||
Don't have an account? <Link to="/signup">Sign Up</Link>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
127
examples/guides/codegen-nhost/src/pages/SignUp.tsx
Normal file
127
examples/guides/codegen-nhost/src/pages/SignUp.tsx
Normal file
@@ -0,0 +1,127 @@
|
||||
import type { ErrorResponse } from "@nhost/nhost-js/auth";
|
||||
import type { FetchError } from "@nhost/nhost-js/fetch";
|
||||
import { type JSX, useId, useState } from "react";
|
||||
import { Link, Navigate, useNavigate } from "react-router-dom";
|
||||
import { useAuth } from "../lib/nhost/AuthProvider";
|
||||
|
||||
export default function SignUp(): JSX.Element {
|
||||
const { nhost, isAuthenticated } = useAuth();
|
||||
const navigate = useNavigate();
|
||||
const displayNameId = useId();
|
||||
const emailId = useId();
|
||||
const passwordId = useId();
|
||||
|
||||
const [email, setEmail] = useState<string>("");
|
||||
const [password, setPassword] = useState<string>("");
|
||||
const [displayName, setDisplayName] = useState<string>("");
|
||||
const [isLoading, setIsLoading] = useState<boolean>(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
// If already authenticated, redirect to profile
|
||||
if (isAuthenticated) {
|
||||
return <Navigate to="/home" />;
|
||||
}
|
||||
|
||||
const handleSubmit = async (
|
||||
e: React.FormEvent<HTMLFormElement>,
|
||||
): Promise<void> => {
|
||||
e.preventDefault();
|
||||
setIsLoading(true);
|
||||
setError(null);
|
||||
|
||||
try {
|
||||
const response = await nhost.auth.signUpEmailPassword({
|
||||
email,
|
||||
password,
|
||||
options: {
|
||||
displayName,
|
||||
},
|
||||
});
|
||||
|
||||
if (response.body) {
|
||||
// Successfully signed up and automatically signed in
|
||||
navigate("/home");
|
||||
} else {
|
||||
// Verification email sent
|
||||
navigate("/verify");
|
||||
}
|
||||
} catch (err) {
|
||||
const error = err as FetchError<ErrorResponse>;
|
||||
setError(`An error occurred during sign up: ${error.message}`);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex flex-col items-center justify-center">
|
||||
<h1 className="text-3xl mb-6 gradient-text">Nhost SDK Demo</h1>
|
||||
|
||||
<div className="glass-card w-full p-8 mb-6">
|
||||
<h2 className="text-2xl mb-6">Sign Up</h2>
|
||||
|
||||
<div>
|
||||
<div className="tabs-container">
|
||||
<button type="button" className="tab-button tab-active">
|
||||
Email + Password
|
||||
</button>
|
||||
</div>
|
||||
<div className="tab-content">
|
||||
<form onSubmit={handleSubmit} className="space-y-5">
|
||||
<div>
|
||||
<label htmlFor={displayNameId}>Display Name</label>
|
||||
<input
|
||||
id={displayNameId}
|
||||
type="text"
|
||||
value={displayName}
|
||||
onChange={(e) => setDisplayName(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label htmlFor={emailId}>Email</label>
|
||||
<input
|
||||
id={emailId}
|
||||
type="email"
|
||||
value={email}
|
||||
onChange={(e) => setEmail(e.target.value)}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label htmlFor={passwordId}>Password</label>
|
||||
<input
|
||||
id={passwordId}
|
||||
type="password"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
required
|
||||
/>
|
||||
<p className="text-xs mt-1 text-gray-400">
|
||||
Password must be at least 8 characters long
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{error && <div className="alert alert-error">{error}</div>}
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
className="btn btn-primary w-full"
|
||||
disabled={isLoading}
|
||||
>
|
||||
{isLoading ? "Signing Up..." : "Sign Up"}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-4">
|
||||
<p>
|
||||
Already have an account? <Link to="/signin">Sign In</Link>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
11
examples/guides/codegen-nhost/src/vite-env.d.ts
vendored
Normal file
11
examples/guides/codegen-nhost/src/vite-env.d.ts
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
/// <reference types="vite/client" />
|
||||
|
||||
interface ImportMetaEnv {
|
||||
readonly VITE_NHOST_REGION: string | undefined;
|
||||
readonly VITE_NHOST_SUBDOMAIN: string | undefined;
|
||||
readonly VITE_ENV: string | undefined;
|
||||
}
|
||||
|
||||
interface ImportMeta {
|
||||
readonly env: ImportMetaEnv;
|
||||
}
|
||||
6
examples/guides/codegen-nhost/tsconfig.json
Normal file
6
examples/guides/codegen-nhost/tsconfig.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/tsconfig",
|
||||
"extends": "../../../build/configs/tsconfig/frontend.json",
|
||||
"include": ["./src/**/*.ts", "./src/**/*.tsx"],
|
||||
"references": [{ "path": "./tsconfig.node.json" }]
|
||||
}
|
||||
4
examples/guides/codegen-nhost/tsconfig.node.json
Normal file
4
examples/guides/codegen-nhost/tsconfig.node.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/tsconfig",
|
||||
"extends": "../../../build/configs/tsconfig/vite.json"
|
||||
}
|
||||
7
examples/guides/codegen-nhost/vite.config.ts
Normal file
7
examples/guides/codegen-nhost/vite.config.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import react from "@vitejs/plugin-react";
|
||||
import { defineConfig } from "vite";
|
||||
|
||||
// https://vite.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
});
|
||||
@@ -17,6 +17,8 @@ let
|
||||
"pnpm-lock.yaml"
|
||||
"${submodule}/package.json"
|
||||
"${submodule}/pnpm-lock.yaml"
|
||||
"${submodule}/codegen-nhost/package.json"
|
||||
"${submodule}/codegen-nhost/pnpm-lock.yaml"
|
||||
"${submodule}/react-apollo/package.json"
|
||||
"${submodule}/react-apollo/pnpm-lock.yaml"
|
||||
"${submodule}/react-query/package.json"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "demos/react-apollo",
|
||||
"name": "guides/react-apollo",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "demos/react-query",
|
||||
"name": "guides/react-query",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "demos/react-urql",
|
||||
"name": "guides/react-urql",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
|
||||
13
go.mod
13
go.mod
@@ -13,7 +13,7 @@ require (
|
||||
github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf
|
||||
github.com/charmbracelet/lipgloss v1.1.0
|
||||
github.com/creack/pty v1.1.24
|
||||
github.com/davidbyttow/govips/v2 v2.16.0
|
||||
github.com/cshum/vipsgen v1.2.1
|
||||
github.com/gabriel-vasile/mimetype v1.4.8
|
||||
github.com/getkin/kin-openapi v0.133.0
|
||||
github.com/gin-gonic/gin v1.11.0
|
||||
@@ -43,10 +43,10 @@ require (
|
||||
github.com/vektah/gqlparser/v2 v2.5.30
|
||||
github.com/wI2L/jsondiff v0.7.0
|
||||
go.uber.org/mock v0.5.0
|
||||
golang.org/x/crypto v0.42.0
|
||||
golang.org/x/crypto v0.43.0
|
||||
golang.org/x/mod v0.28.0
|
||||
golang.org/x/oauth2 v0.30.0
|
||||
golang.org/x/term v0.35.0
|
||||
golang.org/x/term v0.36.0
|
||||
gopkg.in/evanphx/json-patch.v5 v5.9.11
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
@@ -179,11 +179,10 @@ require (
|
||||
github.com/yosida95/uritemplate/v3 v3.0.2 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect
|
||||
golang.org/x/arch v0.20.0 // indirect
|
||||
golang.org/x/image v0.18.0 // indirect
|
||||
golang.org/x/net v0.44.0 // indirect
|
||||
golang.org/x/net v0.45.0 // indirect
|
||||
golang.org/x/sync v0.17.0 // indirect
|
||||
golang.org/x/sys v0.36.0 // indirect
|
||||
golang.org/x/text v0.29.0 // indirect
|
||||
golang.org/x/sys v0.37.0 // indirect
|
||||
golang.org/x/text v0.30.0 // indirect
|
||||
golang.org/x/time v0.11.0 // indirect
|
||||
golang.org/x/tools v0.37.0 // indirect
|
||||
google.golang.org/protobuf v1.36.9 // indirect
|
||||
|
||||
66
go.sum
66
go.sum
@@ -121,14 +121,14 @@ github.com/cpuguy83/go-md2man/v2 v2.0.7/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6N
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/creack/pty v1.1.24 h1:bJrF4RRfyJnbTJqzRLHzcGaZK1NeM5kTC9jGgovnR1s=
|
||||
github.com/creack/pty v1.1.24/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE=
|
||||
github.com/cshum/vipsgen v1.2.1 h1:Es305Zf7C9T+8QbsiWn3BtQ+2/uHz6sp/SFnvwnO/kU=
|
||||
github.com/cshum/vipsgen v1.2.1/go.mod h1:1GboZQcNmo4NwuNnGogM24m3O+1i6UpnvurqMcsFItE=
|
||||
github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s=
|
||||
github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
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/dgrijalva/jwt-go v0.0.0-20160705203006-01aeca54ebda/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dgryski/trifles v0.0.0-20230903005119-f50d829f2e54 h1:SG7nF6SRlWhcT7cNTs5R6Hk4V2lcmLz2NsG2VnInyNo=
|
||||
github.com/dgryski/trifles v0.0.0-20230903005119-f50d829f2e54/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA=
|
||||
@@ -223,7 +223,6 @@ github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+Licev
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/google/btree v0.0.0-20160524151835-7d79101e329e/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
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-tpm v0.9.3 h1:+yx0/anQuGzi+ssRqeD6WpXjW2L/V0dItUayO0i9sRc=
|
||||
@@ -415,7 +414,6 @@ github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpE
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
@@ -465,7 +463,6 @@ github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJu
|
||||
github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4=
|
||||
github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus=
|
||||
@@ -483,23 +480,14 @@ golang.org/x/arch v0.20.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk=
|
||||
golang.org/x/crypto v0.0.0-20181025213731-e84da0312774/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
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.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||
golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI=
|
||||
golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8=
|
||||
golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04=
|
||||
golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0=
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
|
||||
golang.org/x/image v0.18.0 h1:jGzIakQa/ZXI1I0Fxvaa9W7yP25TqT6cHIHn+6CqvSQ=
|
||||
golang.org/x/image v0.18.0/go.mod h1:4yyo5vMFQjVjUcVk4jEQcU9MGy/rulF5WvUILseCM2E=
|
||||
golang.org/x/mod v0.4.2/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.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U=
|
||||
golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@@ -508,17 +496,12 @@ golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73r
|
||||
golang.org/x/net v0.0.0-20190206173232-65e2d4e15006/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
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.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||
golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I=
|
||||
golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY=
|
||||
golang.org/x/net v0.45.0 h1:RLBg5JKixCy82FtLJpeNlVM0nrSqpCRYzVU1n8kj0tM=
|
||||
golang.org/x/net v0.45.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY=
|
||||
golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
|
||||
golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
|
||||
@@ -526,11 +509,6 @@ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/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.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
|
||||
golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@@ -544,50 +522,31 @@ golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.17.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.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k=
|
||||
golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
|
||||
golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
|
||||
golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
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.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
|
||||
golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ=
|
||||
golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA=
|
||||
golang.org/x/term v0.36.0 h1:zMPR+aF8gfksFprF/Nc/rd1wRS1EI6nDBGyWAvDzx2Q=
|
||||
golang.org/x/term v0.36.0/go.mod h1:Qu394IJq6V6dCBRgwqshf3mPF85AqzYEzofzRdZkWss=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
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.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk=
|
||||
golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4=
|
||||
golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k=
|
||||
golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM=
|
||||
golang.org/x/time v0.0.0-20161028155119-f51c12702a4d/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0=
|
||||
golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
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.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE=
|
||||
golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
@@ -600,7 +559,6 @@ google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXn
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/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-20200227125254-8fa46927fb4f/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/evanphx/json-patch.v5 v5.9.11 h1:OMPeiLomOQwe8+Ku4nwXsdOmrRw2vGUpP3XgLj3ojNw=
|
||||
|
||||
@@ -275,7 +275,8 @@ export type OutputImageFormat =
|
||||
| "jpeg"
|
||||
| "webp"
|
||||
| "png"
|
||||
| "avif";
|
||||
| "avif"
|
||||
| "heic";
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -378,7 +379,7 @@ export interface ListOrphanedFilesResponse200 {
|
||||
|
||||
/**
|
||||
* Parameters for the getFile method.
|
||||
@property q? (number) - Image quality (1-100). Only applies to JPEG, WebP and PNG files
|
||||
@property q? (number) - Image quality (1-100). Only applies to JPEG, WebP, PNG and HEIC files
|
||||
|
||||
@property h? (number) - Maximum height to resize image to while maintaining aspect ratio. Only applies to image files
|
||||
|
||||
@@ -391,7 +392,7 @@ export interface ListOrphanedFilesResponse200 {
|
||||
* Output format for image files. Use 'auto' for content negotiation based on Accept header*/
|
||||
export interface GetFileParams {
|
||||
/**
|
||||
* Image quality (1-100). Only applies to JPEG, WebP and PNG files
|
||||
* Image quality (1-100). Only applies to JPEG, WebP, PNG and HEIC files
|
||||
|
||||
*/
|
||||
q?: number;
|
||||
@@ -419,7 +420,7 @@ export interface GetFileParams {
|
||||
}
|
||||
/**
|
||||
* Parameters for the getFileMetadataHeaders method.
|
||||
@property q? (number) - Image quality (1-100). Only applies to JPEG, WebP and PNG files
|
||||
@property q? (number) - Image quality (1-100). Only applies to JPEG, WebP, PNG and HEIC files
|
||||
|
||||
@property h? (number) - Maximum height to resize image to while maintaining aspect ratio. Only applies to image files
|
||||
|
||||
@@ -432,7 +433,7 @@ export interface GetFileParams {
|
||||
* Output format for image files. Use 'auto' for content negotiation based on Accept header*/
|
||||
export interface GetFileMetadataHeadersParams {
|
||||
/**
|
||||
* Image quality (1-100). Only applies to JPEG, WebP and PNG files
|
||||
* Image quality (1-100). Only applies to JPEG, WebP, PNG and HEIC files
|
||||
|
||||
*/
|
||||
q?: number;
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
## [storage@0.10.0] - 2025-11-19
|
||||
|
||||
### 🚀 Features
|
||||
|
||||
- *(storage)* Added support for images/heic (#3694)
|
||||
|
||||
## [storage@0.9.1] - 2025-11-06
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
@@ -2066,83 +2066,84 @@ func (sh *strictHandler) GetVersion(ctx *gin.Context) {
|
||||
// Base64 encoded, gzipped, json marshaled Swagger object
|
||||
var swaggerSpec = []string{
|
||||
|
||||
"H4sIAAAAAAAC/+xde3PbtrL/KhjezjQ5FSVLjpNzNdO5102c1j1x4ontk86tc2cgciWiIQEWACUrtr/7",
|
||||
"mQXAlwj5FSd1E/3TOhIei90f9oUFdB5EIssFB65VMD4PVJRARs2fe1IK+RZULrgC/IDGMdNMcJoeSpGD",
|
||||
"1AxUMJ7SVEEviEFFkuX4fTC2fQnjUyEzip8RCbqQHGIyWRKdANk93O8HvSBvjHQeAHa701QxaMpS1R0y",
|
||||
"ppquH1HLojPgbtWSYGciIaUaYqKFIdzQ2CNsSihf4nx6mUMwDsTkD4h0cNkLMlCKzgzL2iP/UmSUhxJo",
|
||||
"TCepG4m41jgSnNEsT3GwlywFwoUmU1HwuJ5Eacn4LLi87AUS/iyYhDgY/17N+L5DzaWHvpZg3zGdHEoR",
|
||||
"gVIQ47RqI+q/p6gNO1bk2CbqFVOaiCmZ4tdEJ1STBUggqoiw37RI0yWpBiETmAoJNSeIiKJCSohxAUxD",
|
||||
"Zqb4TsI0GAf/NagVycBpkQHScQCaGsnUUKRS0qUfm60et0PHc5HlEhLgis2BZG6QFjLpRBSaUMMAwjhR",
|
||||
"WkgnkDaUJkX0AfR+3OXh/gvkIPLEtiGR4JoyzvjMfIpDtwVcKJAqtK274u0FkQQE3a7uTnbMMlCaZjlZ",
|
||||
"JMCr8cmCKuK6tecabY22w61hONw5Ho7G20/GO0//L+gFlgPBGLcIhJpl4CMENJ11adjjmukl0XRGpkKS",
|
||||
"iEYJkDlNWWx42p7/NKDDySjajp/AzvTpaeCbhnm4esLZnwUQFgPXbMpAmrn8/Ix34NnTCCbhs2d0FD4Z",
|
||||
"7myHk2cxDYfTZ9FwuDMZTacj77zqJE8FjcEz/7sEdAL1jCShikwAeHtvFG6AFkFWsbjpJkKkQLnVDdfB",
|
||||
"2KeSnhdKi6yGL1VKRMxopQXTiZ8n5wFNUbyHUhjqcxbpQqKQI6phJuQSd92caioD367LWAbH5sNVxhzs",
|
||||
"H+wRbF+ivisPltEZDP7IYebjOqeZZ9jXNGuNSBiP0iLGTQRnGrfwKrJyu7TQLa3/R+6dTrGPnumO2MfV",
|
||||
"6chkqUG15hg92Xn67J+N3cK4fvqknoVxDTMwHCzy+C57NqVKE9d3zcZ9erz13+MnO+Pt0c03bgnLn5Yn",
|
||||
"CuTVWgu1EVkkosLyGqnSSTQcbccwfbLz9FqjxNBuGUk7CfRqDer0SlPPNfnX2pcNJL5fYxyOiiyjiOdb",
|
||||
"2YafqGLRwzcF34pq/KJK4QqsNkDaYIEPem8KnRd6H1XdS7cnkfwpLYziVXa89npsH2IxZ6RmVKV1v/rk",
|
||||
"RAH5nhZafG8Nq+AauCYcZkIzC9IJRT9McLIbRZBrkgCNQSILeJHhYrA77jk7vdPBC5jkCGOO/6BzNsUV",
|
||||
"1UxzjTsgOJSg2IxDfPL21R3Dvud2AyhCSV6ORk7evjILjJmESFvJ4jhmiR43Hs5yZr/0KNcECGpBs2Mh",
|
||||
"EjxWpOCapQY0OJPpvaLYt59ubXm1uEz9U3SJ91BdczTROlfjwaDUIe6bfiSygRH2wGrT/8FBKSL1x7Pl",
|
||||
"x2uRiuT1muzwAfPty+ejf45GL6j27Cj8FFn19uVzgq0cFlvEHxfQI8MR2S1mZLQ12iHD0Xhre7yzRX4+",
|
||||
"OEbhUK1B4mj//+hA8IvjAi7eQXxxnBQXLyW7OKL64qjgj3vk9DQ+H/ZGl+TRr5RfvITJxQGVF7u5vDig",
|
||||
"y4tfC37xa5Fe7BaziyPIL95E+uK1mF+8gOix6frk0vxvdDlu/Y+cni5++K7DrF5wFs5E6D5Eo4vcODF2",
|
||||
"5ROCiLKbjY4iyskESottgEA5gTOmNGqlUgG38Xs3v+/EzRGt+H9a1C7gDTzAchiraZpTtHxBpzi9zuAa",
|
||||
"5QwLgt84gtiMl1Fy1wxJwJZxaL5Zp5M781r9ex+yy6WYM3RtjAdmLRPKixIOizVS85neN7lLDjih7L9o",
|
||||
"216yPzWRezlfj1BycrL/gixYmiJwZsBRY6w6e3a4kMXhcLTtU8X3EzrcEjquu0FOGy2xiIoMuL4NXNZD",
|
||||
"pcs1/EpINmPIa2xjgFYysVBr+Fe27FtLdwOI/RskOhH7tR94VwM3tyN5XEpcjDMERIGcs8jrVLI0dtT4",
|
||||
"TVA5AS+yCcjSLVoZmJhx2swZ9kf97WttS4sAb9pQQVRIppdHUQKZpXq30ImQ7GPFuQlQCbJ0iIJf3x13",
|
||||
"nKDdw33yAZYGC647EKQElDZm1OSKjH9oBqspR6uKQvst/IWqQtJwN84YD48gkuCJu2wjQrER+gYStJkY",
|
||||
"d+yERh+AxwPzJVMa7el81Z4zHKXysCys10xeZ7Jy9i9YBpfIMIQCkmWigMhQCBllKQqhyHMh9f/yRCjd",
|
||||
"Z6Ie/zV+Qo7s94FzSSqHomp/ucpW18/BAZkckt0KFrjmjHI6M1qPx/YLZ7GU1QW5WICcFimhxos3/qcU",
|
||||
"KYloTicsZQaqvSBlEThH0JG8m5sU0Cv7BRn1tzp0LxaLPjXN+kLOBm4MNXi1/3zv9dFeiH1wfzKdgm8x",
|
||||
"QS+Yl5sjGPa3bHORA6c5C8bBtvnI+CaJQaZ1s/CvXCgPOKxtIYKjoiGZkFAmQQWhROUQYWgVu0CuXwpE",
|
||||
"kQnVUdIwIYZ1YsUuVBoX+Q40SmpFV/fMilSzPHUT9wgwE1Y5Ldgeg6apo09IwgU3GqRCK8aiDWuJUnIb",
|
||||
"6icRL0sIor5Gb8RMS6UeoKIKS6tiM7SGYZ5oN/RZw2MqZ6DLWLcRjy4SqPhZKm1UVKtqG6Pf0DJE+awe",
|
||||
"jvD7++7Eu1LSZSNvXeYuWmnoKlMyYZzKpW/8dva5trK+Od9cK+Iqf2JlfVAoTTKDFmvO4lpr24URM/GN",
|
||||
"c+ced8iXQW8qdcdAjzrv6A9z6mCXQFyavIy1LZdRa1Q4r/yR5nzoghgCbKhoFjTaGq7gj+Z5yiKD28Ef",
|
||||
"ypqNdeC76fnFmvOKhnLTCTBZkX1/5xVNbq9Qe1OuK3/exKp4l0+4BQevWs51B30eCvdaBz0kLnDzOCJb",
|
||||
"bkEw/r3jEPz+/vJ9L1Blhq7UulOnpDSdqRKmKniPo7nw+JzFl1bcKfji2EOQGcW1pUti25SZu6kUWZW7",
|
||||
"I8cJU0RCJuagyEQ0PN4qvYK4Zlo18+pNmLSV7AszFzLLGBtJM9AglVn7dVm6ZiJLC0d26Wag4aqdAJOS",
|
||||
"am+sXkPEq57c+86me9JlmdngLaRZCj4/0G4OK8MbQxa2ui26rHDMIB5w9YKZz0t8C1oymIPBQSwW3CAU",
|
||||
"BYXLqgYs4dLwBCLBq8Pi0n/tuThbS8pVFQionhldUj6rXV1jONAOM5pWE6su5H4GfT94c1PcC+J6HfPI",
|
||||
"06U752+kay0FRsZck71jOrMWEf0YXqV25zQtQFXh3zrPm01D0zn4PITFApQJQ63Npnx5e/rQM7tPIpmu",
|
||||
"k+uZiK1LSqfaZd9nbA4crTVcxTPXL1SMR9Ci66od3Ewj3p5i5OMnUV3wz0O3SdiTPwuaMr0kj4bhcGvr",
|
||||
"cZ+Y5Rh1Z/3JXw/3fu6RdzA5NDv38PXPldEyFP9ZgHEpHcF/tsjL6BnLiiwYD7e2egEGmPZf3Yxzl74D",
|
||||
"25ckwGaJRlIkKIyQnV4RZJEgqzPKqqMliuGKJkZndJfSOGJYQ30brHejd8FiNK5fgtzFJ5D7U1pYENpp",
|
||||
"CmWP5pgiis0yarf6XYia+ImqTxls2sa7lT7fqZCP0umNt1L3iMtD/Vtj1MTUHp9bBDiLalyxOstnxxjb",
|
||||
"hj8qTaUOga9Vp2bgFq2Ngwc7xqPT0/iH8PQ0/scF/gf/+uHxo57348f/+M6TA+t6TltX+EAi0qBDpSXQ",
|
||||
"LBifrwmiSgmVfIhbXlfQcyu1CTQjsNCs1RPf7KYLulREgdEEtkCBlDmVGOaQoq/Qz8RHlqbUpFaAhydH",
|
||||
"g1hEavAOJoNfjo8PB7/YCQft2a60UMFzGiUQPrc5IM9Bkjm7Y+hWl0VAJqcBUUI5U9m1w1smhS+YyoVi",
|
||||
"/sO9fR4j60FVBtuxViWiSGMyARIzlad0CTFhPGU2m0MxWCVUaxolJkt9M1JuUe9yzYh7d6mbumbMV1Tp",
|
||||
"8MDZxDUHe2iqzGFot8aktKZ3taPBUSGlmFF9BSYMZKq0YdxGiCr7l1i5Zr31fP+C5bq5ynTu7QbH4Udb",
|
||||
"Tz9lox86v3162w3/7W0rq8fH19iNqkSYWX+y1MqbvbvZu6t7d3ttesOEb2XEYeKGEt82Um8k9hkn+9NK",
|
||||
"KOGRaSwkfvgao7gDEwWWO/dL7uHPgcAviwCc8clw5EnbSahlMaUsdTUUnlRKyXryCMWEwuihbE7quNCI",
|
||||
"rNcW2OONpG4tqUbu76ocXZuzv4V75X0NXyd3KaG8mnENDbfN85VZurWZPiT0ilSfUa/VAU4JtAXTiSh0",
|
||||
"lShrVm3eMP1ntLjLE6kKT42SgLXpvfKQ4ZdK4Xxati9KIPqwSfVtUn2bVN8m1bdJ9W1SfbdP9a3JjXnc",
|
||||
"7mbNW2lNN9mvv1eY/gr4TCe3uCnlG7exHTeh+SY034Tm33JovonFv4FY/DnGmaVhqIvofUF5XnjLb/KU",
|
||||
"RtC5RWOr9jgsKqtnvctcQlm6XGnj/Rd9cpw0qrfJVKSpWChsooAoDbkan/KhbVZf7CPTlM4Iq1wMU+GP",
|
||||
"f2RUfqjHN2GZrXozd2lO+ciO1Mr+m0Izs5gqiV0W57tq81O+3ScvW7kHpqq7RI/Qme6RjGVgLjH1GoT2",
|
||||
"COio//iUn/I9GiVmRdiXapGxqEcmhTaPUtgvcPeqHrJqzkSh7PptIa4N1gj6mCipiKYY24kUdztS2T/l",
|
||||
"nQyFE9G9FCE5Dt1f1ds9VTkb78N7xakl43oF9hGMJmKbl7PXlxw3L/JcXezbubfmucCy5gTa0Yje32ot",
|
||||
"L19d0l3LerfurVZwZZH+JbUKF8t99tAqFxt8v3XxYqkI1+Q026Wxg+o+qruxenVpY/v2arNEo67O2Ktu",
|
||||
"lZZ7Ftsydcpj3O0Zc+/31Dfbp2xW2B4epeHSms0rxJ+kPD5Tnez9odh7WXodmmdUJyBXY+O/As1HIlt9",
|
||||
"zOcO0L0xzhrIdsbxamwPHBfU9SAvW5b3QtZB0pa9PyRYdtJEJ6rBy0KmBHicC2YNUHmF1OayWpZ8TRro",
|
||||
"t3A3+xjupjMhmU6yB0jbcwmGvTR9gMS9sOnrh0bWnn3X4AFSdlQ+avBAaYO4PmV7cDsB4ylVZOGBiB8k",
|
||||
"/5xdCI/FB+DBX0nQWbg5ydycZG5OMjcnmZuTzM1J5ubSwubSwubSwuZ0dXNpYXNpYXNpYbN3N5URm+P3",
|
||||
"zaWFTaHEQymUuOqcYvVIpBfAWZQWMWTl8Yh76ay/pNmV532F5KbqgbzJge8e7hO7AhLDlHGHYPNgJVNk",
|
||||
"93C/R2iaigXiJ0qZoUoLUnBkmDbKPQFC55Sl9kcrXL7O3nPIRAyp/8ESN/tRDlFwq2DlLCxX2GH9+jPv",
|
||||
"tWt9AOfD9jCtQsHPoGvRWLUerVbMlI9rlp93saAG9umecCLFB+Bhs6jA/9zdT6Zhq+7EsAli9JCy1hu3",
|
||||
"CVXNGpkfiZYFmBITc2iJfbmoakGbdS4miWhuvGj39BKz7pd5grEuzzHTuLythavnrcZ1jy/ZpRw0KxU+",
|
||||
"4Uh3/Uu9N34frHyA/gY/Z+I5f/U8yEQmbWn9NTDmzWNh36nwmmc417zKtLqmGu/1o5tdgAuZJ5Rf8Y7j",
|
||||
"G9OgeuuN1u84Isbwn6ZijOtOTVaBSJ+j++V9+uuz4bekuH6p8d7gW715WWH3micP74xQ0WL71wBQtbqm",
|
||||
"awCaMqW/Mf37iin9FWtfnKD46tQvCk3dVvsacHOhw6LxKyB+ZB8jlpjqXQdiU1v7uVBpdOlroRu/G/MV",
|
||||
"4TKB6ENl4bjQX+6J0C+AzIa1RnPMv3dnsEUtyuuh+lW5CciXv7WTUCnSr8lLsGi9uY8wr9/yv7JuUdkn",
|
||||
"+01EfbvfECAnCqZFat92F5xpIcvX3WOYFLMZ4zNvdF6+8v8Zq2E9v6vgEc6/PetdKfR2hxMPM5IvX9f3",
|
||||
"yK2Z1VkqDRnCwkBPzv11pt0H/I9M285b+ueqmMQio4xf9suHjs8lzJjgl337AwGy4IP5MEAEOyrOPb/C",
|
||||
"sJpocGfY7Y891Shcg+Q0bfxaAnE5itgen+fFJGURjq/qYes0RndIeymGcjqzlxYau6kuAXA6pLOSdT/h",
|
||||
"UHdtfNbtX3K8sRr7ikejlrkxVpmj8wxk5LwCgrKXxcDl+8v/BAAA///wREgRYHkAAA==",
|
||||
"H4sIAAAAAAAC/+xde3PbtrL/KhjezjQ5FSVLjpNzNdO513Wcxj1x4ontk86tc2cgciWiIQEWAKUotr/7",
|
||||
"mQXAlwj5FSd1U/3TOhIei90f9oUFdB5EIssFB65VMD4PVJRARs2f+1IK+RZULrgC/IDGMdNMcJoeSZGD",
|
||||
"1AxUMJ7SVEEviEFFkuX4fTC2fQnjUyEzip8RCbqQHGIyWRKdANk9OugHvSBvjHQeAHa701QxaMpS1R0y",
|
||||
"ppquH1HLojPgbtWSYGciIaUaYqKFIdzQ2CNsSihf4nx6mUMwDsTkd4h0cNkLMlCKzgzL2iO/LDLKQwk0",
|
||||
"ppPUjURcaxwJPtIsT3GwFywFwoUmU1HwuJ5Eacn4LLi87AUS/iiYhDgY/1bN+L5DzaWHvpZg3zGdHEkR",
|
||||
"gVIQ47RqI+q/pqgNO1bk2CbqFVOaiCmZ4tdEJ1STBUggqoiw37RI0yWpBiETmAoJNSeIiKJCSohxAUxD",
|
||||
"Zqb4TsI0GAf/NagVycBpkQHScQiaGsnUUKRS0qUfm60et0PHnshyCQlwxeZAMjdIC5l0IgpNqGEAYZwo",
|
||||
"LaQTSBtKkyL6APog7vLw4DlyEHli25BIcE0ZZ3xmPsWh2wIuFEgV2tZd8faCSAKCbld3JzthGShNs5ws",
|
||||
"EuDV+GRBFXHd2nONtkbb4dYwHO6cDEfj7Sfjnaf/F/QCy4FgjFsEQs0y8BECms66NOxzzfSSaDojUyFJ",
|
||||
"RKMEyJymLDY8bc9/FtDhZBRtx09gZ/r0LPBNwzxcPeXsjwIIi4FrNmUgzVx+fsY78OxpBJPw2TM6Cp8M",
|
||||
"d7bDybOYhsPps2g43JmMptORd151mqeCxuCZ/10COoF6RpJQRSYAvL03CjdAiyCrWNx0EyFSoNzqhutg",
|
||||
"7FNJe4XSIqvhS5USETNaacF04ufJeUBTFO+RFIb6nEW6kCjkiGqYCbnEXTenmsrAt+sylsGJ+XCVMYcH",
|
||||
"h/sE25eo78qDZXQGg99zmPm4zmnmGfY1zVojEsajtIhxE8FHjVt4FVm5XVroltb/PfdOp9gnz3TH7NPq",
|
||||
"dGSy1KBac4ye7Dx99s/GbmFcP31Sz8K4hhkYDhZ5fJc9m1Klieu7ZuM+Pdn67/GTnfH26OYbt4TlT8tT",
|
||||
"BfJqrYXaiCwSUWF5jVTpJBqOtmOYPtl5eq1RYmi3jKSdBHq1BnV6pannmvxr7csGEt+vMQ7HRZZRxPOt",
|
||||
"bMNPVLHo4ZuCv4tq/KpK4QqsNkDaYIEPem8KnRf6AFXdC7cnkfwpLYziVXa89npsH2IxZ6RmVKV1v/rk",
|
||||
"VAH5nhZafG8Nq+AauCYcZkIzC9IJRT9McLIbRZBrkgCNQSILeJHhYrA77jk7vdPBC5jkCGOO/6BzNg16",
|
||||
"QQIswoXVvHN9Olg4kqDYjEN8+vbVHaO/PbsPFKEkL0cjp29fmXXGTEKkrYBxHLNSjzcPH3Nmv/To2AQI",
|
||||
"KkOzcSESPFak4JqlBjs4k+m9ot+3n25teZW5TP1TdIn3UF1zNNE6V+PBoFQl7pt+JLKBkfnAKtX/wUEp",
|
||||
"AvbHj8tP1wIWyes12eHD59sXe6N/jkbPqfZsLPwUWfX2xR7BVg6SLeJPCuiR4YjsFjMy2hrtkOFovLU9",
|
||||
"3tkiPx+eoHCo1iBxtP9/dCj4xUkBF+8gvjhJiosXkl0cU31xXPDHPXJ2Fp8Pe6NL8ugXyi9ewOTikMqL",
|
||||
"3VxeHNLlxS8Fv/ilSC92i9nFMeQXbyJ98VrML55D9Nh0fXJp/je6HLf+R87OFj9812FWL/gYzkToPkTb",
|
||||
"i9w4NeblM2KJspsNkiLKyQRKw22AQDmBj0xpVE6lHm7j927u36mbI1pxA7WoPcEbOILlMFbhNKdouYRO",
|
||||
"f3p9wjU6GhYEv3EEsRkvg+WuNZKALePQfLNONXfmtWr4PmSXSzFn6OEYR8waKJQXJRwWa6Tms8Bvcpcj",
|
||||
"cEI5eN42weRgagL4cr4eoeT09OA5WbA0ReDMgKPGWPX57HAhi8PhaNuniu8ngrgldFx3g5w2WmIRFRlw",
|
||||
"fRu4rIdKl2v4lZBsxpDX2MYArWRiodbwr2zZtwbvBhD7N0j0JQ5qd/CuBm5uR/J4lrgYZwiIAjlnkde3",
|
||||
"ZGnsqPGboHICXmQTkKV3tDIwMeO0mTPsj/rb19qWFgHe7KGCqJBML4+jBDJL9W6hEyHZp4pzE6ASZOkX",
|
||||
"Bb+8O+n4QrtHB+QDLA0WXHcgSAkobcyoSRkZN9EMVlOOVhWF9mv4kqpC0nA3zhgPjyGS4Am/bCNCsRH6",
|
||||
"BhK0mRh37IRGH4DHA/MlUxrt6XzVnjMcpXK0LKzXTF4ntHL2L1gGl8gwhAKSZYKByFAIGWUpCqHIcyH1",
|
||||
"//JEKN1noh7/NX5Cju33gXNJKoeian+5ylbXz8EBmRyS3QoWuOaMcjozWo/H9gtnsZTVBblYgJwWKaHG",
|
||||
"mTduqBQpiWhOJyxlBqq9IGUROEfQkbybm0zQK/sFGfW3OnQvFos+Nc36Qs4Gbgw1eHWwt//6eD/EPrg/",
|
||||
"mU7Bt5igF8zLzREM+1u2uciB05wF42DbfGR8k8Qg07pZ+FculAcc1rYQwVHRkExIKHOhglCicogwwopd",
|
||||
"PNcvBaLIhOooaZgQwzqxYhcqjYt8BxoltaKre2ZFqlmeuol7BJiJrpwWbI9B09TRJyThghsNUqEVQ9KG",
|
||||
"tUQpuQ31k4iXJQRRX6M3YqalUg9QUYWlVbGJWsMwT9Ab+qzhCZUz0GXI2whLFwlU/CyVNiqqVbWNQXBo",
|
||||
"GaJ8Vg9H+O19d+JdKemykb4uUxitbHSVMJkwTuXSN347CV1bWd+cb64VcZVGsbI+LJQmmUGLNWdxrbXt",
|
||||
"woiZ+MYpdI875EukN5W6Y6BHnXf0hzl8sEsgLltehtyWy6g1KpxX/khzPnRBDAE2VDQLGm0NV/BH8zxl",
|
||||
"kcHt4HdlzcY68N30GGPNsUVDuekEmKzIvr9jiya3V6i9KdeVP31iVbxLK9yCg1ct57rzPg+F+63zHhIX",
|
||||
"uHkckS23IBj/1nEIfnt/+b4XqDJRV2rdqVNSms5UCVMVvMfRXHh8zuJLK+4UfHHsEciM4trSJbFtygTe",
|
||||
"VIqsSuGRk4QpIiETc1BkIhoeb5VlQVwzrZrp9SZM2kr2uZkLmWWMjaQZaJDKrP26ZF0zn6WFI7t0M9Bw",
|
||||
"1U6AyUy1N1avIeJVT+59Z9M96bLMbPAW0iwFXx5oN4eV4Y0hC1vdFl1WOGYQD7h6wcznJb4FLRnMweAg",
|
||||
"FgtuEIqCwmVVA5ZwaXgCkeDVmXHpv/ZcnK0l5aoKBFTPjC4pn9WurjEcaIcZTauJVRdyP4O+H7y5Ke4F",
|
||||
"cb2OeeTp0h33N7K2lgIjY67J/gmdWYuIfgyvMrxzmhagqvBvnefNpqHpHHwZwmIByoSh1mZTvrw9feiZ",
|
||||
"3SeRTNc59kzE1iWlU+2S8DM2B47WGq7imesXKsYjaNF11Q5uphFvTzHy8bOoLviXodvk7ckfBU2ZXpJH",
|
||||
"w3C4tfW4T8xyjLqz/uQvR/s/98g7mBz1yNHrn832fbl/sFeZLkP3HwUYx9KR/UeLyIx+ZFmRBePh1lYv",
|
||||
"wDDT/qubd+5SeWj7kgTYLNFIkASFcbLTLoIsEmR4Rll1zkQxaNHEaI7ughrnDWuob0P2bvQuWIwm9muQ",
|
||||
"u/gMcn9KCwtFO02h7DkdU0SxWUbthr8LURM/UfVZg03eeDfUlzsi8lE6vfGG6p53eah/a0ybmNqzdIsA",
|
||||
"Z1eNQ1bn+uwYY9vwR6Wp1CHwtUrVDNyitXH8YMd4dHYW/xCencX/uMD/4F8/PH7U8378+B/feTJhXf9p",
|
||||
"6wpPSEQadKi0BJoF4/M1oVQpoZIPccv3MudwuFKbRjMCC81aPVHObrqgS0UUGE1gqxVImVmJYQ4pegz9",
|
||||
"THxiaUpNggV4eHo8iEWkBu9gMnh5cnI0eGknHLRnu9JOBXs0SiDcs5kgz3GSOcFj6FyXFUEmswFRQjlT",
|
||||
"2bXDWyaFz5nKhWL+I74DHiPrQVVm27FWJaJIYzIBEjOVp3QJMWE8ZTanQzFkJVRrGiUmV30zUm5R/HLN",
|
||||
"iPt3KaK6ZsxXVOnw0FnGNcd7aKvMkWi34KS0qXe1psFxIaWYUX0FJgxkquRh3EaIKvuXWLlmvfV8/4Ll",
|
||||
"urnKpO7tBsfhR1tPP2ejHznvfXrbDf/321ZWj4+vsRtVvTCzXmWplTd7d7N3V/fu9tokhwniyrjDRA8l",
|
||||
"vm283kjvM04OppVQwmPTWEj88DXGcocmFix37tfcw18CgV8XATjjk+HIk7yTUMtiSlnqKik8CZWS9eQR",
|
||||
"igmF0UPZnNbRoRFZry2wxxtJ3VpSjQzgVZm6Nmd/DffLyxu+Tu6GQnlP4xoabpvtK3N1a/N9SOgVCT+j",
|
||||
"XqtjnBJoC6YTUegqXdYs4bxhEtBocZctUhWeGoUBa5N85VHDy0rhfF7OL0og+rBJ+G0SfpuE3ybht0n4",
|
||||
"bRJ+d034rcmQeZzvZv1baVM3ObC/VrD+CvhMJ7e4POUbt7EdNwH6JkDfBOh/5wB9E5H/DSLyPYw2S8NQ",
|
||||
"F9T7QvO88Jbi5CmNoHOjxlbwcVhUVs96l7mEsoy50sYHz/vkJGlUcpOpSFOxUNhEAVEacjU+40PbrL7r",
|
||||
"R6YpnRFWuRim2h//yKj8UI9vgjNbAWfu1ZzxkR2pdQZgis7MYqpUdlmo7yrPz/h2n7xoZSCYqu4VPUJn",
|
||||
"ukcyloG50NRrENojoKP+4zN+xvdplJgVYV+qRcaiHpkU2rxTYb/A3at6yKo5E4Wy67dFuTZkI+hjoqQi",
|
||||
"mmKEJ1Lc7Uhl/4x38hRORPdSkOQ4dH8VcPdU8Wy8D+91p5aM6xXYdzGaiG3e115ffty81HN14W/nDpvn",
|
||||
"Msuac2hHI3p/q3W9fHVJdy3x3bq3usGVRfqX1CpiLPfZQ6tibPD91oWMpSJck9lsl8kOqrup7vbq1WWO",
|
||||
"7ZuszUKNukZjv7phWu5ZbMvUGY9xt2fMPelTX3afsllhe3iUhktuNq8Tf5by+EI1s/eHYu/F6XVonlGd",
|
||||
"gFyNjf8MNB+LbPV9nztA98Y4ayDbGcersT1wXFDXg7xsWd4RWQdJWwL/kGDZSROdqgYvC5kS4HEumDVA",
|
||||
"5XVSm8tqWfI1aaBfw93sU7ibzoRkOskeIG17Egx7afoAiXtuk9gPjax9+8bBA6TsuHzg4IHSBnF91vbg",
|
||||
"dgLGU6rIwkMRP0j+ObsQnogPwIM/k6CP4eY8c3OeuTnP3Jxnbs4zN+eZmwsMmwsMmwsMmzPWzQWGzQWG",
|
||||
"zQWGzd7d1Eds6iM2Fxg25RIPq1ziqtOK1YORXgAfo7SIISsPSdzbZ/0lza489SskN7UP5E0OfPfogNgV",
|
||||
"kBimjDsEmycsmSK7Rwc9QtNULBA/UcoMVVqQgiPDtFHuCRA6pyy1v2bhsnb2zkMmYkj9T5i42Y9ziIJb",
|
||||
"BSsfw3KFHdavP/leu9YHcEpsj9QqFPwMuhaNVevRat1M+dxm+XkXC2pgH/MJJ1J8AB42Swv8D+D9ZBq2",
|
||||
"qk8MmyBGDylrvXqbUNWslPmRaFmAKTQxR5fYl4uqIrRZ7WJSieb2i3aPMTHrfplHGesiHTONy95auHpe",
|
||||
"b1z3HJNdymGzXuEzDnbXv9174xfDypfpb/A7J55TWM8TTWTSltafA2PePBz2nQ2veZhzzTtNq2uq8V4/",
|
||||
"w9kFuJB5QvkVLzu+MQ2q199o/bIjYgz/aerGuO5UZhWI9Dm6X97HwL4YfkuK67cb7w2+1SuYFXaveQTx",
|
||||
"zggVLbZ/CwBVq2u6BqApU/pvpn9fMaW/Ye2LExTfnPpFoanbal8Dbi50WDR+HsSP7BPEElO960BsKmy/",
|
||||
"FCqNLn0tdOMHZb4hXCYQfagsHBf66z0a+hWQ2bDWaI759+4ktqhFeT1Uvyk3Afnyl3YSKkX6LXkJFq03",
|
||||
"9xHm9ev+V1YvKvuIv4mob/erAuRUwbRI7WvvgjMtZPneewyTYjZjfOaNzst3/79gTaznlxY8wvm3Z70r",
|
||||
"5d7ucOJhRvLle/seuTWzOkulIUNYGOjJub/atPuk/7Fp23ld/1wVk1hklPHLfvn08bmEGRP8sm9/MkAW",
|
||||
"fDAfBohgR8W553cZVhMN7gy7/bGnJoVrkJymjd9PIC5HEdvj87yYpCzC8VU9bJ3G6A5pr8ZQTmf26kJj",
|
||||
"N9UlAE6HdFay7kcd6q6Nz7r9S443VmNf9GhUNDfGKnN0noGMnFdAUPayGLh8f/mfAAAA////QOU7eXkA",
|
||||
"AA==",
|
||||
}
|
||||
|
||||
// GetSwagger returns the content of the embedded swagger specification file
|
||||
|
||||
@@ -18,6 +18,7 @@ const (
|
||||
const (
|
||||
Auto OutputImageFormat = "auto"
|
||||
Avif OutputImageFormat = "avif"
|
||||
Heic OutputImageFormat = "heic"
|
||||
Jpeg OutputImageFormat = "jpeg"
|
||||
Png OutputImageFormat = "png"
|
||||
Same OutputImageFormat = "same"
|
||||
@@ -158,7 +159,7 @@ type UploadFilesMultipartBody struct {
|
||||
|
||||
// GetFileParams defines parameters for GetFile.
|
||||
type GetFileParams struct {
|
||||
// Q Image quality (1-100). Only applies to JPEG, WebP and PNG files
|
||||
// Q Image quality (1-100). Only applies to JPEG, WebP, PNG and HEIC files
|
||||
Q *int `form:"q,omitempty" json:"q,omitempty"`
|
||||
|
||||
// H Maximum height to resize image to while maintaining aspect ratio. Only applies to image files
|
||||
@@ -191,7 +192,7 @@ type GetFileParams struct {
|
||||
|
||||
// GetFileMetadataHeadersParams defines parameters for GetFileMetadataHeaders.
|
||||
type GetFileMetadataHeadersParams struct {
|
||||
// Q Image quality (1-100). Only applies to JPEG, WebP and PNG files
|
||||
// Q Image quality (1-100). Only applies to JPEG, WebP, PNG and HEIC files
|
||||
Q *int `form:"q,omitempty" json:"q,omitempty"`
|
||||
|
||||
// H Maximum height to resize image to while maintaining aspect ratio. Only applies to image files
|
||||
@@ -257,7 +258,7 @@ type GetFileWithPresignedURLParams struct {
|
||||
// XId Use presignedurl endpoint to generate this automatically
|
||||
XId string `form:"x-id" json:"x-id"`
|
||||
|
||||
// Q Image quality (1-100). Only applies to JPEG, WebP and PNG files
|
||||
// Q Image quality (1-100). Only applies to JPEG, WebP, PNG and HEIC files
|
||||
Q *int `form:"q,omitempty" json:"q,omitempty"`
|
||||
|
||||
// H Maximum height to resize image to while maintaining aspect ratio. Only applies to image files
|
||||
|
||||
@@ -28,6 +28,7 @@ const (
|
||||
const (
|
||||
Auto OutputImageFormat = "auto"
|
||||
Avif OutputImageFormat = "avif"
|
||||
Heic OutputImageFormat = "heic"
|
||||
Jpeg OutputImageFormat = "jpeg"
|
||||
Png OutputImageFormat = "png"
|
||||
Same OutputImageFormat = "same"
|
||||
@@ -168,7 +169,7 @@ type UploadFilesMultipartBody struct {
|
||||
|
||||
// GetFileParams defines parameters for GetFile.
|
||||
type GetFileParams struct {
|
||||
// Q Image quality (1-100). Only applies to JPEG, WebP and PNG files
|
||||
// Q Image quality (1-100). Only applies to JPEG, WebP, PNG and HEIC files
|
||||
Q *int `form:"q,omitempty" json:"q,omitempty"`
|
||||
|
||||
// H Maximum height to resize image to while maintaining aspect ratio. Only applies to image files
|
||||
@@ -201,7 +202,7 @@ type GetFileParams struct {
|
||||
|
||||
// GetFileMetadataHeadersParams defines parameters for GetFileMetadataHeaders.
|
||||
type GetFileMetadataHeadersParams struct {
|
||||
// Q Image quality (1-100). Only applies to JPEG, WebP and PNG files
|
||||
// Q Image quality (1-100). Only applies to JPEG, WebP, PNG and HEIC files
|
||||
Q *int `form:"q,omitempty" json:"q,omitempty"`
|
||||
|
||||
// H Maximum height to resize image to while maintaining aspect ratio. Only applies to image files
|
||||
@@ -267,7 +268,7 @@ type GetFileWithPresignedURLParams struct {
|
||||
// XId Use presignedurl endpoint to generate this automatically
|
||||
XId string `form:"x-id" json:"x-id"`
|
||||
|
||||
// Q Image quality (1-100). Only applies to JPEG, WebP and PNG files
|
||||
// Q Image quality (1-100). Only applies to JPEG, WebP, PNG and HEIC files
|
||||
Q *int `form:"q,omitempty" json:"q,omitempty"`
|
||||
|
||||
// H Maximum height to resize image to while maintaining aspect ratio. Only applies to image files
|
||||
|
||||
@@ -283,7 +283,7 @@ func TestGetFileMetadataHeaders(t *testing.T) { //nolint:maintidx
|
||||
"Accept-Ranges": []string{"bytes"},
|
||||
"Cache-Control": []string{"max-age=3600"},
|
||||
"Content-Disposition": []string{`inline; filename="nhost.jpg"`},
|
||||
"Content-Length": []string{"8709"},
|
||||
"Content-Length": []string{"8963"},
|
||||
"Content-Type": []string{"image/jpeg"},
|
||||
"Date": []string{"Mon, 21 Jul 2025 13:24:53 GMT"},
|
||||
"Etag": []string{`"78b676e65ebc31f0bb1f2f0d05098572"`},
|
||||
|
||||
@@ -399,7 +399,7 @@ func TestGetFile(t *testing.T) { //nolint:maintidx
|
||||
"Accept-Ranges": []string{"bytes"},
|
||||
"Cache-Control": []string{"max-age=3600"},
|
||||
"Content-Disposition": []string{`inline; filename="nhost.jpg"`},
|
||||
"Content-Length": []string{"8709"},
|
||||
"Content-Length": []string{"8963"},
|
||||
"Content-Type": []string{"image/jpeg"},
|
||||
"Date": []string{"Mon, 21 Jul 2025 13:24:53 GMT"},
|
||||
"Etag": []string{`"78b676e65ebc31f0bb1f2f0d05098572"`},
|
||||
|
||||
@@ -475,7 +475,7 @@ func TestGetFileWithPresignedURL(t *testing.T) { //nolint:cyclop,maintidx
|
||||
"Accept-Ranges": []string{"bytes"},
|
||||
"Cache-Control": []string{"max-age=30"},
|
||||
"Content-Disposition": []string{`inline; filename="nhost.jpg"`},
|
||||
"Content-Length": []string{"8709"},
|
||||
"Content-Length": []string{"8963"},
|
||||
"Content-Type": []string{"image/jpeg"},
|
||||
"Date": []string{"Mon, 21 Jul 2025 13:24:53 GMT"},
|
||||
"Etag": []string{`"78b676e65ebc31f0bb1f2f0d05098572"`},
|
||||
|
||||
@@ -37,6 +37,8 @@ func mimeTypeToImageType(mimeType string) (image.ImageType, *APIError) {
|
||||
return image.ImageTypeJPEG, nil
|
||||
case "image/avif":
|
||||
return image.ImageTypeAVIF, nil
|
||||
case "image/heic", "image/heif":
|
||||
return image.ImageTypeHEIC, nil
|
||||
default:
|
||||
return 0, BadDataError(
|
||||
fmt.Errorf( //nolint: err113
|
||||
@@ -73,6 +75,8 @@ func chooseImageFormat( //nolint: cyclop
|
||||
return originalFormat, image.ImageTypeJPEG, nil
|
||||
case api.Avif:
|
||||
return originalFormat, image.ImageTypeAVIF, nil
|
||||
case api.Heic:
|
||||
return originalFormat, image.ImageTypeHEIC, nil
|
||||
case api.Auto:
|
||||
for _, acceptHeader := range acceptHeader {
|
||||
acceptedTypes := strings.Split(acceptHeader, ",")
|
||||
@@ -85,6 +89,8 @@ func chooseImageFormat( //nolint: cyclop
|
||||
return originalFormat, image.ImageTypeJPEG, nil
|
||||
case slices.Contains(acceptedTypes, "image/png"):
|
||||
return originalFormat, image.ImageTypePNG, nil
|
||||
case slices.Contains(acceptedTypes, "image/heic"):
|
||||
return originalFormat, image.ImageTypeHEIC, nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,8 +98,11 @@ func chooseImageFormat( //nolint: cyclop
|
||||
default:
|
||||
return 0, 0, BadDataError(
|
||||
//nolint: err113
|
||||
fmt.Errorf("format must be one of: same, webp, png, jpeg, avif, auto. Got: %s", format),
|
||||
"format must be one of: same, webp, png, jpeg, avif, auto. Got: "+string(format),
|
||||
fmt.Errorf(
|
||||
"format must be one of: same, webp, png, jpeg, avif, heic, auto. Got: %s",
|
||||
format,
|
||||
),
|
||||
"format must be one of: same, webp, png, jpeg, avif, heic, auto. Got: "+string(format),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,7 +148,7 @@ paths:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RFC2822Date'
|
||||
- name: q
|
||||
description: "Image quality (1-100). Only applies to JPEG, WebP and PNG files"
|
||||
description: "Image quality (1-100). Only applies to JPEG, WebP, PNG and HEIC files"
|
||||
in: query
|
||||
schema:
|
||||
type: integer
|
||||
@@ -332,7 +332,7 @@ paths:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RFC2822Date'
|
||||
- name: q
|
||||
description: "Image quality (1-100). Only applies to JPEG, WebP and PNG files"
|
||||
description: "Image quality (1-100). Only applies to JPEG, WebP, PNG and HEIC files"
|
||||
in: query
|
||||
schema:
|
||||
type: integer
|
||||
@@ -614,7 +614,7 @@ paths:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RFC2822Date'
|
||||
- name: q
|
||||
description: "Image quality (1-100). Only applies to JPEG, WebP and PNG files"
|
||||
description: "Image quality (1-100). Only applies to JPEG, WebP, PNG and HEIC files"
|
||||
in: query
|
||||
schema:
|
||||
type: integer
|
||||
@@ -1178,4 +1178,5 @@ components:
|
||||
- webp
|
||||
- png
|
||||
- avif
|
||||
- heic
|
||||
example: same
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
package image
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/davidbyttow/govips/v2/vips"
|
||||
"github.com/cshum/vipsgen/vips"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -24,6 +21,7 @@ const (
|
||||
ImageTypePNG
|
||||
ImageTypeWEBP
|
||||
ImageTypeAVIF
|
||||
ImageTypeHEIC
|
||||
)
|
||||
|
||||
type Options struct {
|
||||
@@ -54,6 +52,8 @@ func (o Options) FormatMimeType() string {
|
||||
return "image/webp"
|
||||
case ImageTypeAVIF:
|
||||
return "image/avif"
|
||||
case ImageTypeHEIC:
|
||||
return "image/heic"
|
||||
}
|
||||
|
||||
return ""
|
||||
@@ -69,6 +69,8 @@ func (o Options) FileExtension() string {
|
||||
return "webp"
|
||||
case ImageTypeAVIF:
|
||||
return "avif"
|
||||
case ImageTypeHEIC:
|
||||
return "heic"
|
||||
}
|
||||
|
||||
return ""
|
||||
@@ -76,12 +78,10 @@ func (o Options) FileExtension() string {
|
||||
|
||||
type Transformer struct {
|
||||
workers chan struct{}
|
||||
pool sync.Pool
|
||||
}
|
||||
|
||||
func NewTransformer() *Transformer {
|
||||
if atomic.CompareAndSwapInt32(&initialized, 0, 1) {
|
||||
vips.LoggingSettings(nil, vips.LogLevelWarning)
|
||||
vips.Startup(nil)
|
||||
}
|
||||
|
||||
@@ -92,11 +92,6 @@ func NewTransformer() *Transformer {
|
||||
|
||||
return &Transformer{
|
||||
workers: workers,
|
||||
pool: sync.Pool{
|
||||
New: func() any {
|
||||
return new(bytes.Buffer)
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,35 +99,67 @@ func (t *Transformer) Shutdown() {
|
||||
vips.Shutdown()
|
||||
}
|
||||
|
||||
func export(image *vips.ImageRef, opts Options) ([]byte, error) {
|
||||
var (
|
||||
b []byte
|
||||
err error
|
||||
)
|
||||
|
||||
switch opts.Format {
|
||||
case ImageTypeJPEG:
|
||||
ep := vips.NewJpegExportParams()
|
||||
ep.Quality = opts.Quality
|
||||
b, _, err = image.ExportJpeg(ep)
|
||||
case ImageTypePNG:
|
||||
ep := vips.NewPngExportParams()
|
||||
b, _, err = image.ExportPng(ep)
|
||||
case ImageTypeWEBP:
|
||||
ep := vips.NewWebpExportParams()
|
||||
ep.Quality = opts.Quality
|
||||
b, _, err = image.ExportWebp(ep)
|
||||
case ImageTypeAVIF:
|
||||
ep := vips.NewAvifExportParams()
|
||||
ep.Quality = opts.Quality
|
||||
ep.Effort = 0
|
||||
b, _, err = image.ExportAvif(ep)
|
||||
}
|
||||
|
||||
return b, err //nolint: wrapcheck
|
||||
type readCloserAdapter struct {
|
||||
io.Reader
|
||||
}
|
||||
|
||||
func processImage(image *vips.ImageRef, opts Options) error {
|
||||
func (r readCloserAdapter) Close() error {
|
||||
if closer, ok := r.Reader.(io.Closer); ok {
|
||||
return closer.Close() //nolint: wrapcheck
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type writeCloserAdapter struct {
|
||||
io.Writer
|
||||
}
|
||||
|
||||
func (w writeCloserAdapter) Close() error {
|
||||
if closer, ok := w.Writer.(io.Closer); ok {
|
||||
return closer.Close() //nolint: wrapcheck
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func exportToTarget(image *vips.Image, target *vips.Target, opts Options) error {
|
||||
quality := opts.Quality
|
||||
if quality == 0 {
|
||||
quality = 75
|
||||
}
|
||||
|
||||
var err error
|
||||
switch opts.Format {
|
||||
case ImageTypeJPEG:
|
||||
jpegOpts := vips.DefaultJpegsaveTargetOptions()
|
||||
jpegOpts.Q = quality
|
||||
err = image.JpegsaveTarget(target, jpegOpts)
|
||||
case ImageTypePNG:
|
||||
pngOpts := vips.DefaultPngsaveTargetOptions()
|
||||
err = image.PngsaveTarget(target, pngOpts)
|
||||
case ImageTypeWEBP:
|
||||
webpOpts := vips.DefaultWebpsaveTargetOptions()
|
||||
webpOpts.Q = quality
|
||||
err = image.WebpsaveTarget(target, webpOpts)
|
||||
case ImageTypeAVIF:
|
||||
heifOpts := vips.DefaultHeifsaveTargetOptions()
|
||||
heifOpts.Q = quality
|
||||
heifOpts.Compression = vips.HeifCompressionAv1
|
||||
err = image.HeifsaveTarget(target, heifOpts)
|
||||
case ImageTypeHEIC:
|
||||
heifOpts := vips.DefaultHeifsaveTargetOptions()
|
||||
heifOpts.Q = quality
|
||||
heifOpts.Compression = vips.HeifCompressionHevc
|
||||
err = image.HeifsaveTarget(target, heifOpts)
|
||||
default:
|
||||
return fmt.Errorf("unsupported format: %d", opts.Format) //nolint: err113
|
||||
}
|
||||
|
||||
return err //nolint: wrapcheck
|
||||
}
|
||||
|
||||
func imageResize(image *vips.Image, opts Options) error {
|
||||
if opts.Width > 0 || opts.Height > 0 {
|
||||
width := opts.Width
|
||||
height := opts.Height
|
||||
@@ -145,13 +172,33 @@ func processImage(image *vips.ImageRef, opts Options) error {
|
||||
height = int((float64(width) / float64(image.Width())) * float64(image.Height()))
|
||||
}
|
||||
|
||||
if err := image.Thumbnail(width, height, vips.InterestingCentre); err != nil {
|
||||
thumbnailOpts := vips.DefaultThumbnailImageOptions()
|
||||
thumbnailOpts.Crop = vips.InterestingCentre
|
||||
thumbnailOpts.Height = height
|
||||
|
||||
if err := image.ThumbnailImage(width, thumbnailOpts); err != nil {
|
||||
return fmt.Errorf("failed to thumbnail: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func imagePipeline(image *vips.Image, opts Options) error {
|
||||
if err := imageResize(image, opts); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Auto-rotate when converting formats to ensure correct display
|
||||
if opts.FormatChanged() {
|
||||
if err := image.Autorot(nil); err != nil {
|
||||
return fmt.Errorf("failed to auto-rotate: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Apply blur if specified
|
||||
if opts.Blur > 0 {
|
||||
if err := image.GaussianBlur(float64(opts.Blur)); err != nil {
|
||||
if err := image.Gaussblur(float64(opts.Blur), nil); err != nil {
|
||||
return fmt.Errorf("failed to blur: %w", err)
|
||||
}
|
||||
}
|
||||
@@ -161,49 +208,37 @@ func processImage(image *vips.ImageRef, opts Options) error {
|
||||
|
||||
func (t *Transformer) Run(
|
||||
orig io.Reader,
|
||||
length uint64,
|
||||
length uint64, //nolint:revive
|
||||
modified io.Writer,
|
||||
opts Options,
|
||||
) error {
|
||||
// this is to avoid processing too many images at the same time in order to save memory
|
||||
// Limit concurrent processing to avoid processing too many images at the same time
|
||||
<-t.workers
|
||||
|
||||
defer func() { t.workers <- struct{}{} }()
|
||||
|
||||
buf, _ := t.pool.Get().(*bytes.Buffer)
|
||||
defer t.pool.Put(buf)
|
||||
defer buf.Reset()
|
||||
// Create streaming source from io.Reader
|
||||
// This avoids loading the entire file into a buffer!
|
||||
source := vips.NewSource(readCloserAdapter{orig})
|
||||
defer source.Close()
|
||||
|
||||
if length > math.MaxUint32 {
|
||||
panic("length is too big")
|
||||
}
|
||||
|
||||
if l := int(length); buf.Len() < l {
|
||||
buf.Grow(l)
|
||||
}
|
||||
|
||||
_, err := io.Copy(buf, orig)
|
||||
image, err := vips.NewImageFromSource(source, nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return fmt.Errorf("failed to load image from source: %w", err)
|
||||
}
|
||||
|
||||
image, err := vips.NewImageFromBuffer(buf.Bytes())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to load image: %w", err)
|
||||
}
|
||||
defer image.Close()
|
||||
|
||||
if err := processImage(image, opts); err != nil {
|
||||
// Apply additional processing (auto-rotate, blur)
|
||||
if err := imagePipeline(image, opts); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b, err := export(image, opts)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to export: %w", err)
|
||||
}
|
||||
// Export with streaming target
|
||||
target := vips.NewTarget(writeCloserAdapter{modified})
|
||||
defer target.Close()
|
||||
|
||||
if _, err = modified.Write(b); err != nil {
|
||||
return fmt.Errorf("failed to write: %w", err)
|
||||
if err := exportToTarget(image, target, opts); err != nil {
|
||||
return fmt.Errorf("failed to export: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -24,7 +24,7 @@ func TestManipulate(t *testing.T) {
|
||||
{
|
||||
name: "jpg",
|
||||
filename: "testdata/nhost.jpg",
|
||||
sum: "0a3f081bd296958cfc99297ee9fb4cc2e5a1b22bebfded81c6e00e25caf84f36",
|
||||
sum: "3cffeb9c31e624970f6b6e440213a9805c4ecf56052268631d1add81f9fde37b",
|
||||
size: 33399,
|
||||
options: image.Options{
|
||||
Height: 100,
|
||||
@@ -37,45 +37,78 @@ func TestManipulate(t *testing.T) {
|
||||
{
|
||||
name: "jpg",
|
||||
filename: "testdata/nhost.jpg",
|
||||
sum: "cd9857da2c40b6c46d39abd0f18def2c9879c2a06a1702c131c17b2bfdb43268",
|
||||
sum: "131c9a8f0dfb0aa345bb498a314da97711b5f3c146e572c02d62d09ace22db7b",
|
||||
size: 33399,
|
||||
options: image.Options{Width: 300, Height: 100, Blur: 2, Format: image.ImageTypeJPEG},
|
||||
},
|
||||
{
|
||||
name: "png",
|
||||
filename: "testdata/nhost.png",
|
||||
sum: "d538212aa74ad1d17261bc2126e60964e6d2dc1c7898ea3b9f9bd3b5bc94b380",
|
||||
sum: "ac7da45c3a994e50fdbc25123992b31116d32f20dac2c5436d2d6fdbfd319853",
|
||||
size: 68307,
|
||||
options: image.Options{Width: 300, Height: 100, Blur: 2, Format: image.ImageTypePNG},
|
||||
},
|
||||
{
|
||||
name: "webp",
|
||||
filename: "testdata/nhost.webp",
|
||||
sum: "720eebe382c26b5fb8abf8552f282317074a4c9f6467aa8a60bb93a20f55e063",
|
||||
sum: "e9e2342f901aa447ebd32ee4ef5a6f89f007f8d692350ec45b7f02b727cc043b",
|
||||
size: 17784,
|
||||
options: image.Options{Width: 300, Height: 100, Blur: 2, Format: image.ImageTypeWEBP},
|
||||
},
|
||||
{
|
||||
name: "jpg only blur",
|
||||
filename: "testdata/nhost.jpg",
|
||||
sum: "0b038c3afbe8a848974874aad4fb11983d45ab84d9113eb4260c4ed34d2d03d6",
|
||||
sum: "e359c19b3a708cfce10577d7b67f7372ddc57b478dcfc5c34b7d49e63bd13a86",
|
||||
size: 33399,
|
||||
options: image.Options{Blur: 2, Format: image.ImageTypeJPEG},
|
||||
},
|
||||
{
|
||||
name: "webp to avif",
|
||||
filename: "testdata/nhost.webp",
|
||||
sum: "e0a5fb177567987b16b379ce2f263cc319c4f7f5e7145c9ae81682b02c7a9f6d",
|
||||
sum: "44ae1c37353bcd8db71df35120be7c6c22435d258ccb3248662bd4fd181b7cf0",
|
||||
size: 17784,
|
||||
options: image.Options{Width: 300, Height: 100, Blur: 2, Format: image.ImageTypeAVIF},
|
||||
},
|
||||
{
|
||||
name: "jpeg to avif, no image manipulation",
|
||||
filename: "testdata/nhost.jpg",
|
||||
sum: "cd3f0137250dcc145ee9f1e63733c30bccfc6ad1c058b2be719ea9e8148029db",
|
||||
sum: "3c03519a14713701db1eaab77dae305b5484f20baacac9625294dd6952446062",
|
||||
size: 17784,
|
||||
options: image.Options{Format: image.ImageTypeAVIF},
|
||||
},
|
||||
{
|
||||
name: "heic",
|
||||
filename: "testdata/nhost.heic",
|
||||
sum: "621a8cac7292d02342e699b11db69b1b5b6f55cb09ce06006a53f9cff7727a98",
|
||||
size: 12968,
|
||||
options: image.Options{
|
||||
Width: 300,
|
||||
Height: 100,
|
||||
Blur: 2,
|
||||
Format: image.ImageTypeHEIC,
|
||||
Quality: 50,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "jpeg to heic",
|
||||
filename: "testdata/nhost.jpg",
|
||||
sum: "c564a40516e3c6f39a8b5d1ba934f3007512d9766630fd512a4c268a0c0b4cb8",
|
||||
size: 33399,
|
||||
options: image.Options{
|
||||
Width: 300,
|
||||
Height: 100,
|
||||
Blur: 2,
|
||||
Format: image.ImageTypeHEIC,
|
||||
Quality: 50,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "webp to heic",
|
||||
filename: "testdata/nhost.webp",
|
||||
sum: "f1d3ebb85e83f70b4d283b30e5c2f765a9f8847b7dceae3d40907aab16b93004",
|
||||
size: 17784,
|
||||
options: image.Options{Width: 300, Height: 100, Blur: 2, Format: image.ImageTypeHEIC},
|
||||
},
|
||||
}
|
||||
|
||||
transformer := image.NewTransformer()
|
||||
|
||||
BIN
services/storage/image/testdata/nhost.heic
vendored
Normal file
BIN
services/storage/image/testdata/nhost.heic
vendored
Normal file
Binary file not shown.
21
vendor/github.com/cshum/vipsgen/LICENSE
generated
vendored
Normal file
21
vendor/github.com/cshum/vipsgen/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2025 Adrian Shum and contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
100
vendor/github.com/cshum/vipsgen/pointer/pointer.go
generated
vendored
Normal file
100
vendor/github.com/cshum/vipsgen/pointer/pointer.go
generated
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
package pointer
|
||||
|
||||
// #include <stdlib.h>
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const blockSize = 1024
|
||||
|
||||
var (
|
||||
mutex sync.RWMutex
|
||||
store = map[unsafe.Pointer]interface{}{}
|
||||
free []unsafe.Pointer
|
||||
blocks []unsafe.Pointer
|
||||
)
|
||||
|
||||
func allocMem() {
|
||||
mem := C.malloc(blockSize)
|
||||
if mem == nil {
|
||||
panic("can't allocate memory block for C pointers")
|
||||
}
|
||||
blocks = append(blocks, mem)
|
||||
for i := 0; i < blockSize; i++ {
|
||||
p := unsafe.Pointer(uintptr(mem) + uintptr(blockSize-1-i))
|
||||
free = append(free, p)
|
||||
}
|
||||
}
|
||||
|
||||
func getPtr() unsafe.Pointer {
|
||||
// Generate real fake C pointer.
|
||||
// This pointer will not store any data, but will be used for indexing
|
||||
// purposes. Since Go doesn't allow to cast dangling pointer to
|
||||
// unsafe.Pointer, we do really allocate memory. Why we need indexing? Because
|
||||
// Go doest allow C code to store pointers to Go data.
|
||||
if len(free) == 0 {
|
||||
allocMem()
|
||||
}
|
||||
n := len(free) - 1
|
||||
p := free[n]
|
||||
free = free[:n]
|
||||
return p
|
||||
}
|
||||
|
||||
// Save an object in the storage and return an index pointer to it.
|
||||
func Save(v interface{}) unsafe.Pointer {
|
||||
if v == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
mutex.Lock()
|
||||
ptr := getPtr()
|
||||
store[ptr] = v
|
||||
mutex.Unlock()
|
||||
|
||||
return ptr
|
||||
}
|
||||
|
||||
// Restore an object from the storage by its index pointer.
|
||||
func Restore(ptr unsafe.Pointer) (v interface{}) {
|
||||
if ptr == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
mutex.RLock()
|
||||
v = store[ptr]
|
||||
mutex.RUnlock()
|
||||
return
|
||||
}
|
||||
|
||||
// Unref removes an object from the storage and returns the index pointer to the
|
||||
// pool for reuse.
|
||||
func Unref(ptr unsafe.Pointer) {
|
||||
if ptr == nil {
|
||||
return
|
||||
}
|
||||
|
||||
mutex.Lock()
|
||||
if _, ok := store[ptr]; ok {
|
||||
delete(store, ptr)
|
||||
free = append(free, ptr)
|
||||
}
|
||||
mutex.Unlock()
|
||||
}
|
||||
|
||||
// Clear storage and free all memory
|
||||
func Clear() {
|
||||
mutex.Lock()
|
||||
for p := range store {
|
||||
delete(store, p)
|
||||
}
|
||||
free = nil
|
||||
for _, p := range blocks {
|
||||
C.free(p)
|
||||
}
|
||||
blocks = nil
|
||||
mutex.Unlock()
|
||||
}
|
||||
76
vendor/github.com/cshum/vipsgen/vips/callback.go
generated
vendored
Normal file
76
vendor/github.com/cshum/vipsgen/vips/callback.go
generated
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
// Code generated by github.com/cshum/vipsgen from libvips 8.17.2; DO NOT EDIT.
|
||||
|
||||
package vips
|
||||
|
||||
import "C"
|
||||
import (
|
||||
"github.com/cshum/vipsgen/pointer"
|
||||
"io"
|
||||
"reflect"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
//export goLoggingHandler
|
||||
func goLoggingHandler(domain *C.char, level C.int, message *C.char) {
|
||||
log(C.GoString(domain), LogLevel(level), C.GoString(message))
|
||||
}
|
||||
|
||||
//export goSourceRead
|
||||
func goSourceRead(
|
||||
ptr unsafe.Pointer, buffer unsafe.Pointer, size C.longlong,
|
||||
) C.longlong {
|
||||
src, ok := pointer.Restore(ptr).(*Source)
|
||||
if !ok {
|
||||
return -1
|
||||
}
|
||||
sh := &reflect.SliceHeader{
|
||||
Data: uintptr(buffer),
|
||||
Len: int(size),
|
||||
Cap: int(size),
|
||||
}
|
||||
buf := *(*[]byte)(unsafe.Pointer(sh))
|
||||
n, err := src.reader.Read(buf)
|
||||
if err == io.EOF {
|
||||
return C.longlong(n)
|
||||
} else if err != nil {
|
||||
return -1
|
||||
}
|
||||
return C.longlong(n)
|
||||
}
|
||||
|
||||
//export goSourceSeek
|
||||
func goSourceSeek(
|
||||
ptr unsafe.Pointer, offset C.longlong, whence int,
|
||||
) C.longlong {
|
||||
src, ok := pointer.Restore(ptr).(*Source)
|
||||
if ok && src.seeker != nil {
|
||||
switch whence {
|
||||
case io.SeekStart, io.SeekCurrent, io.SeekEnd:
|
||||
if n, err := src.seeker.Seek(int64(offset), whence); err == nil {
|
||||
return C.longlong(n)
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
//export goTargetWrite
|
||||
func goTargetWrite(
|
||||
ptr unsafe.Pointer, buffer unsafe.Pointer, size C.longlong,
|
||||
) C.longlong {
|
||||
target, ok := pointer.Restore(ptr).(*Target)
|
||||
if !ok {
|
||||
return -1
|
||||
}
|
||||
sh := &reflect.SliceHeader{
|
||||
Data: uintptr(buffer),
|
||||
Len: int(size),
|
||||
Cap: int(size),
|
||||
}
|
||||
buf := *(*[]byte)(unsafe.Pointer(sh))
|
||||
n, err := target.writer.Write(buf)
|
||||
if err != nil {
|
||||
return -1
|
||||
}
|
||||
return C.longlong(n)
|
||||
}
|
||||
48
vendor/github.com/cshum/vipsgen/vips/connection.c
generated
vendored
Normal file
48
vendor/github.com/cshum/vipsgen/vips/connection.c
generated
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
// Code generated by github.com/cshum/vipsgen from libvips 8.17.2; DO NOT EDIT.
|
||||
|
||||
#include "connection.h"
|
||||
|
||||
static gint64 go_read(VipsSourceCustom *source_custom, void *buffer, gint64 length, void* ptr)
|
||||
{
|
||||
return goSourceRead(ptr, buffer, length);
|
||||
}
|
||||
|
||||
static gint64 go_seek(VipsSourceCustom *source_custom, gint64 offset, int whence, void* ptr)
|
||||
{
|
||||
return goSourceSeek(ptr, offset, whence);
|
||||
}
|
||||
|
||||
static gint64 go_write(VipsTargetCustom *target_custom, void *buffer, gint64 length, void* ptr)
|
||||
{
|
||||
return goTargetWrite(ptr, buffer, length);
|
||||
}
|
||||
|
||||
VipsSourceCustom * create_go_custom_source(void* ptr)
|
||||
{
|
||||
VipsSourceCustom * source_custom = vips_source_custom_new();
|
||||
g_signal_connect(source_custom, "read", G_CALLBACK(go_read), ptr);
|
||||
return source_custom;
|
||||
}
|
||||
|
||||
VipsSourceCustom * create_go_custom_source_with_seek(void* ptr)
|
||||
{
|
||||
VipsSourceCustom * source_custom = vips_source_custom_new();
|
||||
g_signal_connect(source_custom, "read", G_CALLBACK(go_read), ptr);
|
||||
g_signal_connect(source_custom, "seek", G_CALLBACK(go_seek), ptr);
|
||||
return source_custom;
|
||||
}
|
||||
|
||||
VipsTargetCustom * create_go_custom_target(void* ptr)
|
||||
{
|
||||
VipsTargetCustom * target_custom = vips_target_custom_new();
|
||||
g_signal_connect(target_custom, "write", G_CALLBACK(go_write), ptr);
|
||||
return target_custom;
|
||||
}
|
||||
|
||||
void clear_source(VipsSourceCustom **source_custom) {
|
||||
if (G_IS_OBJECT(*source_custom)) g_clear_object(source_custom);
|
||||
}
|
||||
|
||||
void clear_target(VipsTargetCustom **target_custom) {
|
||||
if (G_IS_OBJECT(*target_custom)) g_clear_object(target_custom);
|
||||
}
|
||||
97
vendor/github.com/cshum/vipsgen/vips/connection.go
generated
vendored
Normal file
97
vendor/github.com/cshum/vipsgen/vips/connection.go
generated
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
// Code generated by github.com/cshum/vipsgen from libvips 8.17.2; DO NOT EDIT.
|
||||
|
||||
package vips
|
||||
|
||||
// #include "connection.h"
|
||||
import "C"
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/cshum/vipsgen/pointer"
|
||||
"io"
|
||||
"sync"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// Source contains a libvips VipsSourceCustom and manages its lifecycle.
|
||||
type Source struct {
|
||||
reader io.ReadCloser
|
||||
seeker io.Seeker
|
||||
src *C.VipsSourceCustom
|
||||
ptr unsafe.Pointer
|
||||
lock sync.Mutex
|
||||
}
|
||||
|
||||
// NewSource creates Source from reader
|
||||
func NewSource(reader io.ReadCloser) *Source {
|
||||
Startup(nil)
|
||||
s := &Source{reader: reader}
|
||||
seeker, ok := reader.(io.ReadSeeker)
|
||||
if ok {
|
||||
s.seeker = seeker
|
||||
s.ptr = pointer.Save(s)
|
||||
s.src = C.create_go_custom_source_with_seek(s.ptr)
|
||||
} else {
|
||||
s.ptr = pointer.Save(s)
|
||||
s.src = C.create_go_custom_source(s.ptr)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// Close source
|
||||
func (s *Source) Close() {
|
||||
if s == nil {
|
||||
return
|
||||
}
|
||||
s.lock.Lock()
|
||||
if s.ptr != nil {
|
||||
C.clear_source(&s.src)
|
||||
pointer.Unref(s.ptr)
|
||||
s.ptr = nil
|
||||
s.lock.Unlock()
|
||||
if s.reader != nil {
|
||||
_ = s.reader.Close()
|
||||
s.reader = nil
|
||||
}
|
||||
log("vipsgen", LogLevelDebug, fmt.Sprintf("closing source %p", s))
|
||||
} else {
|
||||
s.lock.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
// Target contains a libvips VipsTargetCustom and manages its lifecycle.
|
||||
type Target struct {
|
||||
writer io.WriteCloser
|
||||
target *C.VipsTargetCustom
|
||||
ptr unsafe.Pointer
|
||||
lock sync.Mutex
|
||||
}
|
||||
|
||||
// NewTarget creates Target from writer
|
||||
func NewTarget(writer io.WriteCloser) *Target {
|
||||
Startup(nil)
|
||||
t := &Target{writer: writer}
|
||||
t.ptr = pointer.Save(t)
|
||||
t.target = C.create_go_custom_target(t.ptr)
|
||||
return t
|
||||
}
|
||||
|
||||
// Close target
|
||||
func (t *Target) Close() {
|
||||
if t == nil {
|
||||
return
|
||||
}
|
||||
t.lock.Lock()
|
||||
if t.ptr != nil {
|
||||
C.clear_target(&t.target)
|
||||
pointer.Unref(t.ptr)
|
||||
t.ptr = nil
|
||||
t.lock.Unlock()
|
||||
if t.writer != nil {
|
||||
_ = t.writer.Close()
|
||||
t.writer = nil
|
||||
}
|
||||
log("vipsgen", LogLevelDebug, fmt.Sprintf("closing target %p", t))
|
||||
} else {
|
||||
t.lock.Unlock()
|
||||
}
|
||||
}
|
||||
19
vendor/github.com/cshum/vipsgen/vips/connection.h
generated
vendored
Normal file
19
vendor/github.com/cshum/vipsgen/vips/connection.h
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
// Code generated by github.com/cshum/vipsgen from libvips 8.17.2; DO NOT EDIT.
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <vips/vips.h>
|
||||
|
||||
extern long long goSourceRead(void*, void *, long long);
|
||||
extern long long goSourceSeek(void*, long long, int);
|
||||
extern long long goTargetWrite(void*, void *, long long);
|
||||
|
||||
static gint64 go_read(VipsSourceCustom *source_custom, void *buffer, gint64 length, void* ptr);
|
||||
static gint64 go_seek(VipsSourceCustom *source_custom, gint64 offset, int whence, void* ptr);
|
||||
static gint64 go_write(VipsTargetCustom *target_custom, void *buffer, gint64 length, void* ptr);
|
||||
|
||||
VipsSourceCustom * create_go_custom_source(void* ptr);
|
||||
VipsSourceCustom * create_go_custom_source_with_seek(void* ptr);
|
||||
VipsTargetCustom * create_go_custom_target(void* ptr);
|
||||
|
||||
void clear_source(VipsSourceCustom **source_custom);
|
||||
void clear_target(VipsTargetCustom **target_custom);
|
||||
10776
vendor/github.com/cshum/vipsgen/vips/image.go
generated
vendored
Normal file
10776
vendor/github.com/cshum/vipsgen/vips/image.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
818
vendor/github.com/cshum/vipsgen/vips/types.go
generated
vendored
Normal file
818
vendor/github.com/cshum/vipsgen/vips/types.go
generated
vendored
Normal file
@@ -0,0 +1,818 @@
|
||||
// Code generated by github.com/cshum/vipsgen from libvips 8.17.2; DO NOT EDIT.
|
||||
|
||||
package vips
|
||||
|
||||
// #include <vips/vips.h>
|
||||
import "C"
|
||||
import (
|
||||
"strings"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// ImageType represents an image type
|
||||
type ImageType string
|
||||
|
||||
// ImageType enum
|
||||
const (
|
||||
ImageTypeUnknown ImageType = "unknown"
|
||||
ImageTypeJpeg ImageType = "jpeg"
|
||||
ImageTypeGif ImageType = "gif"
|
||||
ImageTypePng ImageType = "png"
|
||||
ImageTypeWebp ImageType = "webp"
|
||||
ImageTypeHeif ImageType = "heif"
|
||||
ImageTypeSvg ImageType = "svg"
|
||||
ImageTypeTiff ImageType = "tiff"
|
||||
ImageTypeJp2k ImageType = "jp2k"
|
||||
ImageTypeAvif ImageType = "avif"
|
||||
ImageTypePdf ImageType = "pdf"
|
||||
ImageTypeBmp ImageType = "bmp"
|
||||
ImageTypeMagick ImageType = "magick"
|
||||
ImageTypeAnalyze ImageType = "analyze"
|
||||
ImageTypeCsv ImageType = "csv"
|
||||
ImageTypeDz ImageType = "dz"
|
||||
ImageTypeFits ImageType = "fits"
|
||||
ImageTypeJxl ImageType = "jxl"
|
||||
ImageTypeMat ImageType = "mat"
|
||||
ImageTypeMatrix ImageType = "matrix"
|
||||
ImageTypeOpenexr ImageType = "openexr"
|
||||
ImageTypeOpenslide ImageType = "openslide"
|
||||
ImageTypePpm ImageType = "ppm"
|
||||
ImageTypeRad ImageType = "rad"
|
||||
ImageTypeRaw ImageType = "raw"
|
||||
ImageTypeVips ImageType = "vips"
|
||||
)
|
||||
|
||||
|
||||
// Access represents VipsAccess type
|
||||
type Access int
|
||||
|
||||
// Access enum
|
||||
const (
|
||||
AccessRandom Access = C.VIPS_ACCESS_RANDOM
|
||||
AccessSequential Access = C.VIPS_ACCESS_SEQUENTIAL
|
||||
AccessSequentialUnbuffered Access = C.VIPS_ACCESS_SEQUENTIAL_UNBUFFERED
|
||||
AccessLast Access = C.VIPS_ACCESS_LAST
|
||||
)
|
||||
|
||||
// Align represents VipsAlign type
|
||||
type Align int
|
||||
|
||||
// Align enum
|
||||
const (
|
||||
AlignLow Align = C.VIPS_ALIGN_LOW
|
||||
AlignCentre Align = C.VIPS_ALIGN_CENTRE
|
||||
AlignHigh Align = C.VIPS_ALIGN_HIGH
|
||||
AlignLast Align = C.VIPS_ALIGN_LAST
|
||||
)
|
||||
|
||||
// Angle represents VipsAngle type
|
||||
type Angle int
|
||||
|
||||
// Angle enum
|
||||
const (
|
||||
AngleD0 Angle = C.VIPS_ANGLE_D0
|
||||
AngleD90 Angle = C.VIPS_ANGLE_D90
|
||||
AngleD180 Angle = C.VIPS_ANGLE_D180
|
||||
AngleD270 Angle = C.VIPS_ANGLE_D270
|
||||
AngleLast Angle = C.VIPS_ANGLE_LAST
|
||||
)
|
||||
|
||||
// Angle45 represents VipsAngle45 type
|
||||
type Angle45 int
|
||||
|
||||
// Angle45 enum
|
||||
const (
|
||||
Angle45D0 Angle45 = C.VIPS_ANGLE45_D0
|
||||
Angle45D45 Angle45 = C.VIPS_ANGLE45_D45
|
||||
Angle45D90 Angle45 = C.VIPS_ANGLE45_D90
|
||||
Angle45D135 Angle45 = C.VIPS_ANGLE45_D135
|
||||
Angle45D180 Angle45 = C.VIPS_ANGLE45_D180
|
||||
Angle45D225 Angle45 = C.VIPS_ANGLE45_D225
|
||||
Angle45D270 Angle45 = C.VIPS_ANGLE45_D270
|
||||
Angle45D315 Angle45 = C.VIPS_ANGLE45_D315
|
||||
Angle45Last Angle45 = C.VIPS_ANGLE45_LAST
|
||||
)
|
||||
|
||||
// BandFormat represents VipsBandFormat 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
|
||||
BandFormatLast BandFormat = C.VIPS_FORMAT_LAST
|
||||
)
|
||||
|
||||
// BlendMode represents VipsBlendMode type
|
||||
type BlendMode int
|
||||
|
||||
// BlendMode enum
|
||||
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
|
||||
BlendModeColourDodge BlendMode = C.VIPS_BLEND_MODE_COLOUR_DODGE
|
||||
BlendModeColourBurn 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
|
||||
BlendModeLast BlendMode = C.VIPS_BLEND_MODE_LAST
|
||||
)
|
||||
|
||||
// Coding represents VipsCoding type
|
||||
type Coding int
|
||||
|
||||
// Coding enum
|
||||
const (
|
||||
CodingError Coding = C.VIPS_CODING_ERROR
|
||||
CodingNone Coding = C.VIPS_CODING_NONE
|
||||
CodingLabq Coding = C.VIPS_CODING_LABQ
|
||||
CodingRad Coding = C.VIPS_CODING_RAD
|
||||
CodingLast Coding = C.VIPS_CODING_LAST
|
||||
)
|
||||
|
||||
// Combine represents VipsCombine type
|
||||
type Combine int
|
||||
|
||||
// Combine enum
|
||||
const (
|
||||
CombineMax Combine = C.VIPS_COMBINE_MAX
|
||||
CombineSum Combine = C.VIPS_COMBINE_SUM
|
||||
CombineMin Combine = C.VIPS_COMBINE_MIN
|
||||
CombineLast Combine = C.VIPS_COMBINE_LAST
|
||||
)
|
||||
|
||||
// CombineMode represents VipsCombineMode type
|
||||
type CombineMode int
|
||||
|
||||
// CombineMode enum
|
||||
const (
|
||||
CombineModeSet CombineMode = C.VIPS_COMBINE_MODE_SET
|
||||
CombineModeAdd CombineMode = C.VIPS_COMBINE_MODE_ADD
|
||||
CombineModeLast CombineMode = C.VIPS_COMBINE_MODE_LAST
|
||||
)
|
||||
|
||||
// CompassDirection represents VipsCompassDirection type
|
||||
type CompassDirection int
|
||||
|
||||
// CompassDirection enum
|
||||
const (
|
||||
CompassDirectionCentre CompassDirection = C.VIPS_COMPASS_DIRECTION_CENTRE
|
||||
CompassDirectionNorth CompassDirection = C.VIPS_COMPASS_DIRECTION_NORTH
|
||||
CompassDirectionEast CompassDirection = C.VIPS_COMPASS_DIRECTION_EAST
|
||||
CompassDirectionSouth CompassDirection = C.VIPS_COMPASS_DIRECTION_SOUTH
|
||||
CompassDirectionWest CompassDirection = C.VIPS_COMPASS_DIRECTION_WEST
|
||||
CompassDirectionNorthEast CompassDirection = C.VIPS_COMPASS_DIRECTION_NORTH_EAST
|
||||
CompassDirectionSouthEast CompassDirection = C.VIPS_COMPASS_DIRECTION_SOUTH_EAST
|
||||
CompassDirectionSouthWest CompassDirection = C.VIPS_COMPASS_DIRECTION_SOUTH_WEST
|
||||
CompassDirectionNorthWest CompassDirection = C.VIPS_COMPASS_DIRECTION_NORTH_WEST
|
||||
CompassDirectionLast CompassDirection = C.VIPS_COMPASS_DIRECTION_LAST
|
||||
)
|
||||
|
||||
// Direction represents VipsDirection type
|
||||
type Direction int
|
||||
|
||||
// Direction enum
|
||||
const (
|
||||
DirectionHorizontal Direction = C.VIPS_DIRECTION_HORIZONTAL
|
||||
DirectionVertical Direction = C.VIPS_DIRECTION_VERTICAL
|
||||
DirectionLast Direction = C.VIPS_DIRECTION_LAST
|
||||
)
|
||||
|
||||
// Extend represents VipsExtend type
|
||||
type Extend int
|
||||
|
||||
// Extend enum
|
||||
const (
|
||||
ExtendBlack Extend = C.VIPS_EXTEND_BLACK
|
||||
ExtendCopy Extend = C.VIPS_EXTEND_COPY
|
||||
ExtendRepeat Extend = C.VIPS_EXTEND_REPEAT
|
||||
ExtendMirror Extend = C.VIPS_EXTEND_MIRROR
|
||||
ExtendWhite Extend = C.VIPS_EXTEND_WHITE
|
||||
ExtendBackground Extend = C.VIPS_EXTEND_BACKGROUND
|
||||
ExtendLast Extend = C.VIPS_EXTEND_LAST
|
||||
)
|
||||
|
||||
// FailOn represents VipsFailOn type
|
||||
type FailOn int
|
||||
|
||||
// FailOn enum
|
||||
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
|
||||
FailOnLast FailOn = C.VIPS_FAIL_ON_LAST
|
||||
)
|
||||
|
||||
// DzContainer represents VipsForeignDzContainer type
|
||||
type DzContainer int
|
||||
|
||||
// DzContainer enum
|
||||
const (
|
||||
DzContainerFs DzContainer = C.VIPS_FOREIGN_DZ_CONTAINER_FS
|
||||
DzContainerZip DzContainer = C.VIPS_FOREIGN_DZ_CONTAINER_ZIP
|
||||
DzContainerSzi DzContainer = C.VIPS_FOREIGN_DZ_CONTAINER_SZI
|
||||
DzContainerLast DzContainer = C.VIPS_FOREIGN_DZ_CONTAINER_LAST
|
||||
)
|
||||
|
||||
// DzDepth represents VipsForeignDzDepth type
|
||||
type DzDepth int
|
||||
|
||||
// DzDepth enum
|
||||
const (
|
||||
DzDepthOnepixel DzDepth = C.VIPS_FOREIGN_DZ_DEPTH_ONEPIXEL
|
||||
DzDepthOnetile DzDepth = C.VIPS_FOREIGN_DZ_DEPTH_ONETILE
|
||||
DzDepthOne DzDepth = C.VIPS_FOREIGN_DZ_DEPTH_ONE
|
||||
DzDepthLast DzDepth = C.VIPS_FOREIGN_DZ_DEPTH_LAST
|
||||
)
|
||||
|
||||
// DzLayout represents VipsForeignDzLayout type
|
||||
type DzLayout int
|
||||
|
||||
// DzLayout enum
|
||||
const (
|
||||
DzLayoutDz DzLayout = C.VIPS_FOREIGN_DZ_LAYOUT_DZ
|
||||
DzLayoutZoomify DzLayout = C.VIPS_FOREIGN_DZ_LAYOUT_ZOOMIFY
|
||||
DzLayoutGoogle DzLayout = C.VIPS_FOREIGN_DZ_LAYOUT_GOOGLE
|
||||
DzLayoutIiif DzLayout = C.VIPS_FOREIGN_DZ_LAYOUT_IIIF
|
||||
DzLayoutIiif3 DzLayout = C.VIPS_FOREIGN_DZ_LAYOUT_IIIF3
|
||||
DzLayoutLast DzLayout = C.VIPS_FOREIGN_DZ_LAYOUT_LAST
|
||||
)
|
||||
|
||||
// Flags represents VipsForeignFlags type
|
||||
type Flags int
|
||||
|
||||
// Flags enum
|
||||
const (
|
||||
FlagsNone Flags = C.VIPS_FOREIGN_NONE
|
||||
FlagsPartial Flags = C.VIPS_FOREIGN_PARTIAL
|
||||
FlagsBigendian Flags = C.VIPS_FOREIGN_BIGENDIAN
|
||||
FlagsSequential Flags = C.VIPS_FOREIGN_SEQUENTIAL
|
||||
FlagsAll Flags = C.VIPS_FOREIGN_ALL
|
||||
)
|
||||
|
||||
// HeifCompression represents VipsForeignHeifCompression type
|
||||
type HeifCompression int
|
||||
|
||||
// HeifCompression enum
|
||||
const (
|
||||
HeifCompressionHevc HeifCompression = C.VIPS_FOREIGN_HEIF_COMPRESSION_HEVC
|
||||
HeifCompressionAvc HeifCompression = C.VIPS_FOREIGN_HEIF_COMPRESSION_AVC
|
||||
HeifCompressionJpeg HeifCompression = C.VIPS_FOREIGN_HEIF_COMPRESSION_JPEG
|
||||
HeifCompressionAv1 HeifCompression = C.VIPS_FOREIGN_HEIF_COMPRESSION_AV1
|
||||
HeifCompressionLast HeifCompression = C.VIPS_FOREIGN_HEIF_COMPRESSION_LAST
|
||||
)
|
||||
|
||||
// HeifEncoder represents VipsForeignHeifEncoder type
|
||||
type HeifEncoder int
|
||||
|
||||
// HeifEncoder enum
|
||||
const (
|
||||
HeifEncoderAuto HeifEncoder = C.VIPS_FOREIGN_HEIF_ENCODER_AUTO
|
||||
HeifEncoderAom HeifEncoder = C.VIPS_FOREIGN_HEIF_ENCODER_AOM
|
||||
HeifEncoderRav1e HeifEncoder = C.VIPS_FOREIGN_HEIF_ENCODER_RAV1E
|
||||
HeifEncoderSvt HeifEncoder = C.VIPS_FOREIGN_HEIF_ENCODER_SVT
|
||||
HeifEncoderX265 HeifEncoder = C.VIPS_FOREIGN_HEIF_ENCODER_X265
|
||||
HeifEncoderLast HeifEncoder = C.VIPS_FOREIGN_HEIF_ENCODER_LAST
|
||||
)
|
||||
|
||||
// Keep represents VipsForeignKeep type
|
||||
type Keep int
|
||||
|
||||
// Keep enum
|
||||
const (
|
||||
KeepNone Keep = C.VIPS_FOREIGN_KEEP_NONE
|
||||
KeepExif Keep = C.VIPS_FOREIGN_KEEP_EXIF
|
||||
KeepXmp Keep = C.VIPS_FOREIGN_KEEP_XMP
|
||||
KeepIptc Keep = C.VIPS_FOREIGN_KEEP_IPTC
|
||||
KeepIcc Keep = C.VIPS_FOREIGN_KEEP_ICC
|
||||
KeepOther Keep = C.VIPS_FOREIGN_KEEP_OTHER
|
||||
KeepAll Keep = C.VIPS_FOREIGN_KEEP_ALL
|
||||
)
|
||||
|
||||
// PngFilter represents VipsForeignPngFilter type
|
||||
type PngFilter int
|
||||
|
||||
// PngFilter enum
|
||||
const (
|
||||
PngFilterNone PngFilter = C.VIPS_FOREIGN_PNG_FILTER_NONE
|
||||
PngFilterSub PngFilter = C.VIPS_FOREIGN_PNG_FILTER_SUB
|
||||
PngFilterUp PngFilter = C.VIPS_FOREIGN_PNG_FILTER_UP
|
||||
PngFilterAvg PngFilter = C.VIPS_FOREIGN_PNG_FILTER_AVG
|
||||
PngFilterPaeth PngFilter = C.VIPS_FOREIGN_PNG_FILTER_PAETH
|
||||
PngFilterAll PngFilter = C.VIPS_FOREIGN_PNG_FILTER_ALL
|
||||
)
|
||||
|
||||
// PpmFormat represents VipsForeignPpmFormat type
|
||||
type PpmFormat int
|
||||
|
||||
// PpmFormat enum
|
||||
const (
|
||||
PpmFormatPbm PpmFormat = C.VIPS_FOREIGN_PPM_FORMAT_PBM
|
||||
PpmFormatPgm PpmFormat = C.VIPS_FOREIGN_PPM_FORMAT_PGM
|
||||
PpmFormatPpm PpmFormat = C.VIPS_FOREIGN_PPM_FORMAT_PPM
|
||||
PpmFormatPfm PpmFormat = C.VIPS_FOREIGN_PPM_FORMAT_PFM
|
||||
PpmFormatPnm PpmFormat = C.VIPS_FOREIGN_PPM_FORMAT_PNM
|
||||
PpmFormatLast PpmFormat = C.VIPS_FOREIGN_PPM_FORMAT_LAST
|
||||
)
|
||||
|
||||
// Subsample represents VipsForeignSubsample type
|
||||
type Subsample int
|
||||
|
||||
// Subsample enum
|
||||
const (
|
||||
SubsampleAuto Subsample = C.VIPS_FOREIGN_SUBSAMPLE_AUTO
|
||||
SubsampleOn Subsample = C.VIPS_FOREIGN_SUBSAMPLE_ON
|
||||
SubsampleOff Subsample = C.VIPS_FOREIGN_SUBSAMPLE_OFF
|
||||
SubsampleLast Subsample = C.VIPS_FOREIGN_SUBSAMPLE_LAST
|
||||
)
|
||||
|
||||
// TiffCompression represents VipsForeignTiffCompression type
|
||||
type TiffCompression int
|
||||
|
||||
// TiffCompression enum
|
||||
const (
|
||||
TiffCompressionNone TiffCompression = C.VIPS_FOREIGN_TIFF_COMPRESSION_NONE
|
||||
TiffCompressionJpeg TiffCompression = C.VIPS_FOREIGN_TIFF_COMPRESSION_JPEG
|
||||
TiffCompressionDeflate TiffCompression = C.VIPS_FOREIGN_TIFF_COMPRESSION_DEFLATE
|
||||
TiffCompressionPackbits TiffCompression = C.VIPS_FOREIGN_TIFF_COMPRESSION_PACKBITS
|
||||
TiffCompressionCcittfax4 TiffCompression = C.VIPS_FOREIGN_TIFF_COMPRESSION_CCITTFAX4
|
||||
TiffCompressionLzw TiffCompression = C.VIPS_FOREIGN_TIFF_COMPRESSION_LZW
|
||||
TiffCompressionWebp TiffCompression = C.VIPS_FOREIGN_TIFF_COMPRESSION_WEBP
|
||||
TiffCompressionZstd TiffCompression = C.VIPS_FOREIGN_TIFF_COMPRESSION_ZSTD
|
||||
TiffCompressionJp2k TiffCompression = C.VIPS_FOREIGN_TIFF_COMPRESSION_JP2K
|
||||
TiffCompressionLast TiffCompression = C.VIPS_FOREIGN_TIFF_COMPRESSION_LAST
|
||||
)
|
||||
|
||||
// TiffPredictor represents VipsForeignTiffPredictor type
|
||||
type TiffPredictor int
|
||||
|
||||
// TiffPredictor enum
|
||||
const (
|
||||
TiffPredictorNone TiffPredictor = C.VIPS_FOREIGN_TIFF_PREDICTOR_NONE
|
||||
TiffPredictorHorizontal TiffPredictor = C.VIPS_FOREIGN_TIFF_PREDICTOR_HORIZONTAL
|
||||
TiffPredictorFloat TiffPredictor = C.VIPS_FOREIGN_TIFF_PREDICTOR_FLOAT
|
||||
TiffPredictorLast TiffPredictor = C.VIPS_FOREIGN_TIFF_PREDICTOR_LAST
|
||||
)
|
||||
|
||||
// TiffResunit represents VipsForeignTiffResunit type
|
||||
type TiffResunit int
|
||||
|
||||
// TiffResunit enum
|
||||
const (
|
||||
TiffResunitCm TiffResunit = C.VIPS_FOREIGN_TIFF_RESUNIT_CM
|
||||
TiffResunitInch TiffResunit = C.VIPS_FOREIGN_TIFF_RESUNIT_INCH
|
||||
TiffResunitLast TiffResunit = C.VIPS_FOREIGN_TIFF_RESUNIT_LAST
|
||||
)
|
||||
|
||||
// WebpPreset represents VipsForeignWebpPreset type
|
||||
type WebpPreset int
|
||||
|
||||
// WebpPreset enum
|
||||
const (
|
||||
WebpPresetDefault WebpPreset = C.VIPS_FOREIGN_WEBP_PRESET_DEFAULT
|
||||
WebpPresetPicture WebpPreset = C.VIPS_FOREIGN_WEBP_PRESET_PICTURE
|
||||
WebpPresetPhoto WebpPreset = C.VIPS_FOREIGN_WEBP_PRESET_PHOTO
|
||||
WebpPresetDrawing WebpPreset = C.VIPS_FOREIGN_WEBP_PRESET_DRAWING
|
||||
WebpPresetIcon WebpPreset = C.VIPS_FOREIGN_WEBP_PRESET_ICON
|
||||
WebpPresetText WebpPreset = C.VIPS_FOREIGN_WEBP_PRESET_TEXT
|
||||
WebpPresetLast WebpPreset = C.VIPS_FOREIGN_WEBP_PRESET_LAST
|
||||
)
|
||||
|
||||
// Intent represents VipsIntent 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
|
||||
IntentAuto Intent = C.VIPS_INTENT_AUTO
|
||||
IntentLast Intent = C.VIPS_INTENT_LAST
|
||||
)
|
||||
|
||||
// Interesting represents VipsInteresting type
|
||||
type Interesting int
|
||||
|
||||
// Interesting enum
|
||||
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
|
||||
)
|
||||
|
||||
// Interpretation represents VipsInterpretation 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
|
||||
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
|
||||
InterpretationRgb16 Interpretation = C.VIPS_INTERPRETATION_RGB16
|
||||
InterpretationGrey16 Interpretation = C.VIPS_INTERPRETATION_GREY16
|
||||
InterpretationMatrix Interpretation = C.VIPS_INTERPRETATION_MATRIX
|
||||
InterpretationScrgb Interpretation = C.VIPS_INTERPRETATION_scRGB
|
||||
InterpretationHsv Interpretation = C.VIPS_INTERPRETATION_HSV
|
||||
InterpretationLast Interpretation = C.VIPS_INTERPRETATION_LAST
|
||||
)
|
||||
|
||||
// Kernel represents VipsKernel type
|
||||
type Kernel int
|
||||
|
||||
// Kernel enum
|
||||
const (
|
||||
KernelNearest Kernel = C.VIPS_KERNEL_NEAREST
|
||||
KernelLinear Kernel = C.VIPS_KERNEL_LINEAR
|
||||
KernelCubic Kernel = C.VIPS_KERNEL_CUBIC
|
||||
KernelMitchell Kernel = C.VIPS_KERNEL_MITCHELL
|
||||
KernelLanczos2 Kernel = C.VIPS_KERNEL_LANCZOS2
|
||||
KernelLanczos3 Kernel = C.VIPS_KERNEL_LANCZOS3
|
||||
KernelMks2013 Kernel = C.VIPS_KERNEL_MKS2013
|
||||
KernelMks2021 Kernel = C.VIPS_KERNEL_MKS2021
|
||||
KernelLast Kernel = C.VIPS_KERNEL_LAST
|
||||
)
|
||||
|
||||
// OperationBoolean represents VipsOperationBoolean type
|
||||
type OperationBoolean int
|
||||
|
||||
// OperationBoolean enum
|
||||
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
|
||||
OperationBooleanLast OperationBoolean = C.VIPS_OPERATION_BOOLEAN_LAST
|
||||
)
|
||||
|
||||
// OperationComplex represents VipsOperationComplex type
|
||||
type OperationComplex int
|
||||
|
||||
// OperationComplex enum
|
||||
const (
|
||||
OperationComplexPolar OperationComplex = C.VIPS_OPERATION_COMPLEX_POLAR
|
||||
OperationComplexRect OperationComplex = C.VIPS_OPERATION_COMPLEX_RECT
|
||||
OperationComplexConj OperationComplex = C.VIPS_OPERATION_COMPLEX_CONJ
|
||||
OperationComplexLast OperationComplex = C.VIPS_OPERATION_COMPLEX_LAST
|
||||
)
|
||||
|
||||
// OperationComplex2 represents VipsOperationComplex2 type
|
||||
type OperationComplex2 int
|
||||
|
||||
// OperationComplex2 enum
|
||||
const (
|
||||
OperationComplex2CrossPhase OperationComplex2 = C.VIPS_OPERATION_COMPLEX2_CROSS_PHASE
|
||||
OperationComplex2Last OperationComplex2 = C.VIPS_OPERATION_COMPLEX2_LAST
|
||||
)
|
||||
|
||||
// OperationComplexget represents VipsOperationComplexget type
|
||||
type OperationComplexget int
|
||||
|
||||
// OperationComplexget enum
|
||||
const (
|
||||
OperationComplexgetReal OperationComplexget = C.VIPS_OPERATION_COMPLEXGET_REAL
|
||||
OperationComplexgetImag OperationComplexget = C.VIPS_OPERATION_COMPLEXGET_IMAG
|
||||
OperationComplexgetLast OperationComplexget = C.VIPS_OPERATION_COMPLEXGET_LAST
|
||||
)
|
||||
|
||||
// OperationMath represents VipsOperationMath type
|
||||
type OperationMath int
|
||||
|
||||
// OperationMath enum
|
||||
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
|
||||
OperationMathSinh OperationMath = C.VIPS_OPERATION_MATH_SINH
|
||||
OperationMathCosh OperationMath = C.VIPS_OPERATION_MATH_COSH
|
||||
OperationMathTanh OperationMath = C.VIPS_OPERATION_MATH_TANH
|
||||
OperationMathAsinh OperationMath = C.VIPS_OPERATION_MATH_ASINH
|
||||
OperationMathAcosh OperationMath = C.VIPS_OPERATION_MATH_ACOSH
|
||||
OperationMathAtanh OperationMath = C.VIPS_OPERATION_MATH_ATANH
|
||||
OperationMathLast OperationMath = C.VIPS_OPERATION_MATH_LAST
|
||||
)
|
||||
|
||||
// OperationMath2 represents VipsOperationMath2 type
|
||||
type OperationMath2 int
|
||||
|
||||
// OperationMath2 enum
|
||||
const (
|
||||
OperationMath2Pow OperationMath2 = C.VIPS_OPERATION_MATH2_POW
|
||||
OperationMath2Wop OperationMath2 = C.VIPS_OPERATION_MATH2_WOP
|
||||
OperationMath2Atan2 OperationMath2 = C.VIPS_OPERATION_MATH2_ATAN2
|
||||
OperationMath2Last OperationMath2 = C.VIPS_OPERATION_MATH2_LAST
|
||||
)
|
||||
|
||||
// OperationMorphology represents VipsOperationMorphology type
|
||||
type OperationMorphology int
|
||||
|
||||
// OperationMorphology enum
|
||||
const (
|
||||
OperationMorphologyErode OperationMorphology = C.VIPS_OPERATION_MORPHOLOGY_ERODE
|
||||
OperationMorphologyDilate OperationMorphology = C.VIPS_OPERATION_MORPHOLOGY_DILATE
|
||||
OperationMorphologyLast OperationMorphology = C.VIPS_OPERATION_MORPHOLOGY_LAST
|
||||
)
|
||||
|
||||
// OperationRelational represents VipsOperationRelational type
|
||||
type OperationRelational int
|
||||
|
||||
// OperationRelational enum
|
||||
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
|
||||
OperationRelationalLast OperationRelational = C.VIPS_OPERATION_RELATIONAL_LAST
|
||||
)
|
||||
|
||||
// OperationRound represents VipsOperationRound type
|
||||
type OperationRound int
|
||||
|
||||
// OperationRound enum
|
||||
const (
|
||||
OperationRoundRint OperationRound = C.VIPS_OPERATION_ROUND_RINT
|
||||
OperationRoundCeil OperationRound = C.VIPS_OPERATION_ROUND_CEIL
|
||||
OperationRoundFloor OperationRound = C.VIPS_OPERATION_ROUND_FLOOR
|
||||
OperationRoundLast OperationRound = C.VIPS_OPERATION_ROUND_LAST
|
||||
)
|
||||
|
||||
// PCS represents VipsPCS type
|
||||
type PCS int
|
||||
|
||||
// PCS enum
|
||||
const (
|
||||
PcsLab PCS = C.VIPS_PCS_LAB
|
||||
PcsXyz PCS = C.VIPS_PCS_XYZ
|
||||
PcsLast PCS = C.VIPS_PCS_LAST
|
||||
)
|
||||
|
||||
// Precision represents VipsPrecision type
|
||||
type Precision int
|
||||
|
||||
// Precision enum
|
||||
const (
|
||||
PrecisionInteger Precision = C.VIPS_PRECISION_INTEGER
|
||||
PrecisionFloat Precision = C.VIPS_PRECISION_FLOAT
|
||||
PrecisionApproximate Precision = C.VIPS_PRECISION_APPROXIMATE
|
||||
PrecisionLast Precision = C.VIPS_PRECISION_LAST
|
||||
)
|
||||
|
||||
// RegionShrink represents VipsRegionShrink type
|
||||
type RegionShrink int
|
||||
|
||||
// RegionShrink enum
|
||||
const (
|
||||
RegionShrinkMean RegionShrink = C.VIPS_REGION_SHRINK_MEAN
|
||||
RegionShrinkMedian RegionShrink = C.VIPS_REGION_SHRINK_MEDIAN
|
||||
RegionShrinkMode RegionShrink = C.VIPS_REGION_SHRINK_MODE
|
||||
RegionShrinkMax RegionShrink = C.VIPS_REGION_SHRINK_MAX
|
||||
RegionShrinkMin RegionShrink = C.VIPS_REGION_SHRINK_MIN
|
||||
RegionShrinkNearest RegionShrink = C.VIPS_REGION_SHRINK_NEAREST
|
||||
RegionShrinkLast RegionShrink = C.VIPS_REGION_SHRINK_LAST
|
||||
)
|
||||
|
||||
// SdfShape represents VipsSdfShape type
|
||||
type SdfShape int
|
||||
|
||||
// SdfShape enum
|
||||
const (
|
||||
SdfShapeCircle SdfShape = C.VIPS_SDF_SHAPE_CIRCLE
|
||||
SdfShapeBox SdfShape = C.VIPS_SDF_SHAPE_BOX
|
||||
SdfShapeRoundedBox SdfShape = C.VIPS_SDF_SHAPE_ROUNDED_BOX
|
||||
SdfShapeLine SdfShape = C.VIPS_SDF_SHAPE_LINE
|
||||
SdfShapeLast SdfShape = C.VIPS_SDF_SHAPE_LAST
|
||||
)
|
||||
|
||||
// Size represents VipsSize type
|
||||
type Size int
|
||||
|
||||
// Size enum
|
||||
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
|
||||
)
|
||||
|
||||
// TextWrap represents VipsTextWrap type
|
||||
type TextWrap int
|
||||
|
||||
// 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
|
||||
TextWrapLast TextWrap = C.VIPS_TEXT_WRAP_LAST
|
||||
)
|
||||
|
||||
|
||||
// imageMimeTypes map the various image types to its mime type representation
|
||||
var imageMimeTypes = map[ImageType]string{
|
||||
ImageTypeJpeg: "image/jpeg",
|
||||
ImageTypeGif: "image/gif",
|
||||
ImageTypePng: "image/png",
|
||||
ImageTypeWebp: "image/webp",
|
||||
ImageTypeHeif: "image/heif",
|
||||
ImageTypeSvg: "image/svg+xml",
|
||||
ImageTypeTiff: "image/tiff",
|
||||
ImageTypeJp2k: "image/jp2",
|
||||
ImageTypeAvif: "image/avif",
|
||||
ImageTypePdf: "application/pdf",
|
||||
ImageTypeBmp: "image/bmp",
|
||||
ImageTypeAnalyze: "application/x-analyze",
|
||||
ImageTypeCsv: "text/csv",
|
||||
ImageTypeDz: "image/x-deepzoom",
|
||||
ImageTypeFits: "image/fits",
|
||||
ImageTypeJxl: "image/jxl",
|
||||
ImageTypeMat: "application/x-matlab-data",
|
||||
ImageTypeMatrix: "application/x-matrix",
|
||||
ImageTypeOpenexr: "image/openexr",
|
||||
ImageTypeOpenslide: "application/x-openslide",
|
||||
ImageTypePpm: "image/x-portable-pixmap",
|
||||
ImageTypeRad: "image/rad",
|
||||
ImageTypeRaw: "image/raw",
|
||||
ImageTypeVips: "image/vnd.libvips",
|
||||
}
|
||||
|
||||
// MimeType returns the MIME type for the image type.
|
||||
func (imageType ImageType) MimeType() (mime string, ok bool) {
|
||||
mime, ok = imageMimeTypes[imageType]
|
||||
return
|
||||
}
|
||||
|
||||
// vipsDetermineImageType determine the image type from loader metadata
|
||||
func vipsDetermineImageType(in *C.VipsImage) ImageType {
|
||||
if in != nil {
|
||||
if vipsLoader, ok := vipsImageGetMetaLoader(in); ok {
|
||||
if strings.HasPrefix(vipsLoader, "jpeg") {
|
||||
return ImageTypeJpeg
|
||||
}
|
||||
if strings.HasPrefix(vipsLoader, "gif") {
|
||||
return ImageTypeGif
|
||||
}
|
||||
if strings.HasPrefix(vipsLoader, "png") {
|
||||
return ImageTypePng
|
||||
}
|
||||
if strings.HasPrefix(vipsLoader, "webp") {
|
||||
return ImageTypeWebp
|
||||
}
|
||||
if strings.HasPrefix(vipsLoader, "heif") {
|
||||
return ImageTypeHeif
|
||||
}
|
||||
if strings.HasPrefix(vipsLoader, "svg") {
|
||||
return ImageTypeSvg
|
||||
}
|
||||
if strings.HasPrefix(vipsLoader, "tiff") {
|
||||
return ImageTypeTiff
|
||||
}
|
||||
if strings.HasPrefix(vipsLoader, "jp2k") {
|
||||
return ImageTypeJp2k
|
||||
}
|
||||
if strings.HasPrefix(vipsLoader, "pdf") {
|
||||
return ImageTypePdf
|
||||
}
|
||||
if strings.HasPrefix(vipsLoader, "analyze") {
|
||||
return ImageTypeAnalyze
|
||||
}
|
||||
if strings.HasPrefix(vipsLoader, "csv") {
|
||||
return ImageTypeCsv
|
||||
}
|
||||
if strings.HasPrefix(vipsLoader, "fits") {
|
||||
return ImageTypeFits
|
||||
}
|
||||
if strings.HasPrefix(vipsLoader, "jxl") {
|
||||
return ImageTypeJxl
|
||||
}
|
||||
if strings.HasPrefix(vipsLoader, "mat") {
|
||||
return ImageTypeMat
|
||||
}
|
||||
if strings.HasPrefix(vipsLoader, "matrix") {
|
||||
return ImageTypeMatrix
|
||||
}
|
||||
if strings.HasPrefix(vipsLoader, "openexr") {
|
||||
return ImageTypeOpenexr
|
||||
}
|
||||
if strings.HasPrefix(vipsLoader, "openslide") {
|
||||
return ImageTypeOpenslide
|
||||
}
|
||||
if strings.HasPrefix(vipsLoader, "ppm") {
|
||||
return ImageTypePpm
|
||||
}
|
||||
if strings.HasPrefix(vipsLoader, "rad") {
|
||||
return ImageTypeRad
|
||||
}
|
||||
if strings.HasPrefix(vipsLoader, "raw") {
|
||||
return ImageTypeRaw
|
||||
}
|
||||
if strings.HasPrefix(vipsLoader, "vips") {
|
||||
return ImageTypeVips
|
||||
}
|
||||
if strings.HasPrefix(vipsLoader, "magick") {
|
||||
return ImageTypeMagick
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return ImageTypeUnknown
|
||||
}
|
||||
|
||||
// Interpolate represents VipsInterpolate type
|
||||
type Interpolate struct {
|
||||
interp *C.VipsInterpolate
|
||||
}
|
||||
|
||||
// InterpolateType represents the type of interpolation to use
|
||||
type InterpolateType string
|
||||
|
||||
// InterpolateType enum - these values match the predefined interpolators in libvips
|
||||
const (
|
||||
InterpolateNearest InterpolateType = "nearest"
|
||||
InterpolateBilinear InterpolateType = "bilinear"
|
||||
InterpolateBicubic InterpolateType = "bicubic"
|
||||
InterpolateLbb InterpolateType = "lbb" // Lanczos3
|
||||
InterpolateNohalo InterpolateType = "nohalo"
|
||||
InterpolateVsqbs InterpolateType = "vsqbs"
|
||||
)
|
||||
|
||||
// NewInterpolate creates a new Interpolate with the given name
|
||||
// Valid names include: "nearest", "bilinear", "bicubic", "lbb", "nohalo", "vsqbs"
|
||||
func NewInterpolate(name InterpolateType) *Interpolate {
|
||||
Startup(nil)
|
||||
cName := C.CString(string(name))
|
||||
defer C.free(unsafe.Pointer(cName))
|
||||
|
||||
interp := C.vips_interpolate_new(cName)
|
||||
if interp == nil {
|
||||
// Default to bilinear if requested interpolator not found
|
||||
C.vips_error_clear()
|
||||
cDefault := C.CString("bilinear")
|
||||
defer C.free(unsafe.Pointer(cDefault))
|
||||
interp = C.vips_interpolate_new(cDefault)
|
||||
}
|
||||
return &Interpolate{interp: interp}
|
||||
}
|
||||
|
||||
// Close frees the interpolator resources
|
||||
func (i *Interpolate) Close() {
|
||||
if i != nil && i.interp != nil {
|
||||
C.g_object_unref(C.gpointer(i.interp))
|
||||
i.interp = nil
|
||||
}
|
||||
}
|
||||
25
vendor/github.com/cshum/vipsgen/vips/util.c
generated
vendored
Normal file
25
vendor/github.com/cshum/vipsgen/vips/util.c
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
// Code generated by github.com/cshum/vipsgen from libvips 8.17.2; DO NOT EDIT.
|
||||
|
||||
#include "util.h"
|
||||
|
||||
static void logging_handler(const gchar *log_domain,
|
||||
GLogLevelFlags log_level,
|
||||
const gchar *message, gpointer user_data) {
|
||||
goLoggingHandler((char *)log_domain, (int)log_level, (char *)message);
|
||||
}
|
||||
|
||||
static void null_logging_handler(const gchar *log_domain,
|
||||
GLogLevelFlags log_level, const gchar *message,
|
||||
gpointer user_data) {}
|
||||
|
||||
void set_logging_handler(void) {
|
||||
g_log_set_default_handler(logging_handler, NULL);
|
||||
}
|
||||
|
||||
void unset_logging_handler(void) {
|
||||
g_log_set_default_handler(null_logging_handler, NULL);
|
||||
}
|
||||
|
||||
int is_gobject(void* obj) {
|
||||
return G_IS_OBJECT(obj) ? 1 : 0;
|
||||
}
|
||||
474
vendor/github.com/cshum/vipsgen/vips/util.go
generated
vendored
Normal file
474
vendor/github.com/cshum/vipsgen/vips/util.go
generated
vendored
Normal file
@@ -0,0 +1,474 @@
|
||||
// Code generated by github.com/cshum/vipsgen from libvips 8.17.2; DO NOT EDIT.
|
||||
|
||||
package vips
|
||||
|
||||
// #cgo pkg-config: vips
|
||||
// #include "util.h"
|
||||
import "C"
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
"sync"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// Version is the full libvips version string (x.y.z)
|
||||
const Version = string(C.VIPS_VERSION)
|
||||
|
||||
// MajorVersion is the libvips major component of the version string (x in x.y.z)
|
||||
const MajorVersion = int(C.VIPS_MAJOR_VERSION)
|
||||
|
||||
// MinorVersion is the libvips minor component of the version string (y in x.y.z)
|
||||
const MinorVersion = int(C.VIPS_MINOR_VERSION)
|
||||
|
||||
// MicroVersion is the libvips micro component of the version string (z in x.y.z)
|
||||
// Also known as patch version
|
||||
const MicroVersion = int(C.VIPS_MICRO_VERSION)
|
||||
|
||||
var (
|
||||
lock sync.Mutex
|
||||
once sync.Once
|
||||
isStarted bool
|
||||
isShutdown bool
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
ConcurrencyLevel int
|
||||
MaxCacheFiles int
|
||||
MaxCacheMem int
|
||||
MaxCacheSize int
|
||||
ReportLeaks bool
|
||||
CacheTrace bool
|
||||
VectorEnabled bool
|
||||
}
|
||||
|
||||
// LogLevel log level
|
||||
type LogLevel int
|
||||
|
||||
// LogLevel enum
|
||||
const (
|
||||
LogLevelError LogLevel = C.G_LOG_LEVEL_ERROR
|
||||
LogLevelCritical LogLevel = C.G_LOG_LEVEL_CRITICAL
|
||||
LogLevelWarning LogLevel = C.G_LOG_LEVEL_WARNING
|
||||
LogLevelMessage LogLevel = C.G_LOG_LEVEL_MESSAGE
|
||||
LogLevelInfo LogLevel = C.G_LOG_LEVEL_INFO
|
||||
LogLevelDebug LogLevel = C.G_LOG_LEVEL_DEBUG
|
||||
)
|
||||
|
||||
var (
|
||||
currentLoggingHandlerFunction = noopLoggingHandler
|
||||
currentLoggingVerbosity LogLevel
|
||||
)
|
||||
|
||||
// LoggingHandlerFunction logging handler function
|
||||
type LoggingHandlerFunction func(messageDomain string, messageLevel LogLevel, message string)
|
||||
|
||||
// SetLogging set logging handler and verbosity
|
||||
func SetLogging(handler LoggingHandlerFunction, verbosity LogLevel) {
|
||||
if handler != nil {
|
||||
currentLoggingHandlerFunction = handler
|
||||
}
|
||||
currentLoggingVerbosity = verbosity
|
||||
}
|
||||
|
||||
func noopLoggingHandler(_ string, _ LogLevel, _ string) {
|
||||
}
|
||||
|
||||
func log(domain string, level LogLevel, message string) {
|
||||
if level <= currentLoggingVerbosity {
|
||||
currentLoggingHandlerFunction(domain, level, message)
|
||||
}
|
||||
}
|
||||
|
||||
func enableLogging() {
|
||||
C.set_logging_handler()
|
||||
}
|
||||
|
||||
func disableLogging() {
|
||||
C.unset_logging_handler()
|
||||
}
|
||||
|
||||
// Startup sets up libvips and ensures the versions are correct. Pass in nil for default config.
|
||||
func Startup(config *Config) {
|
||||
once.Do(func() {
|
||||
startup(config)
|
||||
})
|
||||
}
|
||||
|
||||
func startup(config *Config) {
|
||||
lock.Lock()
|
||||
defer lock.Unlock()
|
||||
|
||||
if isStarted || isShutdown {
|
||||
return
|
||||
}
|
||||
|
||||
runtime.LockOSThread()
|
||||
defer runtime.UnlockOSThread()
|
||||
|
||||
if MajorVersion < 8 || (MajorVersion == 8 && MinorVersion < 10) {
|
||||
panic("requires libvips version 8.10+")
|
||||
}
|
||||
|
||||
cName := C.CString("vips")
|
||||
defer freeCString(cName)
|
||||
|
||||
// Override default glib logging handler to intercept logging messages
|
||||
enableLogging()
|
||||
|
||||
err := C.vips_init(cName)
|
||||
if err != 0 {
|
||||
panic(fmt.Sprintf("Failed to start vips code=%v", err))
|
||||
}
|
||||
|
||||
if config != nil {
|
||||
C.vips_leak_set(toGboolean(config.ReportLeaks))
|
||||
}
|
||||
|
||||
if config != nil && config.ConcurrencyLevel >= 0 {
|
||||
C.vips_concurrency_set(C.int(config.ConcurrencyLevel))
|
||||
} else {
|
||||
C.vips_concurrency_set(1)
|
||||
}
|
||||
|
||||
if config != nil && config.MaxCacheFiles >= 0 {
|
||||
C.vips_cache_set_max_files(C.int(config.MaxCacheFiles))
|
||||
} else {
|
||||
C.vips_cache_set_max_files(0)
|
||||
}
|
||||
|
||||
if config != nil && config.MaxCacheMem >= 0 {
|
||||
C.vips_cache_set_max_mem(C.size_t(config.MaxCacheMem))
|
||||
} else {
|
||||
C.vips_cache_set_max_mem(0)
|
||||
}
|
||||
|
||||
if config != nil && config.MaxCacheSize >= 0 {
|
||||
C.vips_cache_set_max(C.int(config.MaxCacheSize))
|
||||
} else {
|
||||
C.vips_cache_set_max(0)
|
||||
}
|
||||
|
||||
if config != nil && config.VectorEnabled {
|
||||
C.vips_vector_set_enabled(1)
|
||||
} else {
|
||||
C.vips_vector_set_enabled(0)
|
||||
}
|
||||
|
||||
if config != nil && config.CacheTrace {
|
||||
C.vips_cache_set_trace(toGboolean(true))
|
||||
}
|
||||
|
||||
log("vipsgen", LogLevelInfo, fmt.Sprintf("vips %s started with concurrency=%d cache_max_files=%d cache_max_mem=%d cache_max=%d",
|
||||
Version,
|
||||
int(C.vips_concurrency_get()),
|
||||
int(C.vips_cache_get_max_files()),
|
||||
int(C.vips_cache_get_max_mem()),
|
||||
int(C.vips_cache_get_max())))
|
||||
|
||||
isStarted = true
|
||||
}
|
||||
|
||||
// Shutdown libvips
|
||||
func Shutdown() {
|
||||
lock.Lock()
|
||||
defer lock.Unlock()
|
||||
|
||||
if !isStarted || isShutdown {
|
||||
return
|
||||
}
|
||||
|
||||
runtime.LockOSThread()
|
||||
defer runtime.UnlockOSThread()
|
||||
|
||||
C.vips_shutdown()
|
||||
disableLogging()
|
||||
|
||||
isShutdown = true
|
||||
}
|
||||
|
||||
// MemoryStats is a data structure that houses various memory statistics from ReadVipsMemStats()
|
||||
type MemoryStats struct {
|
||||
Mem int64
|
||||
MemHigh int64
|
||||
Files int64
|
||||
Allocs int64
|
||||
}
|
||||
|
||||
// ReadVipsMemStats returns various memory statistics such as allocated memory and open files.
|
||||
func ReadVipsMemStats(stats *MemoryStats) {
|
||||
stats.Mem = int64(C.vips_tracked_get_mem())
|
||||
stats.MemHigh = int64(C.vips_tracked_get_mem_highwater())
|
||||
stats.Allocs = int64(C.vips_tracked_get_allocs())
|
||||
stats.Files = int64(C.vips_tracked_get_files())
|
||||
}
|
||||
|
||||
// HasOperation checks if a libvips operation exists
|
||||
func HasOperation(name string) bool {
|
||||
Startup(nil)
|
||||
cName := C.CString(name)
|
||||
defer freeCString(cName)
|
||||
vop := C.vips_operation_new(cName)
|
||||
if vop == nil {
|
||||
C.vips_error_clear()
|
||||
return false
|
||||
}
|
||||
if C.is_gobject(unsafe.Pointer(vop)) != 0 {
|
||||
C.g_object_unref(C.gpointer(vop))
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func handleImageError(out *C.VipsImage) error {
|
||||
if out != nil {
|
||||
clearImage(out)
|
||||
}
|
||||
return handleVipsError()
|
||||
}
|
||||
|
||||
func handleVipsError() error {
|
||||
s := C.GoString(C.vips_error_buffer())
|
||||
C.vips_error_clear()
|
||||
|
||||
return fmt.Errorf("%v", s)
|
||||
}
|
||||
|
||||
func freeCString(s *C.char) {
|
||||
C.free(unsafe.Pointer(s))
|
||||
}
|
||||
|
||||
func gFreePointer(ref unsafe.Pointer) {
|
||||
C.g_free(C.gpointer(ref))
|
||||
}
|
||||
|
||||
func boolToInt(b bool) int {
|
||||
if b {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func boolToStr(v bool) string {
|
||||
if v {
|
||||
return "TRUE"
|
||||
}
|
||||
return "FALSE"
|
||||
}
|
||||
|
||||
func toGboolean(b bool) C.gboolean {
|
||||
if b {
|
||||
return C.gboolean(1)
|
||||
}
|
||||
return C.gboolean(0)
|
||||
}
|
||||
|
||||
func fromGboolean(b C.gboolean) bool {
|
||||
return b != 0
|
||||
}
|
||||
|
||||
var cStringsCache sync.Map
|
||||
|
||||
func cachedCString(str string) *C.char {
|
||||
if cstr, ok := cStringsCache.Load(str); ok {
|
||||
return cstr.(*C.char)
|
||||
}
|
||||
cstr := C.CString(str)
|
||||
cStringsCache.Store(str, cstr)
|
||||
return cstr
|
||||
}
|
||||
|
||||
// bufferToBytes converts a C buffer to Go bytes and frees the original buffer.
|
||||
// This function takes ownership of the buffer and will free it after conversion.
|
||||
func bufferToBytes(buf unsafe.Pointer, length C.size_t) []byte {
|
||||
if buf == nil {
|
||||
return nil
|
||||
}
|
||||
bytes := C.GoBytes(buf, C.int(length))
|
||||
C.g_free(C.gpointer(buf))
|
||||
return bytes
|
||||
}
|
||||
|
||||
// convertImagesToVipsImages converts from Image slice to VipsImage slice
|
||||
func convertImagesToVipsImages(images []*Image) []*C.VipsImage {
|
||||
vipsImages := make([]*C.VipsImage, len(images))
|
||||
for i, img := range images {
|
||||
vipsImages[i] = img.image
|
||||
}
|
||||
return vipsImages
|
||||
}
|
||||
|
||||
// convertVipsImagesToImages converts a slice of *C.VipsImage to []*Image
|
||||
func convertVipsImagesToImages(vipsImages []*C.VipsImage) []*Image {
|
||||
images := make([]*Image, len(vipsImages))
|
||||
for i, vipsImg := range vipsImages {
|
||||
images[i] = newImageRef(vipsImg, ImageTypeUnknown, nil)
|
||||
}
|
||||
return images
|
||||
}
|
||||
|
||||
// vipsInterpolateToC converts a Go Interpolate to a C VipsInterpolate pointer
|
||||
func vipsInterpolateToC(interp *Interpolate) *C.VipsInterpolate {
|
||||
if interp == nil {
|
||||
return nil
|
||||
}
|
||||
return interp.interp
|
||||
}
|
||||
|
||||
// vipsInterpolateFromC converts a C VipsInterpolate pointer to a Go Interpolate
|
||||
func vipsInterpolateFromC(interp *C.VipsInterpolate) *Interpolate {
|
||||
if interp == nil {
|
||||
return nil
|
||||
}
|
||||
return &Interpolate{interp: interp}
|
||||
}
|
||||
|
||||
// convertToDoubleArray converts a Go float64 slice to a C double array and returns the length
|
||||
func convertToDoubleArray(values []float64) (*C.double, C.int, error) {
|
||||
if len(values) == 0 {
|
||||
return nil, 0, nil
|
||||
}
|
||||
|
||||
// Allocate C memory
|
||||
size := C.size_t(len(values)) * C.size_t(unsafe.Sizeof(C.double(0)))
|
||||
cArray := (*C.double)(C.malloc(size))
|
||||
if cArray == nil {
|
||||
return nil, 0, fmt.Errorf("failed to allocate memory for double array")
|
||||
}
|
||||
|
||||
// Copy values to C array
|
||||
for i, v := range values {
|
||||
ptr := unsafe.Pointer(uintptr(unsafe.Pointer(cArray)) + uintptr(i)*unsafe.Sizeof(C.double(0)))
|
||||
*(*C.double)(ptr) = C.double(v)
|
||||
}
|
||||
|
||||
return cArray, C.int(len(values)), nil
|
||||
}
|
||||
|
||||
// freeDoubleArray frees memory allocated for a C double array
|
||||
func freeDoubleArray(array *C.double) {
|
||||
if array != nil {
|
||||
C.free(unsafe.Pointer(array))
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
func fromCArrayInt(out *C.int, n int) []int {
|
||||
if out == nil || n <= 0 {
|
||||
return nil
|
||||
}
|
||||
data := make([]int, n)
|
||||
for i := 0; i < n; i++ {
|
||||
data[i] = int(*(*C.int)(unsafe.Pointer(uintptr(unsafe.Pointer(out)) + uintptr(i)*unsafe.Sizeof(C.int(0)))))
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
// convertToIntArray converts a Go int slice to a C int array and returns the length
|
||||
func convertToIntArray(values []int) (*C.int, C.int, error) {
|
||||
if len(values) == 0 {
|
||||
return nil, 0, nil
|
||||
}
|
||||
|
||||
// Allocate C memory
|
||||
size := C.size_t(len(values)) * C.size_t(unsafe.Sizeof(C.int(0)))
|
||||
cArray := (*C.int)(C.malloc(size))
|
||||
if cArray == nil {
|
||||
return nil, 0, fmt.Errorf("failed to allocate memory for int array")
|
||||
}
|
||||
|
||||
// Copy values to C array
|
||||
for i, v := range values {
|
||||
ptr := unsafe.Pointer(uintptr(unsafe.Pointer(cArray)) + uintptr(i)*unsafe.Sizeof(C.int(0)))
|
||||
*(*C.int)(ptr) = C.int(v)
|
||||
}
|
||||
|
||||
return cArray, C.int(len(values)), nil
|
||||
}
|
||||
|
||||
// freeIntArray frees memory allocated for a C int array
|
||||
func freeIntArray(array *C.int) {
|
||||
if array != nil {
|
||||
C.free(unsafe.Pointer(array))
|
||||
}
|
||||
}
|
||||
|
||||
// convertToBlendModeArray converts a Go BlendMode slice to a C int array and returns the length
|
||||
func convertToBlendModeArray(values []BlendMode) (*C.int, C.int, error) {
|
||||
if len(values) == 0 {
|
||||
return nil, 0, nil
|
||||
}
|
||||
|
||||
// Allocate C memory
|
||||
size := C.size_t(len(values)) * C.size_t(unsafe.Sizeof(C.int(0)))
|
||||
cArray := (*C.int)(C.malloc(size))
|
||||
if cArray == nil {
|
||||
return nil, 0, fmt.Errorf("failed to allocate memory for BlendMode array")
|
||||
}
|
||||
|
||||
// Copy values to C array
|
||||
for i, v := range values {
|
||||
ptr := unsafe.Pointer(uintptr(unsafe.Pointer(cArray)) + uintptr(i)*unsafe.Sizeof(C.int(0)))
|
||||
*(*C.int)(ptr) = C.int(v)
|
||||
}
|
||||
|
||||
return cArray, C.int(len(values)), nil
|
||||
}
|
||||
|
||||
// convertToImageArray converts a Go []*Image slice to a C VipsImage** array and returns the length
|
||||
func convertToImageArray(images []*C.VipsImage) (**C.VipsImage, C.int, error) {
|
||||
if len(images) == 0 {
|
||||
return nil, 0, nil
|
||||
}
|
||||
|
||||
// Allocate C memory for array of VipsImage pointers
|
||||
size := C.size_t(len(images)) * C.size_t(unsafe.Sizeof((*C.VipsImage)(nil)))
|
||||
cArray := (**C.VipsImage)(C.malloc(size))
|
||||
if cArray == nil {
|
||||
return nil, 0, fmt.Errorf("failed to allocate memory for image array")
|
||||
}
|
||||
|
||||
// Convert each Image to a C VipsImage pointer and store in array
|
||||
for i, img := range images {
|
||||
ptr := unsafe.Pointer(uintptr(unsafe.Pointer(cArray)) + uintptr(i)*unsafe.Sizeof((*C.VipsImage)(nil)))
|
||||
*(**C.VipsImage)(ptr) = img
|
||||
}
|
||||
|
||||
return cArray, C.int(len(images)), nil
|
||||
}
|
||||
|
||||
// freeImageArray frees memory allocated for a C VipsImage** array
|
||||
func freeImageArray(array **C.VipsImage) {
|
||||
if array != nil {
|
||||
C.free(unsafe.Pointer(array))
|
||||
}
|
||||
}
|
||||
|
||||
// vipsBlobToBytes converts a VipsBlob to a Go byte slice and unrefs the blob
|
||||
func vipsBlobToBytes(blob *C.VipsBlob) []byte {
|
||||
if blob == nil {
|
||||
return nil
|
||||
}
|
||||
var size C.size_t
|
||||
ptr := C.vips_blob_get(blob, &size)
|
||||
data := C.GoBytes(ptr, C.int(size))
|
||||
C.vips_area_unref((*C.VipsArea)(unsafe.Pointer(blob)))
|
||||
return data
|
||||
}
|
||||
|
||||
// getImagePointer safely extracts the C.VipsImage pointer from an Image, returning nil if the Image is nil
|
||||
func getImagePointer(img *Image) *C.VipsImage {
|
||||
if img == nil {
|
||||
return nil
|
||||
}
|
||||
return img.image
|
||||
}
|
||||
@@ -1,9 +1,11 @@
|
||||
// Code generated by github.com/cshum/vipsgen from libvips 8.17.2; DO NOT EDIT.
|
||||
|
||||
// clang-format off
|
||||
// include order matters
|
||||
#include <stdlib.h>
|
||||
#include <glib.h>
|
||||
#include <vips/vips.h>
|
||||
#include <vips/vector.h>
|
||||
// clang-format on
|
||||
|
||||
#if (VIPS_MAJOR_VERSION < 8)
|
||||
@@ -11,9 +13,9 @@ error_requires_version_8
|
||||
#endif
|
||||
|
||||
extern void
|
||||
govipsLoggingHandler(char *log_domain, int log_level, char *message);
|
||||
goLoggingHandler(char *log_domain, int log_level, char *message);
|
||||
|
||||
static void govips_logging_handler(const gchar *log_domain,
|
||||
static void logging_handler(const gchar *log_domain,
|
||||
GLogLevelFlags log_level,
|
||||
const gchar *message, gpointer user_data);
|
||||
|
||||
@@ -21,6 +23,11 @@ static void null_logging_handler(const gchar *log_domain,
|
||||
GLogLevelFlags log_level, const gchar *message,
|
||||
gpointer user_data);
|
||||
|
||||
void vips_set_logging_handler(void);
|
||||
void vips_unset_logging_handler(void);
|
||||
void vips_default_logging_handler(void);
|
||||
void set_logging_handler(void);
|
||||
void unset_logging_handler(void);
|
||||
|
||||
#ifndef G_IS_OBJECT
|
||||
#define G_IS_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_OBJECT))
|
||||
#endif
|
||||
|
||||
int is_gobject(void* obj);
|
||||
6120
vendor/github.com/cshum/vipsgen/vips/vips.c
generated
vendored
Normal file
6120
vendor/github.com/cshum/vipsgen/vips/vips.c
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
6523
vendor/github.com/cshum/vipsgen/vips/vips.go
generated
vendored
Normal file
6523
vendor/github.com/cshum/vipsgen/vips/vips.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
886
vendor/github.com/cshum/vipsgen/vips/vips.h
generated
vendored
Normal file
886
vendor/github.com/cshum/vipsgen/vips/vips.h
generated
vendored
Normal file
@@ -0,0 +1,886 @@
|
||||
// Code generated by github.com/cshum/vipsgen from libvips 8.17.2; DO NOT EDIT.
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <vips/vips.h>
|
||||
#include <vips/vector.h>
|
||||
|
||||
// Prerequisites to build, get outputs and cleanup a vips operation
|
||||
|
||||
int vipsgen_operation_execute(VipsOperation *operation, ...);
|
||||
int vipsgen_operation_save_buffer(VipsOperation *operation, void** buf, size_t* len);
|
||||
int vipsgen_set_source(VipsOperation *operation, const char *name, VipsSource *value);
|
||||
int vipsgen_set_target(VipsOperation *operation, const char *name, VipsTarget *value);
|
||||
int vipsgen_set_int(VipsOperation *operation, const char *name, int value);
|
||||
int vipsgen_set_bool(VipsOperation *operation, const char *name, gboolean value);
|
||||
int vipsgen_set_double(VipsOperation *operation, const char *name, double value);
|
||||
int vipsgen_set_guint64(VipsOperation *operation, const char *name, guint64 value);
|
||||
int vipsgen_set_string(VipsOperation *operation, const char *name, const char *value);
|
||||
int vipsgen_set_image(VipsOperation *operation, const char *name, VipsImage *value);
|
||||
int vipsgen_set_array_double(VipsOperation *operation, const char *name, VipsArrayDouble *value);
|
||||
int vipsgen_set_array_int(VipsOperation *operation, const char *name, VipsArrayInt *value);
|
||||
int vipsgen_set_array_image(VipsOperation *operation, const char *name, VipsArrayImage *value);
|
||||
int vipsgen_set_interpolate(VipsOperation *operation, const char *name, VipsInterpolate *value);
|
||||
|
||||
// Generated operations
|
||||
|
||||
int vipsgen_CMC2LCh(VipsImage* in, VipsImage** out);
|
||||
|
||||
int vipsgen_CMYK2XYZ(VipsImage* in, VipsImage** out);
|
||||
|
||||
int vipsgen_HSV2sRGB(VipsImage* in, VipsImage** out);
|
||||
|
||||
int vipsgen_LCh2CMC(VipsImage* in, VipsImage** out);
|
||||
|
||||
int vipsgen_LCh2Lab(VipsImage* in, VipsImage** out);
|
||||
|
||||
int vipsgen_Lab2LCh(VipsImage* in, VipsImage** out);
|
||||
|
||||
int vipsgen_Lab2LabQ(VipsImage* in, VipsImage** out);
|
||||
|
||||
int vipsgen_Lab2LabS(VipsImage* in, VipsImage** out);
|
||||
|
||||
int vipsgen_Lab2XYZ(VipsImage* in, VipsImage** out);
|
||||
int vipsgen_Lab2XYZ_with_options(VipsImage* in, VipsImage** out, double* temp, int temp_n);
|
||||
|
||||
int vipsgen_LabQ2Lab(VipsImage* in, VipsImage** out);
|
||||
|
||||
int vipsgen_LabQ2LabS(VipsImage* in, VipsImage** out);
|
||||
|
||||
int vipsgen_LabQ2sRGB(VipsImage* in, VipsImage** out);
|
||||
|
||||
int vipsgen_LabS2Lab(VipsImage* in, VipsImage** out);
|
||||
|
||||
int vipsgen_LabS2LabQ(VipsImage* in, VipsImage** out);
|
||||
|
||||
int vipsgen_XYZ2CMYK(VipsImage* in, VipsImage** out);
|
||||
|
||||
int vipsgen_XYZ2Lab(VipsImage* in, VipsImage** out);
|
||||
int vipsgen_XYZ2Lab_with_options(VipsImage* in, VipsImage** out, double* temp, int temp_n);
|
||||
|
||||
int vipsgen_XYZ2Yxy(VipsImage* in, VipsImage** out);
|
||||
|
||||
int vipsgen_XYZ2scRGB(VipsImage* in, VipsImage** out);
|
||||
|
||||
int vipsgen_Yxy2XYZ(VipsImage* in, VipsImage** out);
|
||||
|
||||
int vipsgen_abs(VipsImage* in, VipsImage** out);
|
||||
|
||||
int vipsgen_add(VipsImage* left, VipsImage* right, VipsImage** out);
|
||||
|
||||
int vipsgen_addalpha(VipsImage* in, VipsImage** out);
|
||||
|
||||
int vipsgen_affine(VipsImage* in, VipsImage** out, double a, double b, double c, double d);
|
||||
int vipsgen_affine_with_options(VipsImage* in, VipsImage** out, double a, double b, double c, double d, VipsInterpolate* interpolate, int* oarea, int oarea_n, double odx, double ody, double idx, double idy, double* background, int background_n, gboolean premultiplied, VipsExtend extend);
|
||||
|
||||
int vipsgen_analyzeload(const char* filename, VipsImage** out);
|
||||
int vipsgen_analyzeload_with_options(const char* filename, VipsImage** out, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_arrayjoin(VipsImage** in, VipsImage** out, int n);
|
||||
int vipsgen_arrayjoin_with_options(VipsImage** in, VipsImage** out, int n, gint across, gint shim, double* background, int background_n, VipsAlign halign, VipsAlign valign, gint hspacing, gint vspacing);
|
||||
|
||||
int vipsgen_autorot(VipsImage* in, VipsImage** out);
|
||||
int vipsgen_autorot_with_options(VipsImage* in, VipsImage** out, gboolean* flip);
|
||||
|
||||
int vipsgen_avg(VipsImage* in, double* out);
|
||||
|
||||
int vipsgen_bandbool(VipsImage* in, VipsImage** out, VipsOperationBoolean boolean);
|
||||
|
||||
int vipsgen_bandfold(VipsImage* in, VipsImage** out);
|
||||
int vipsgen_bandfold_with_options(VipsImage* in, VipsImage** out, gint factor);
|
||||
|
||||
int vipsgen_bandjoin(VipsImage** in, VipsImage** out, int n);
|
||||
|
||||
int vipsgen_bandjoin_const(VipsImage* in, VipsImage** out, double* c, int n);
|
||||
|
||||
int vipsgen_bandmean(VipsImage* in, VipsImage** out);
|
||||
|
||||
int vipsgen_bandrank(VipsImage** in, VipsImage** out, int n);
|
||||
int vipsgen_bandrank_with_options(VipsImage** in, VipsImage** out, int n, gint index);
|
||||
|
||||
int vipsgen_bandunfold(VipsImage* in, VipsImage** out);
|
||||
int vipsgen_bandunfold_with_options(VipsImage* in, VipsImage** out, gint factor);
|
||||
|
||||
int vipsgen_black(VipsImage** out, gint width, gint height);
|
||||
int vipsgen_black_with_options(VipsImage** out, gint width, gint height, gint bands);
|
||||
|
||||
int vipsgen_boolean(VipsImage* left, VipsImage* right, VipsImage** out, VipsOperationBoolean boolean);
|
||||
|
||||
int vipsgen_boolean_const(VipsImage* in, VipsImage** out, VipsOperationBoolean boolean, double* c, int n);
|
||||
|
||||
int vipsgen_buildlut(VipsImage* in, VipsImage** out);
|
||||
|
||||
int vipsgen_byteswap(VipsImage* in, VipsImage** out);
|
||||
|
||||
int vipsgen_canny(VipsImage* in, VipsImage** out);
|
||||
int vipsgen_canny_with_options(VipsImage* in, VipsImage** out, double sigma, VipsPrecision precision);
|
||||
|
||||
int vipsgen_case(VipsImage* index, VipsImage** cases, VipsImage** out, int n);
|
||||
|
||||
int vipsgen_cast(VipsImage* in, VipsImage** out, VipsBandFormat format);
|
||||
int vipsgen_cast_with_options(VipsImage* in, VipsImage** out, VipsBandFormat format, gboolean shift);
|
||||
|
||||
int vipsgen_clamp(VipsImage* in, VipsImage** out);
|
||||
int vipsgen_clamp_with_options(VipsImage* in, VipsImage** out, double min, double max);
|
||||
|
||||
int vipsgen_colourspace(VipsImage* in, VipsImage** out, VipsInterpretation space);
|
||||
int vipsgen_colourspace_with_options(VipsImage* in, VipsImage** out, VipsInterpretation space, VipsInterpretation source_space);
|
||||
|
||||
int vipsgen_compass(VipsImage* in, VipsImage** out, VipsImage* mask);
|
||||
int vipsgen_compass_with_options(VipsImage* in, VipsImage** out, VipsImage* mask, gint times, VipsAngle45 angle, VipsCombine combine, VipsPrecision precision, gint layers, gint cluster);
|
||||
|
||||
int vipsgen_complex(VipsImage* in, VipsImage** out, VipsOperationComplex cmplx);
|
||||
|
||||
int vipsgen_complex2(VipsImage* left, VipsImage* right, VipsImage** out, VipsOperationComplex2 cmplx);
|
||||
|
||||
int vipsgen_complexform(VipsImage* left, VipsImage* right, VipsImage** out);
|
||||
|
||||
int vipsgen_complexget(VipsImage* in, VipsImage** out, VipsOperationComplexget get);
|
||||
|
||||
int vipsgen_composite(VipsImage** in, VipsImage** out, int n, int* mode);
|
||||
int vipsgen_composite_with_options(VipsImage** in, VipsImage** out, int n, int* mode, int* x, int x_n, int* y, int y_n, VipsInterpretation compositing_space, gboolean premultiplied);
|
||||
|
||||
int vipsgen_composite2(VipsImage* base, VipsImage* overlay, VipsImage** out, VipsBlendMode mode);
|
||||
int vipsgen_composite2_with_options(VipsImage* base, VipsImage* overlay, VipsImage** out, VipsBlendMode mode, gint x, gint y, VipsInterpretation compositing_space, gboolean premultiplied);
|
||||
|
||||
int vipsgen_conv(VipsImage* in, VipsImage** out, VipsImage* mask);
|
||||
int vipsgen_conv_with_options(VipsImage* in, VipsImage** out, VipsImage* mask, VipsPrecision precision, gint layers, gint cluster);
|
||||
|
||||
int vipsgen_conva(VipsImage* in, VipsImage** out, VipsImage* mask);
|
||||
int vipsgen_conva_with_options(VipsImage* in, VipsImage** out, VipsImage* mask, gint layers, gint cluster);
|
||||
|
||||
int vipsgen_convasep(VipsImage* in, VipsImage** out, VipsImage* mask);
|
||||
int vipsgen_convasep_with_options(VipsImage* in, VipsImage** out, VipsImage* mask, gint layers);
|
||||
|
||||
int vipsgen_convf(VipsImage* in, VipsImage** out, VipsImage* mask);
|
||||
|
||||
int vipsgen_convi(VipsImage* in, VipsImage** out, VipsImage* mask);
|
||||
|
||||
int vipsgen_convsep(VipsImage* in, VipsImage** out, VipsImage* mask);
|
||||
int vipsgen_convsep_with_options(VipsImage* in, VipsImage** out, VipsImage* mask, VipsPrecision precision, gint layers, gint cluster);
|
||||
|
||||
int vipsgen_copy(VipsImage* in, VipsImage** out);
|
||||
int vipsgen_copy_with_options(VipsImage* in, VipsImage** out, gint width, gint height, gint bands, VipsBandFormat format, VipsCoding coding, VipsInterpretation interpretation, double xres, double yres, gint xoffset, gint yoffset);
|
||||
|
||||
int vipsgen_countlines(VipsImage* in, double* nolines, VipsDirection direction);
|
||||
|
||||
int vipsgen_csvload(const char* filename, VipsImage** out);
|
||||
int vipsgen_csvload_with_options(const char* filename, VipsImage** out, gint skip, gint lines, const char* whitespace, const char* separator, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_csvload_source(VipsSourceCustom* source, VipsImage** out);
|
||||
int vipsgen_csvload_source_with_options(VipsSourceCustom* source, VipsImage** out, gint skip, gint lines, const char* whitespace, const char* separator, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_csvsave(VipsImage* in, const char* filename);
|
||||
int vipsgen_csvsave_with_options(VipsImage* in, const char* filename, const char* separator, VipsForeignKeep keep, double* background, int background_n, gint page_height, const char* profile);
|
||||
|
||||
int vipsgen_csvsave_target(VipsImage* in, VipsTargetCustom* target);
|
||||
int vipsgen_csvsave_target_with_options(VipsImage* in, VipsTargetCustom* target, const char* separator, VipsForeignKeep keep, double* background, int background_n, gint page_height, const char* profile);
|
||||
|
||||
int vipsgen_dE00(VipsImage* left, VipsImage* right, VipsImage** out);
|
||||
|
||||
int vipsgen_dE76(VipsImage* left, VipsImage* right, VipsImage** out);
|
||||
|
||||
int vipsgen_dECMC(VipsImage* left, VipsImage* right, VipsImage** out);
|
||||
|
||||
int vipsgen_deviate(VipsImage* in, double* out);
|
||||
|
||||
int vipsgen_divide(VipsImage* left, VipsImage* right, VipsImage** out);
|
||||
|
||||
int vipsgen_draw_circle(VipsImage* image, double* ink, int n, gint cx, gint cy, gint radius);
|
||||
int vipsgen_draw_circle_with_options(VipsImage* image, double* ink, int n, gint cx, gint cy, gint radius, gboolean fill);
|
||||
|
||||
int vipsgen_draw_flood(VipsImage* image, double* ink, int n, gint x, gint y);
|
||||
int vipsgen_draw_flood_with_options(VipsImage* image, double* ink, int n, gint x, gint y, VipsImage* test, gboolean equal, gint* left, gint* top, gint* width, gint* height);
|
||||
|
||||
int vipsgen_draw_image(VipsImage* image, VipsImage* sub, gint x, gint y);
|
||||
int vipsgen_draw_image_with_options(VipsImage* image, VipsImage* sub, gint x, gint y, VipsCombineMode mode);
|
||||
|
||||
int vipsgen_draw_line(VipsImage* image, double* ink, int n, gint x1, gint y1, gint x2, gint y2);
|
||||
|
||||
int vipsgen_draw_mask(VipsImage* image, double* ink, int n, VipsImage* mask, gint x, gint y);
|
||||
|
||||
int vipsgen_draw_rect(VipsImage* image, double* ink, int n, gint left, gint top, gint width, gint height);
|
||||
int vipsgen_draw_rect_with_options(VipsImage* image, double* ink, int n, gint left, gint top, gint width, gint height, gboolean fill);
|
||||
|
||||
int vipsgen_draw_smudge(VipsImage* image, gint left, gint top, gint width, gint height);
|
||||
|
||||
int vipsgen_dzsave(VipsImage* in, const char* filename);
|
||||
int vipsgen_dzsave_with_options(VipsImage* in, const char* filename, const char* imagename, VipsForeignDzLayout layout, const char* suffix, gint overlap, gint tile_size, gboolean centre, VipsForeignDzDepth depth, VipsAngle angle, VipsForeignDzContainer container, gint compression, VipsRegionShrink region_shrink, gint skip_blanks, const char* id, gint Q, VipsForeignKeep keep, double* background, int background_n, gint page_height, const char* profile);
|
||||
|
||||
int vipsgen_dzsave_buffer(VipsImage* in, void** buf, size_t* len);
|
||||
int vipsgen_dzsave_buffer_with_options(VipsImage* in, void** buf, size_t* len, const char* imagename, VipsForeignDzLayout layout, const char* suffix, gint overlap, gint tile_size, gboolean centre, VipsForeignDzDepth depth, VipsAngle angle, VipsForeignDzContainer container, gint compression, VipsRegionShrink region_shrink, gint skip_blanks, const char* id, gint Q, VipsForeignKeep keep, double* background, int background_n, gint page_height, const char* profile);
|
||||
|
||||
int vipsgen_dzsave_target(VipsImage* in, VipsTargetCustom* target);
|
||||
int vipsgen_dzsave_target_with_options(VipsImage* in, VipsTargetCustom* target, const char* imagename, VipsForeignDzLayout layout, const char* suffix, gint overlap, gint tile_size, gboolean centre, VipsForeignDzDepth depth, VipsAngle angle, VipsForeignDzContainer container, gint compression, VipsRegionShrink region_shrink, gint skip_blanks, const char* id, gint Q, VipsForeignKeep keep, double* background, int background_n, gint page_height, const char* profile);
|
||||
|
||||
int vipsgen_embed(VipsImage* in, VipsImage** out, gint x, gint y, gint width, gint height);
|
||||
int vipsgen_embed_with_options(VipsImage* in, VipsImage** out, gint x, gint y, gint width, gint height, VipsExtend extend, double* background, int background_n);
|
||||
|
||||
int vipsgen_extract_area(VipsImage* input, VipsImage** out, gint left, gint top, gint width, gint height);
|
||||
|
||||
int vipsgen_extract_band(VipsImage* in, VipsImage** out, gint band);
|
||||
int vipsgen_extract_band_with_options(VipsImage* in, VipsImage** out, gint band, gint n);
|
||||
|
||||
int vipsgen_eye(VipsImage** out, gint width, gint height);
|
||||
int vipsgen_eye_with_options(VipsImage** out, gint width, gint height, gboolean uchar, double factor);
|
||||
|
||||
int vipsgen_falsecolour(VipsImage* in, VipsImage** out);
|
||||
|
||||
int vipsgen_fastcor(VipsImage* in, VipsImage* ref, VipsImage** out);
|
||||
|
||||
int vipsgen_fill_nearest(VipsImage* in, VipsImage** out);
|
||||
|
||||
int vipsgen_find_trim(VipsImage* in, gint* left, gint* top, gint* width, gint* height);
|
||||
int vipsgen_find_trim_with_options(VipsImage* in, gint* left, gint* top, gint* width, gint* height, double threshold, double* background, int background_n, gboolean line_art);
|
||||
|
||||
int vipsgen_fitsload(const char* filename, VipsImage** out);
|
||||
int vipsgen_fitsload_with_options(const char* filename, VipsImage** out, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_fitssave(VipsImage* in, const char* filename);
|
||||
int vipsgen_fitssave_with_options(VipsImage* in, const char* filename, VipsForeignKeep keep, double* background, int background_n, gint page_height, const char* profile);
|
||||
|
||||
int vipsgen_flatten(VipsImage* in, VipsImage** out);
|
||||
int vipsgen_flatten_with_options(VipsImage* in, VipsImage** out, double* background, int background_n, double max_alpha);
|
||||
|
||||
int vipsgen_flip(VipsImage* in, VipsImage** out, VipsDirection direction);
|
||||
|
||||
int vipsgen_float2rad(VipsImage* in, VipsImage** out);
|
||||
|
||||
int vipsgen_fractsurf(VipsImage** out, gint width, gint height, double fractal_dimension);
|
||||
|
||||
int vipsgen_freqmult(VipsImage* in, VipsImage* mask, VipsImage** out);
|
||||
|
||||
int vipsgen_fwfft(VipsImage* in, VipsImage** out);
|
||||
|
||||
int vipsgen_gamma(VipsImage* in, VipsImage** out);
|
||||
int vipsgen_gamma_with_options(VipsImage* in, VipsImage** out, double exponent);
|
||||
|
||||
int vipsgen_gaussblur(VipsImage* in, VipsImage** out, double sigma);
|
||||
int vipsgen_gaussblur_with_options(VipsImage* in, VipsImage** out, double sigma, double min_ampl, VipsPrecision precision);
|
||||
|
||||
int vipsgen_gaussmat(VipsImage** out, double sigma, double min_ampl);
|
||||
int vipsgen_gaussmat_with_options(VipsImage** out, double sigma, double min_ampl, gboolean separable, VipsPrecision precision);
|
||||
|
||||
int vipsgen_gaussnoise(VipsImage** out, gint width, gint height);
|
||||
int vipsgen_gaussnoise_with_options(VipsImage** out, gint width, gint height, double sigma, double mean, gint seed);
|
||||
|
||||
int vipsgen_getpoint(VipsImage* in, double** out_array, int* n, gint x, gint y);
|
||||
int vipsgen_getpoint_with_options(VipsImage* in, double** out_array, int* n, gint x, gint y, gboolean unpack_complex);
|
||||
|
||||
int vipsgen_gifload(const char* filename, VipsImage** out);
|
||||
int vipsgen_gifload_with_options(const char* filename, VipsImage** out, gint n, gint page, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_gifload_buffer(void* buf, size_t len, VipsImage** out);
|
||||
int vipsgen_gifload_buffer_with_options(void* buf, size_t len, VipsImage** out, gint n, gint page, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_gifload_source(VipsSourceCustom* source, VipsImage** out);
|
||||
int vipsgen_gifload_source_with_options(VipsSourceCustom* source, VipsImage** out, gint n, gint page, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_gifsave(VipsImage* in, const char* filename);
|
||||
int vipsgen_gifsave_with_options(VipsImage* in, const char* filename, double dither, gint effort, gint bitdepth, double interframe_maxerror, gboolean reuse, double interpalette_maxerror, gboolean interlace, gboolean keep_duplicate_frames, VipsForeignKeep keep, double* background, int background_n, gint page_height, const char* profile);
|
||||
|
||||
int vipsgen_gifsave_buffer(VipsImage* in, void** buf, size_t* len);
|
||||
int vipsgen_gifsave_buffer_with_options(VipsImage* in, void** buf, size_t* len, double dither, gint effort, gint bitdepth, double interframe_maxerror, gboolean reuse, double interpalette_maxerror, gboolean interlace, gboolean keep_duplicate_frames, VipsForeignKeep keep, double* background, int background_n, gint page_height, const char* profile);
|
||||
|
||||
int vipsgen_gifsave_target(VipsImage* in, VipsTargetCustom* target);
|
||||
int vipsgen_gifsave_target_with_options(VipsImage* in, VipsTargetCustom* target, double dither, gint effort, gint bitdepth, double interframe_maxerror, gboolean reuse, double interpalette_maxerror, gboolean interlace, gboolean keep_duplicate_frames, VipsForeignKeep keep, double* background, int background_n, gint page_height, const char* profile);
|
||||
|
||||
int vipsgen_globalbalance(VipsImage* in, VipsImage** out);
|
||||
int vipsgen_globalbalance_with_options(VipsImage* in, VipsImage** out, double gamma, gboolean int_output);
|
||||
|
||||
int vipsgen_gravity(VipsImage* in, VipsImage** out, VipsCompassDirection direction, gint width, gint height);
|
||||
int vipsgen_gravity_with_options(VipsImage* in, VipsImage** out, VipsCompassDirection direction, gint width, gint height, VipsExtend extend, double* background, int background_n);
|
||||
|
||||
int vipsgen_grey(VipsImage** out, gint width, gint height);
|
||||
int vipsgen_grey_with_options(VipsImage** out, gint width, gint height, gboolean uchar);
|
||||
|
||||
int vipsgen_grid(VipsImage* in, VipsImage** out, gint tile_height, gint across, gint down);
|
||||
|
||||
int vipsgen_heifload(const char* filename, VipsImage** out);
|
||||
int vipsgen_heifload_with_options(const char* filename, VipsImage** out, gint page, gint n, gboolean thumbnail, gboolean unlimited, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_heifload_buffer(void* buf, size_t len, VipsImage** out);
|
||||
int vipsgen_heifload_buffer_with_options(void* buf, size_t len, VipsImage** out, gint page, gint n, gboolean thumbnail, gboolean unlimited, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_heifload_source(VipsSourceCustom* source, VipsImage** out);
|
||||
int vipsgen_heifload_source_with_options(VipsSourceCustom* source, VipsImage** out, gint page, gint n, gboolean thumbnail, gboolean unlimited, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_heifsave(VipsImage* in, const char* filename);
|
||||
int vipsgen_heifsave_with_options(VipsImage* in, const char* filename, gint Q, gint bitdepth, gboolean lossless, VipsForeignHeifCompression compression, gint effort, VipsForeignSubsample subsample_mode, VipsForeignHeifEncoder encoder, VipsForeignKeep keep, double* background, int background_n, gint page_height, const char* profile);
|
||||
|
||||
int vipsgen_heifsave_buffer(VipsImage* in, void** buf, size_t* len);
|
||||
int vipsgen_heifsave_buffer_with_options(VipsImage* in, void** buf, size_t* len, gint Q, gint bitdepth, gboolean lossless, VipsForeignHeifCompression compression, gint effort, VipsForeignSubsample subsample_mode, VipsForeignHeifEncoder encoder, VipsForeignKeep keep, double* background, int background_n, gint page_height, const char* profile);
|
||||
|
||||
int vipsgen_heifsave_target(VipsImage* in, VipsTargetCustom* target);
|
||||
int vipsgen_heifsave_target_with_options(VipsImage* in, VipsTargetCustom* target, gint Q, gint bitdepth, gboolean lossless, VipsForeignHeifCompression compression, gint effort, VipsForeignSubsample subsample_mode, VipsForeignHeifEncoder encoder, VipsForeignKeep keep, double* background, int background_n, gint page_height, const char* profile);
|
||||
|
||||
int vipsgen_hist_cum(VipsImage* in, VipsImage** out);
|
||||
|
||||
int vipsgen_hist_entropy(VipsImage* in, double* out);
|
||||
|
||||
int vipsgen_hist_equal(VipsImage* in, VipsImage** out);
|
||||
int vipsgen_hist_equal_with_options(VipsImage* in, VipsImage** out, gint band);
|
||||
|
||||
int vipsgen_hist_find(VipsImage* in, VipsImage** out);
|
||||
int vipsgen_hist_find_with_options(VipsImage* in, VipsImage** out, gint band);
|
||||
|
||||
int vipsgen_hist_find_indexed(VipsImage* in, VipsImage* index, VipsImage** out);
|
||||
int vipsgen_hist_find_indexed_with_options(VipsImage* in, VipsImage* index, VipsImage** out, VipsCombine combine);
|
||||
|
||||
int vipsgen_hist_find_ndim(VipsImage* in, VipsImage** out);
|
||||
int vipsgen_hist_find_ndim_with_options(VipsImage* in, VipsImage** out, gint bins);
|
||||
|
||||
int vipsgen_hist_ismonotonic(VipsImage* in, gboolean* monotonic);
|
||||
|
||||
int vipsgen_hist_local(VipsImage* in, VipsImage** out, gint width, gint height);
|
||||
int vipsgen_hist_local_with_options(VipsImage* in, VipsImage** out, gint width, gint height, gint max_slope);
|
||||
|
||||
int vipsgen_hist_match(VipsImage* in, VipsImage* ref, VipsImage** out);
|
||||
|
||||
int vipsgen_hist_norm(VipsImage* in, VipsImage** out);
|
||||
|
||||
int vipsgen_hist_plot(VipsImage* in, VipsImage** out);
|
||||
|
||||
int vipsgen_hough_circle(VipsImage* in, VipsImage** out);
|
||||
int vipsgen_hough_circle_with_options(VipsImage* in, VipsImage** out, gint scale, gint min_radius, gint max_radius);
|
||||
|
||||
int vipsgen_hough_line(VipsImage* in, VipsImage** out);
|
||||
int vipsgen_hough_line_with_options(VipsImage* in, VipsImage** out, gint width, gint height);
|
||||
|
||||
int vipsgen_icc_export(VipsImage* in, VipsImage** out);
|
||||
int vipsgen_icc_export_with_options(VipsImage* in, VipsImage** out, VipsPCS pcs, VipsIntent intent, gboolean black_point_compensation, const char* output_profile, gint depth);
|
||||
|
||||
int vipsgen_icc_import(VipsImage* in, VipsImage** out);
|
||||
int vipsgen_icc_import_with_options(VipsImage* in, VipsImage** out, VipsPCS pcs, VipsIntent intent, gboolean black_point_compensation, gboolean embedded, const char* input_profile);
|
||||
|
||||
int vipsgen_icc_transform(VipsImage* in, VipsImage** out, const char* output_profile);
|
||||
int vipsgen_icc_transform_with_options(VipsImage* in, VipsImage** out, const char* output_profile, VipsPCS pcs, VipsIntent intent, gboolean black_point_compensation, gboolean embedded, const char* input_profile, gint depth);
|
||||
|
||||
int vipsgen_identity(VipsImage** out);
|
||||
int vipsgen_identity_with_options(VipsImage** out, gint bands, gboolean ushort, gint size);
|
||||
|
||||
int vipsgen_ifthenelse(VipsImage* cond, VipsImage* in1, VipsImage* in2, VipsImage** out);
|
||||
int vipsgen_ifthenelse_with_options(VipsImage* cond, VipsImage* in1, VipsImage* in2, VipsImage** out, gboolean blend);
|
||||
|
||||
int vipsgen_insert(VipsImage* main, VipsImage* sub, VipsImage** out, gint x, gint y);
|
||||
int vipsgen_insert_with_options(VipsImage* main, VipsImage* sub, VipsImage** out, gint x, gint y, gboolean expand, double* background, int background_n);
|
||||
|
||||
int vipsgen_invert(VipsImage* in, VipsImage** out);
|
||||
|
||||
int vipsgen_invertlut(VipsImage* in, VipsImage** out);
|
||||
int vipsgen_invertlut_with_options(VipsImage* in, VipsImage** out, gint size);
|
||||
|
||||
int vipsgen_invfft(VipsImage* in, VipsImage** out);
|
||||
int vipsgen_invfft_with_options(VipsImage* in, VipsImage** out, gboolean real);
|
||||
|
||||
int vipsgen_join(VipsImage* in1, VipsImage* in2, VipsImage** out, VipsDirection direction);
|
||||
int vipsgen_join_with_options(VipsImage* in1, VipsImage* in2, VipsImage** out, VipsDirection direction, gboolean expand, gint shim, double* background, int background_n, VipsAlign align);
|
||||
|
||||
int vipsgen_jp2kload(const char* filename, VipsImage** out);
|
||||
int vipsgen_jp2kload_with_options(const char* filename, VipsImage** out, gint page, gboolean oneshot, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_jp2kload_buffer(void* buf, size_t len, VipsImage** out);
|
||||
int vipsgen_jp2kload_buffer_with_options(void* buf, size_t len, VipsImage** out, gint page, gboolean oneshot, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_jp2kload_source(VipsSourceCustom* source, VipsImage** out);
|
||||
int vipsgen_jp2kload_source_with_options(VipsSourceCustom* source, VipsImage** out, gint page, gboolean oneshot, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_jp2ksave(VipsImage* in, const char* filename);
|
||||
int vipsgen_jp2ksave_with_options(VipsImage* in, const char* filename, gint tile_width, gint tile_height, gboolean lossless, gint Q, VipsForeignSubsample subsample_mode, VipsForeignKeep keep, double* background, int background_n, gint page_height, const char* profile);
|
||||
|
||||
int vipsgen_jp2ksave_buffer(VipsImage* in, void** buf, size_t* len);
|
||||
int vipsgen_jp2ksave_buffer_with_options(VipsImage* in, void** buf, size_t* len, gint tile_width, gint tile_height, gboolean lossless, gint Q, VipsForeignSubsample subsample_mode, VipsForeignKeep keep, double* background, int background_n, gint page_height, const char* profile);
|
||||
|
||||
int vipsgen_jp2ksave_target(VipsImage* in, VipsTargetCustom* target);
|
||||
int vipsgen_jp2ksave_target_with_options(VipsImage* in, VipsTargetCustom* target, gint tile_width, gint tile_height, gboolean lossless, gint Q, VipsForeignSubsample subsample_mode, VipsForeignKeep keep, double* background, int background_n, gint page_height, const char* profile);
|
||||
|
||||
int vipsgen_jpegload(const char* filename, VipsImage** out);
|
||||
int vipsgen_jpegload_with_options(const char* filename, VipsImage** out, gint shrink, gboolean autorotate, gboolean unlimited, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_jpegload_buffer(void* buf, size_t len, VipsImage** out);
|
||||
int vipsgen_jpegload_buffer_with_options(void* buf, size_t len, VipsImage** out, gint shrink, gboolean autorotate, gboolean unlimited, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_jpegload_source(VipsSourceCustom* source, VipsImage** out);
|
||||
int vipsgen_jpegload_source_with_options(VipsSourceCustom* source, VipsImage** out, gint shrink, gboolean autorotate, gboolean unlimited, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_jpegsave(VipsImage* in, const char* filename);
|
||||
int vipsgen_jpegsave_with_options(VipsImage* in, const char* filename, gint Q, gboolean optimize_coding, gboolean interlace, gboolean trellis_quant, gboolean overshoot_deringing, gboolean optimize_scans, gint quant_table, VipsForeignSubsample subsample_mode, gint restart_interval, VipsForeignKeep keep, double* background, int background_n, gint page_height, const char* profile);
|
||||
|
||||
int vipsgen_jpegsave_buffer(VipsImage* in, void** buf, size_t* len);
|
||||
int vipsgen_jpegsave_buffer_with_options(VipsImage* in, void** buf, size_t* len, gint Q, gboolean optimize_coding, gboolean interlace, gboolean trellis_quant, gboolean overshoot_deringing, gboolean optimize_scans, gint quant_table, VipsForeignSubsample subsample_mode, gint restart_interval, VipsForeignKeep keep, double* background, int background_n, gint page_height, const char* profile);
|
||||
|
||||
int vipsgen_jpegsave_target(VipsImage* in, VipsTargetCustom* target);
|
||||
int vipsgen_jpegsave_target_with_options(VipsImage* in, VipsTargetCustom* target, gint Q, gboolean optimize_coding, gboolean interlace, gboolean trellis_quant, gboolean overshoot_deringing, gboolean optimize_scans, gint quant_table, VipsForeignSubsample subsample_mode, gint restart_interval, VipsForeignKeep keep, double* background, int background_n, gint page_height, const char* profile);
|
||||
|
||||
int vipsgen_jxlload(const char* filename, VipsImage** out);
|
||||
int vipsgen_jxlload_with_options(const char* filename, VipsImage** out, gint page, gint n, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_jxlload_buffer(void* buf, size_t len, VipsImage** out);
|
||||
int vipsgen_jxlload_buffer_with_options(void* buf, size_t len, VipsImage** out, gint page, gint n, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_jxlload_source(VipsSourceCustom* source, VipsImage** out);
|
||||
int vipsgen_jxlload_source_with_options(VipsSourceCustom* source, VipsImage** out, gint page, gint n, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_jxlsave(VipsImage* in, const char* filename);
|
||||
int vipsgen_jxlsave_with_options(VipsImage* in, const char* filename, gint tier, double distance, gint effort, gboolean lossless, gint Q, VipsForeignKeep keep, double* background, int background_n, gint page_height, const char* profile);
|
||||
|
||||
int vipsgen_jxlsave_buffer(VipsImage* in, void** buf, size_t* len);
|
||||
int vipsgen_jxlsave_buffer_with_options(VipsImage* in, void** buf, size_t* len, gint tier, double distance, gint effort, gboolean lossless, gint Q, VipsForeignKeep keep, double* background, int background_n, gint page_height, const char* profile);
|
||||
|
||||
int vipsgen_jxlsave_target(VipsImage* in, VipsTargetCustom* target);
|
||||
int vipsgen_jxlsave_target_with_options(VipsImage* in, VipsTargetCustom* target, gint tier, double distance, gint effort, gboolean lossless, gint Q, VipsForeignKeep keep, double* background, int background_n, gint page_height, const char* profile);
|
||||
|
||||
int vipsgen_labelregions(VipsImage* in, VipsImage** mask);
|
||||
int vipsgen_labelregions_with_options(VipsImage* in, VipsImage** mask, gint* segments);
|
||||
|
||||
int vipsgen_linear(VipsImage* in, VipsImage** out, double* a, double* b, int n);
|
||||
int vipsgen_linear_with_options(VipsImage* in, VipsImage** out, double* a, double* b, int n, gboolean uchar);
|
||||
|
||||
int vipsgen_linecache(VipsImage* in, VipsImage** out);
|
||||
int vipsgen_linecache_with_options(VipsImage* in, VipsImage** out, gint tile_height, VipsAccess access, gboolean threaded, gboolean persistent);
|
||||
|
||||
int vipsgen_logmat(VipsImage** out, double sigma, double min_ampl);
|
||||
int vipsgen_logmat_with_options(VipsImage** out, double sigma, double min_ampl, gboolean separable, VipsPrecision precision);
|
||||
|
||||
int vipsgen_magickload(const char* filename, VipsImage** out);
|
||||
int vipsgen_magickload_with_options(const char* filename, VipsImage** out, const char* density, gint page, gint n, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_magickload_buffer(void* buf, size_t len, VipsImage** out);
|
||||
int vipsgen_magickload_buffer_with_options(void* buf, size_t len, VipsImage** out, const char* density, gint page, gint n, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_magicksave(VipsImage* in, const char* filename);
|
||||
int vipsgen_magicksave_with_options(VipsImage* in, const char* filename, const char* format, gint quality, gboolean optimize_gif_frames, gboolean optimize_gif_transparency, gint bitdepth, VipsForeignKeep keep, double* background, int background_n, gint page_height, const char* profile);
|
||||
|
||||
int vipsgen_magicksave_buffer(VipsImage* in, void** buf, size_t* len);
|
||||
int vipsgen_magicksave_buffer_with_options(VipsImage* in, void** buf, size_t* len, const char* format, gint quality, gboolean optimize_gif_frames, gboolean optimize_gif_transparency, gint bitdepth, VipsForeignKeep keep, double* background, int background_n, gint page_height, const char* profile);
|
||||
|
||||
int vipsgen_mapim(VipsImage* in, VipsImage** out, VipsImage* index);
|
||||
int vipsgen_mapim_with_options(VipsImage* in, VipsImage** out, VipsImage* index, VipsInterpolate* interpolate, double* background, int background_n, gboolean premultiplied, VipsExtend extend);
|
||||
|
||||
int vipsgen_maplut(VipsImage* in, VipsImage** out, VipsImage* lut);
|
||||
int vipsgen_maplut_with_options(VipsImage* in, VipsImage** out, VipsImage* lut, gint band);
|
||||
|
||||
int vipsgen_mask_butterworth(VipsImage** out, gint width, gint height, double order, double frequency_cutoff, double amplitude_cutoff);
|
||||
int vipsgen_mask_butterworth_with_options(VipsImage** out, gint width, gint height, double order, double frequency_cutoff, double amplitude_cutoff, gboolean uchar, gboolean nodc, gboolean reject, gboolean optical);
|
||||
|
||||
int vipsgen_mask_butterworth_band(VipsImage** out, gint width, gint height, double order, double frequency_cutoff_x, double frequency_cutoff_y, double radius, double amplitude_cutoff);
|
||||
int vipsgen_mask_butterworth_band_with_options(VipsImage** out, gint width, gint height, double order, double frequency_cutoff_x, double frequency_cutoff_y, double radius, double amplitude_cutoff, gboolean uchar, gboolean nodc, gboolean reject, gboolean optical);
|
||||
|
||||
int vipsgen_mask_butterworth_ring(VipsImage** out, gint width, gint height, double order, double frequency_cutoff, double amplitude_cutoff, double ringwidth);
|
||||
int vipsgen_mask_butterworth_ring_with_options(VipsImage** out, gint width, gint height, double order, double frequency_cutoff, double amplitude_cutoff, double ringwidth, gboolean uchar, gboolean nodc, gboolean reject, gboolean optical);
|
||||
|
||||
int vipsgen_mask_fractal(VipsImage** out, gint width, gint height, double fractal_dimension);
|
||||
int vipsgen_mask_fractal_with_options(VipsImage** out, gint width, gint height, double fractal_dimension, gboolean uchar, gboolean nodc, gboolean reject, gboolean optical);
|
||||
|
||||
int vipsgen_mask_gaussian(VipsImage** out, gint width, gint height, double frequency_cutoff, double amplitude_cutoff);
|
||||
int vipsgen_mask_gaussian_with_options(VipsImage** out, gint width, gint height, double frequency_cutoff, double amplitude_cutoff, gboolean uchar, gboolean nodc, gboolean reject, gboolean optical);
|
||||
|
||||
int vipsgen_mask_gaussian_band(VipsImage** out, gint width, gint height, double frequency_cutoff_x, double frequency_cutoff_y, double radius, double amplitude_cutoff);
|
||||
int vipsgen_mask_gaussian_band_with_options(VipsImage** out, gint width, gint height, double frequency_cutoff_x, double frequency_cutoff_y, double radius, double amplitude_cutoff, gboolean uchar, gboolean nodc, gboolean reject, gboolean optical);
|
||||
|
||||
int vipsgen_mask_gaussian_ring(VipsImage** out, gint width, gint height, double frequency_cutoff, double amplitude_cutoff, double ringwidth);
|
||||
int vipsgen_mask_gaussian_ring_with_options(VipsImage** out, gint width, gint height, double frequency_cutoff, double amplitude_cutoff, double ringwidth, gboolean uchar, gboolean nodc, gboolean reject, gboolean optical);
|
||||
|
||||
int vipsgen_mask_ideal(VipsImage** out, gint width, gint height, double frequency_cutoff);
|
||||
int vipsgen_mask_ideal_with_options(VipsImage** out, gint width, gint height, double frequency_cutoff, gboolean uchar, gboolean nodc, gboolean reject, gboolean optical);
|
||||
|
||||
int vipsgen_mask_ideal_band(VipsImage** out, gint width, gint height, double frequency_cutoff_x, double frequency_cutoff_y, double radius);
|
||||
int vipsgen_mask_ideal_band_with_options(VipsImage** out, gint width, gint height, double frequency_cutoff_x, double frequency_cutoff_y, double radius, gboolean uchar, gboolean nodc, gboolean reject, gboolean optical);
|
||||
|
||||
int vipsgen_mask_ideal_ring(VipsImage** out, gint width, gint height, double frequency_cutoff, double ringwidth);
|
||||
int vipsgen_mask_ideal_ring_with_options(VipsImage** out, gint width, gint height, double frequency_cutoff, double ringwidth, gboolean uchar, gboolean nodc, gboolean reject, gboolean optical);
|
||||
|
||||
int vipsgen_match(VipsImage* ref, VipsImage* sec, VipsImage** out, gint xr1, gint yr1, gint xs1, gint ys1, gint xr2, gint yr2, gint xs2, gint ys2);
|
||||
int vipsgen_match_with_options(VipsImage* ref, VipsImage* sec, VipsImage** out, gint xr1, gint yr1, gint xs1, gint ys1, gint xr2, gint yr2, gint xs2, gint ys2, gint hwindow, gint harea, gboolean search, VipsInterpolate* interpolate);
|
||||
|
||||
int vipsgen_math(VipsImage* in, VipsImage** out, VipsOperationMath math);
|
||||
|
||||
int vipsgen_math2(VipsImage* left, VipsImage* right, VipsImage** out, VipsOperationMath2 math2);
|
||||
|
||||
int vipsgen_math2_const(VipsImage* in, VipsImage** out, VipsOperationMath2 math2, double* c, int n);
|
||||
|
||||
int vipsgen_matload(const char* filename, VipsImage** out);
|
||||
int vipsgen_matload_with_options(const char* filename, VipsImage** out, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_matrixinvert(VipsImage* in, VipsImage** out);
|
||||
|
||||
int vipsgen_matrixload(const char* filename, VipsImage** out);
|
||||
int vipsgen_matrixload_with_options(const char* filename, VipsImage** out, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_matrixload_source(VipsSourceCustom* source, VipsImage** out);
|
||||
int vipsgen_matrixload_source_with_options(VipsSourceCustom* source, VipsImage** out, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_matrixmultiply(VipsImage* left, VipsImage* right, VipsImage** out);
|
||||
|
||||
int vipsgen_matrixprint(VipsImage* in);
|
||||
int vipsgen_matrixprint_with_options(VipsImage* in, VipsForeignKeep keep, double* background, int background_n, gint page_height, const char* profile);
|
||||
|
||||
int vipsgen_matrixsave(VipsImage* in, const char* filename);
|
||||
int vipsgen_matrixsave_with_options(VipsImage* in, const char* filename, VipsForeignKeep keep, double* background, int background_n, gint page_height, const char* profile);
|
||||
|
||||
int vipsgen_matrixsave_target(VipsImage* in, VipsTargetCustom* target);
|
||||
int vipsgen_matrixsave_target_with_options(VipsImage* in, VipsTargetCustom* target, VipsForeignKeep keep, double* background, int background_n, gint page_height, const char* profile);
|
||||
|
||||
int vipsgen_max(VipsImage* in, double* out);
|
||||
int vipsgen_max_with_options(VipsImage* in, double* out, gint size, gint* x, gint* y);
|
||||
|
||||
int vipsgen_maxpair(VipsImage* left, VipsImage* right, VipsImage** out);
|
||||
|
||||
int vipsgen_measure(VipsImage* in, VipsImage** out, gint h, gint v);
|
||||
int vipsgen_measure_with_options(VipsImage* in, VipsImage** out, gint h, gint v, gint left, gint top, gint width, gint height);
|
||||
|
||||
int vipsgen_merge(VipsImage* ref, VipsImage* sec, VipsImage** out, VipsDirection direction, gint dx, gint dy);
|
||||
int vipsgen_merge_with_options(VipsImage* ref, VipsImage* sec, VipsImage** out, VipsDirection direction, gint dx, gint dy, gint mblend);
|
||||
|
||||
int vipsgen_min(VipsImage* in, double* out);
|
||||
int vipsgen_min_with_options(VipsImage* in, double* out, gint size, gint* x, gint* y);
|
||||
|
||||
int vipsgen_minpair(VipsImage* left, VipsImage* right, VipsImage** out);
|
||||
|
||||
int vipsgen_morph(VipsImage* in, VipsImage** out, VipsImage* mask, VipsOperationMorphology morph);
|
||||
|
||||
int vipsgen_mosaic(VipsImage* ref, VipsImage* sec, VipsImage** out, VipsDirection direction, gint xref, gint yref, gint xsec, gint ysec);
|
||||
int vipsgen_mosaic_with_options(VipsImage* ref, VipsImage* sec, VipsImage** out, VipsDirection direction, gint xref, gint yref, gint xsec, gint ysec, gint hwindow, gint harea, gint mblend, gint bandno, gint* dx0, gint* dy0, double* scale1, double* angle1, double* dy1, double* dx1);
|
||||
|
||||
int vipsgen_mosaic1(VipsImage* ref, VipsImage* sec, VipsImage** out, VipsDirection direction, gint xr1, gint yr1, gint xs1, gint ys1, gint xr2, gint yr2, gint xs2, gint ys2);
|
||||
int vipsgen_mosaic1_with_options(VipsImage* ref, VipsImage* sec, VipsImage** out, VipsDirection direction, gint xr1, gint yr1, gint xs1, gint ys1, gint xr2, gint yr2, gint xs2, gint ys2, gint hwindow, gint harea, gboolean search, VipsInterpolate* interpolate, gint mblend);
|
||||
|
||||
int vipsgen_msb(VipsImage* in, VipsImage** out);
|
||||
int vipsgen_msb_with_options(VipsImage* in, VipsImage** out, gint band);
|
||||
|
||||
int vipsgen_multiply(VipsImage* left, VipsImage* right, VipsImage** out);
|
||||
|
||||
int vipsgen_niftiload(const char* filename, VipsImage** out);
|
||||
int vipsgen_niftiload_with_options(const char* filename, VipsImage** out, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_niftiload_source(VipsSourceCustom* source, VipsImage** out);
|
||||
int vipsgen_niftiload_source_with_options(VipsSourceCustom* source, VipsImage** out, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_niftisave(VipsImage* in, const char* filename);
|
||||
int vipsgen_niftisave_with_options(VipsImage* in, const char* filename, VipsForeignKeep keep, double* background, int background_n, gint page_height, const char* profile);
|
||||
|
||||
int vipsgen_openexrload(const char* filename, VipsImage** out);
|
||||
int vipsgen_openexrload_with_options(const char* filename, VipsImage** out, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_openslideload(const char* filename, VipsImage** out);
|
||||
int vipsgen_openslideload_with_options(const char* filename, VipsImage** out, gint level, gboolean autocrop, const char* associated, gboolean attach_associated, gboolean rgb, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_openslideload_source(VipsSourceCustom* source, VipsImage** out);
|
||||
int vipsgen_openslideload_source_with_options(VipsSourceCustom* source, VipsImage** out, gint level, gboolean autocrop, const char* associated, gboolean attach_associated, gboolean rgb, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_pdfload(const char* filename, VipsImage** out);
|
||||
int vipsgen_pdfload_with_options(const char* filename, VipsImage** out, gint page, gint n, double dpi, double scale, double* background, int background_n, const char* password, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_pdfload_buffer(void* buf, size_t len, VipsImage** out);
|
||||
int vipsgen_pdfload_buffer_with_options(void* buf, size_t len, VipsImage** out, gint page, gint n, double dpi, double scale, double* background, int background_n, const char* password, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_pdfload_source(VipsSourceCustom* source, VipsImage** out);
|
||||
int vipsgen_pdfload_source_with_options(VipsSourceCustom* source, VipsImage** out, gint page, gint n, double dpi, double scale, double* background, int background_n, const char* password, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_percent(VipsImage* in, double percent, gint* threshold);
|
||||
|
||||
int vipsgen_perlin(VipsImage** out, gint width, gint height);
|
||||
int vipsgen_perlin_with_options(VipsImage** out, gint width, gint height, gint cell_size, gboolean uchar, gint seed);
|
||||
|
||||
int vipsgen_phasecor(VipsImage* in, VipsImage* in2, VipsImage** out);
|
||||
|
||||
int vipsgen_pngload(const char* filename, VipsImage** out);
|
||||
int vipsgen_pngload_with_options(const char* filename, VipsImage** out, gboolean unlimited, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_pngload_buffer(void* buf, size_t len, VipsImage** out);
|
||||
int vipsgen_pngload_buffer_with_options(void* buf, size_t len, VipsImage** out, gboolean unlimited, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_pngload_source(VipsSourceCustom* source, VipsImage** out);
|
||||
int vipsgen_pngload_source_with_options(VipsSourceCustom* source, VipsImage** out, gboolean unlimited, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_pngsave(VipsImage* in, const char* filename);
|
||||
int vipsgen_pngsave_with_options(VipsImage* in, const char* filename, gint compression, gboolean interlace, VipsForeignPngFilter filter, gboolean palette, gint Q, double dither, gint bitdepth, gint effort, VipsForeignKeep keep, double* background, int background_n, gint page_height, const char* profile);
|
||||
|
||||
int vipsgen_pngsave_buffer(VipsImage* in, void** buf, size_t* len);
|
||||
int vipsgen_pngsave_buffer_with_options(VipsImage* in, void** buf, size_t* len, gint compression, gboolean interlace, VipsForeignPngFilter filter, gboolean palette, gint Q, double dither, gint bitdepth, gint effort, VipsForeignKeep keep, double* background, int background_n, gint page_height, const char* profile);
|
||||
|
||||
int vipsgen_pngsave_target(VipsImage* in, VipsTargetCustom* target);
|
||||
int vipsgen_pngsave_target_with_options(VipsImage* in, VipsTargetCustom* target, gint compression, gboolean interlace, VipsForeignPngFilter filter, gboolean palette, gint Q, double dither, gint bitdepth, gint effort, VipsForeignKeep keep, double* background, int background_n, gint page_height, const char* profile);
|
||||
|
||||
int vipsgen_ppmload(const char* filename, VipsImage** out);
|
||||
int vipsgen_ppmload_with_options(const char* filename, VipsImage** out, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_ppmload_buffer(void* buf, size_t len, VipsImage** out);
|
||||
int vipsgen_ppmload_buffer_with_options(void* buf, size_t len, VipsImage** out, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_ppmload_source(VipsSourceCustom* source, VipsImage** out);
|
||||
int vipsgen_ppmload_source_with_options(VipsSourceCustom* source, VipsImage** out, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_ppmsave(VipsImage* in, const char* filename);
|
||||
int vipsgen_ppmsave_with_options(VipsImage* in, const char* filename, VipsForeignPpmFormat format, gboolean ascii, gint bitdepth, VipsForeignKeep keep, double* background, int background_n, gint page_height, const char* profile);
|
||||
|
||||
int vipsgen_ppmsave_target(VipsImage* in, VipsTargetCustom* target);
|
||||
int vipsgen_ppmsave_target_with_options(VipsImage* in, VipsTargetCustom* target, VipsForeignPpmFormat format, gboolean ascii, gint bitdepth, VipsForeignKeep keep, double* background, int background_n, gint page_height, const char* profile);
|
||||
|
||||
int vipsgen_premultiply(VipsImage* in, VipsImage** out);
|
||||
int vipsgen_premultiply_with_options(VipsImage* in, VipsImage** out, double max_alpha);
|
||||
|
||||
int vipsgen_prewitt(VipsImage* in, VipsImage** out);
|
||||
|
||||
int vipsgen_profile(VipsImage* in, VipsImage** columns, VipsImage** rows);
|
||||
|
||||
int vipsgen_profile_load(const char* name, VipsBlob** profile);
|
||||
|
||||
int vipsgen_project(VipsImage* in, VipsImage** columns, VipsImage** rows);
|
||||
|
||||
int vipsgen_quadratic(VipsImage* in, VipsImage** out, VipsImage* coeff);
|
||||
int vipsgen_quadratic_with_options(VipsImage* in, VipsImage** out, VipsImage* coeff, VipsInterpolate* interpolate);
|
||||
|
||||
int vipsgen_rad2float(VipsImage* in, VipsImage** out);
|
||||
|
||||
int vipsgen_radload(const char* filename, VipsImage** out);
|
||||
int vipsgen_radload_with_options(const char* filename, VipsImage** out, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_radload_buffer(void* buf, size_t len, VipsImage** out);
|
||||
int vipsgen_radload_buffer_with_options(void* buf, size_t len, VipsImage** out, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_radload_source(VipsSourceCustom* source, VipsImage** out);
|
||||
int vipsgen_radload_source_with_options(VipsSourceCustom* source, VipsImage** out, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_radsave(VipsImage* in, const char* filename);
|
||||
int vipsgen_radsave_with_options(VipsImage* in, const char* filename, VipsForeignKeep keep, double* background, int background_n, gint page_height, const char* profile);
|
||||
|
||||
int vipsgen_radsave_buffer(VipsImage* in, void** buf, size_t* len);
|
||||
int vipsgen_radsave_buffer_with_options(VipsImage* in, void** buf, size_t* len, VipsForeignKeep keep, double* background, int background_n, gint page_height, const char* profile);
|
||||
|
||||
int vipsgen_radsave_target(VipsImage* in, VipsTargetCustom* target);
|
||||
int vipsgen_radsave_target_with_options(VipsImage* in, VipsTargetCustom* target, VipsForeignKeep keep, double* background, int background_n, gint page_height, const char* profile);
|
||||
|
||||
int vipsgen_rank(VipsImage* in, VipsImage** out, gint width, gint height, gint index);
|
||||
|
||||
int vipsgen_rawload(const char* filename, VipsImage** out, gint width, gint height, gint bands);
|
||||
int vipsgen_rawload_with_options(const char* filename, VipsImage** out, gint width, gint height, gint bands, guint64 offset, VipsBandFormat format, VipsInterpretation interpretation, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_rawsave(VipsImage* in, const char* filename);
|
||||
int vipsgen_rawsave_with_options(VipsImage* in, const char* filename, VipsForeignKeep keep, double* background, int background_n, gint page_height, const char* profile);
|
||||
|
||||
int vipsgen_rawsave_buffer(VipsImage* in, void** buf, size_t* len);
|
||||
int vipsgen_rawsave_buffer_with_options(VipsImage* in, void** buf, size_t* len, VipsForeignKeep keep, double* background, int background_n, gint page_height, const char* profile);
|
||||
|
||||
int vipsgen_rawsave_target(VipsImage* in, VipsTargetCustom* target);
|
||||
int vipsgen_rawsave_target_with_options(VipsImage* in, VipsTargetCustom* target, VipsForeignKeep keep, double* background, int background_n, gint page_height, const char* profile);
|
||||
|
||||
int vipsgen_recomb(VipsImage* in, VipsImage** out, VipsImage* m);
|
||||
|
||||
int vipsgen_reduce(VipsImage* in, VipsImage** out, double hshrink, double vshrink);
|
||||
int vipsgen_reduce_with_options(VipsImage* in, VipsImage** out, double hshrink, double vshrink, VipsKernel kernel, double gap);
|
||||
|
||||
int vipsgen_reduceh(VipsImage* in, VipsImage** out, double hshrink);
|
||||
int vipsgen_reduceh_with_options(VipsImage* in, VipsImage** out, double hshrink, VipsKernel kernel, double gap);
|
||||
|
||||
int vipsgen_reducev(VipsImage* in, VipsImage** out, double vshrink);
|
||||
int vipsgen_reducev_with_options(VipsImage* in, VipsImage** out, double vshrink, VipsKernel kernel, double gap);
|
||||
|
||||
int vipsgen_relational(VipsImage* left, VipsImage* right, VipsImage** out, VipsOperationRelational relational);
|
||||
|
||||
int vipsgen_relational_const(VipsImage* in, VipsImage** out, VipsOperationRelational relational, double* c, int n);
|
||||
|
||||
int vipsgen_remainder(VipsImage* left, VipsImage* right, VipsImage** out);
|
||||
|
||||
int vipsgen_remainder_const(VipsImage* in, VipsImage** out, double* c, int n);
|
||||
|
||||
int vipsgen_remosaic(VipsImage* in, VipsImage** out, const char* old_str, const char* new_str);
|
||||
|
||||
int vipsgen_replicate(VipsImage* in, VipsImage** out, gint across, gint down);
|
||||
|
||||
int vipsgen_resize(VipsImage* in, VipsImage** out, double scale);
|
||||
int vipsgen_resize_with_options(VipsImage* in, VipsImage** out, double scale, VipsKernel kernel, double gap, double vscale);
|
||||
|
||||
int vipsgen_rot(VipsImage* in, VipsImage** out, VipsAngle angle);
|
||||
|
||||
int vipsgen_rot45(VipsImage* in, VipsImage** out);
|
||||
int vipsgen_rot45_with_options(VipsImage* in, VipsImage** out, VipsAngle45 angle);
|
||||
|
||||
int vipsgen_rotate(VipsImage* in, VipsImage** out, double angle);
|
||||
int vipsgen_rotate_with_options(VipsImage* in, VipsImage** out, double angle, VipsInterpolate* interpolate, double* background, int background_n, double odx, double ody, double idx, double idy);
|
||||
|
||||
int vipsgen_round(VipsImage* in, VipsImage** out, VipsOperationRound round);
|
||||
|
||||
int vipsgen_sRGB2HSV(VipsImage* in, VipsImage** out);
|
||||
|
||||
int vipsgen_sRGB2scRGB(VipsImage* in, VipsImage** out);
|
||||
|
||||
int vipsgen_scRGB2BW(VipsImage* in, VipsImage** out);
|
||||
int vipsgen_scRGB2BW_with_options(VipsImage* in, VipsImage** out, gint depth);
|
||||
|
||||
int vipsgen_scRGB2XYZ(VipsImage* in, VipsImage** out);
|
||||
|
||||
int vipsgen_scRGB2sRGB(VipsImage* in, VipsImage** out);
|
||||
int vipsgen_scRGB2sRGB_with_options(VipsImage* in, VipsImage** out, gint depth);
|
||||
|
||||
int vipsgen_scale(VipsImage* in, VipsImage** out);
|
||||
int vipsgen_scale_with_options(VipsImage* in, VipsImage** out, double exp, gboolean log);
|
||||
|
||||
int vipsgen_scharr(VipsImage* in, VipsImage** out);
|
||||
|
||||
int vipsgen_sdf(VipsImage** out, gint width, gint height, VipsSdfShape shape);
|
||||
int vipsgen_sdf_with_options(VipsImage** out, gint width, gint height, VipsSdfShape shape, double r, double* a, int a_n, double* b, int b_n, double* corners, int corners_n);
|
||||
|
||||
int vipsgen_sequential(VipsImage* in, VipsImage** out);
|
||||
int vipsgen_sequential_with_options(VipsImage* in, VipsImage** out, gint tile_height);
|
||||
|
||||
int vipsgen_sharpen(VipsImage* in, VipsImage** out);
|
||||
int vipsgen_sharpen_with_options(VipsImage* in, VipsImage** out, double sigma, double x1, double y2, double y3, double m1, double m2);
|
||||
|
||||
int vipsgen_shrink(VipsImage* in, VipsImage** out, double hshrink, double vshrink);
|
||||
int vipsgen_shrink_with_options(VipsImage* in, VipsImage** out, double hshrink, double vshrink, gboolean ceil);
|
||||
|
||||
int vipsgen_shrinkh(VipsImage* in, VipsImage** out, gint hshrink);
|
||||
int vipsgen_shrinkh_with_options(VipsImage* in, VipsImage** out, gint hshrink, gboolean ceil);
|
||||
|
||||
int vipsgen_shrinkv(VipsImage* in, VipsImage** out, gint vshrink);
|
||||
int vipsgen_shrinkv_with_options(VipsImage* in, VipsImage** out, gint vshrink, gboolean ceil);
|
||||
|
||||
int vipsgen_sign(VipsImage* in, VipsImage** out);
|
||||
|
||||
int vipsgen_similarity(VipsImage* in, VipsImage** out);
|
||||
int vipsgen_similarity_with_options(VipsImage* in, VipsImage** out, double scale, double angle, VipsInterpolate* interpolate, double* background, int background_n, double odx, double ody, double idx, double idy);
|
||||
|
||||
int vipsgen_sines(VipsImage** out, gint width, gint height);
|
||||
int vipsgen_sines_with_options(VipsImage** out, gint width, gint height, gboolean uchar, double hfreq, double vfreq);
|
||||
|
||||
int vipsgen_smartcrop(VipsImage* input, VipsImage** out, gint width, gint height);
|
||||
int vipsgen_smartcrop_with_options(VipsImage* input, VipsImage** out, gint width, gint height, VipsInteresting interesting, gboolean premultiplied, gint* attention_x, gint* attention_y);
|
||||
|
||||
int vipsgen_sobel(VipsImage* in, VipsImage** out);
|
||||
|
||||
int vipsgen_spcor(VipsImage* in, VipsImage* ref, VipsImage** out);
|
||||
|
||||
int vipsgen_spectrum(VipsImage* in, VipsImage** out);
|
||||
|
||||
int vipsgen_stats(VipsImage* in, VipsImage** out);
|
||||
|
||||
int vipsgen_stdif(VipsImage* in, VipsImage** out, gint width, gint height);
|
||||
int vipsgen_stdif_with_options(VipsImage* in, VipsImage** out, gint width, gint height, double s0, double b, double m0, double a);
|
||||
|
||||
int vipsgen_subsample(VipsImage* input, VipsImage** out, gint xfac, gint yfac);
|
||||
int vipsgen_subsample_with_options(VipsImage* input, VipsImage** out, gint xfac, gint yfac, gboolean point);
|
||||
|
||||
int vipsgen_subtract(VipsImage* left, VipsImage* right, VipsImage** out);
|
||||
|
||||
int vipsgen_sum(VipsImage** in, VipsImage** out, int n);
|
||||
|
||||
int vipsgen_svgload(const char* filename, VipsImage** out);
|
||||
int vipsgen_svgload_with_options(const char* filename, VipsImage** out, double dpi, double scale, gboolean unlimited, const char* stylesheet, gboolean high_bitdepth, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_svgload_buffer(void* buf, size_t len, VipsImage** out);
|
||||
int vipsgen_svgload_buffer_with_options(void* buf, size_t len, VipsImage** out, double dpi, double scale, gboolean unlimited, const char* stylesheet, gboolean high_bitdepth, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_svgload_source(VipsSourceCustom* source, VipsImage** out);
|
||||
int vipsgen_svgload_source_with_options(VipsSourceCustom* source, VipsImage** out, double dpi, double scale, gboolean unlimited, const char* stylesheet, gboolean high_bitdepth, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_switch(VipsImage** tests, VipsImage** out, int n);
|
||||
|
||||
int vipsgen_system(const char* cmd_format);
|
||||
int vipsgen_system_with_options(const char* cmd_format, VipsImage** in, int in_n, const char* out_format, const char* in_format);
|
||||
|
||||
int vipsgen_text(VipsImage** out, const char* text);
|
||||
int vipsgen_text_with_options(VipsImage** out, const char* text, const char* font, gint width, gint height, VipsAlign align, gboolean justify, gint dpi, gint spacing, const char* fontfile, gboolean rgba, VipsTextWrap wrap, gint* autofit_dpi);
|
||||
|
||||
int vipsgen_thumbnail(const char* filename, VipsImage** out, gint width);
|
||||
int vipsgen_thumbnail_with_options(const char* filename, VipsImage** out, gint width, gint height, VipsSize size, gboolean no_rotate, VipsInteresting crop, gboolean linear, const char* input_profile, const char* output_profile, VipsIntent intent, VipsFailOn fail_on);
|
||||
|
||||
int vipsgen_thumbnail_buffer(void* buf, size_t len, VipsImage** out, gint width);
|
||||
int vipsgen_thumbnail_buffer_with_options(void* buf, size_t len, VipsImage** out, gint width, const char* option_string, gint height, VipsSize size, gboolean no_rotate, VipsInteresting crop, gboolean linear, const char* input_profile, const char* output_profile, VipsIntent intent, VipsFailOn fail_on);
|
||||
|
||||
int vipsgen_thumbnail_image(VipsImage* in, VipsImage** out, gint width);
|
||||
int vipsgen_thumbnail_image_with_options(VipsImage* in, VipsImage** out, gint width, gint height, VipsSize size, gboolean no_rotate, VipsInteresting crop, gboolean linear, const char* input_profile, const char* output_profile, VipsIntent intent, VipsFailOn fail_on);
|
||||
|
||||
int vipsgen_thumbnail_source(VipsSourceCustom* source, VipsImage** out, gint width);
|
||||
int vipsgen_thumbnail_source_with_options(VipsSourceCustom* source, VipsImage** out, gint width, const char* option_string, gint height, VipsSize size, gboolean no_rotate, VipsInteresting crop, gboolean linear, const char* input_profile, const char* output_profile, VipsIntent intent, VipsFailOn fail_on);
|
||||
|
||||
int vipsgen_tiffload(const char* filename, VipsImage** out);
|
||||
int vipsgen_tiffload_with_options(const char* filename, VipsImage** out, gint page, gint n, gboolean autorotate, gint subifd, gboolean unlimited, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_tiffload_buffer(void* buf, size_t len, VipsImage** out);
|
||||
int vipsgen_tiffload_buffer_with_options(void* buf, size_t len, VipsImage** out, gint page, gint n, gboolean autorotate, gint subifd, gboolean unlimited, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_tiffload_source(VipsSourceCustom* source, VipsImage** out);
|
||||
int vipsgen_tiffload_source_with_options(VipsSourceCustom* source, VipsImage** out, gint page, gint n, gboolean autorotate, gint subifd, gboolean unlimited, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_tiffsave(VipsImage* in, const char* filename);
|
||||
int vipsgen_tiffsave_with_options(VipsImage* in, const char* filename, VipsForeignTiffCompression compression, gint Q, VipsForeignTiffPredictor predictor, gboolean tile, gint tile_width, gint tile_height, gboolean pyramid, gboolean miniswhite, gint bitdepth, VipsForeignTiffResunit resunit, double xres, double yres, gboolean bigtiff, gboolean properties, VipsRegionShrink region_shrink, gint level, gboolean lossless, VipsForeignDzDepth depth, gboolean subifd, gboolean premultiply, VipsForeignKeep keep, double* background, int background_n, gint page_height, const char* profile);
|
||||
|
||||
int vipsgen_tiffsave_buffer(VipsImage* in, void** buf, size_t* len);
|
||||
int vipsgen_tiffsave_buffer_with_options(VipsImage* in, void** buf, size_t* len, VipsForeignTiffCompression compression, gint Q, VipsForeignTiffPredictor predictor, gboolean tile, gint tile_width, gint tile_height, gboolean pyramid, gboolean miniswhite, gint bitdepth, VipsForeignTiffResunit resunit, double xres, double yres, gboolean bigtiff, gboolean properties, VipsRegionShrink region_shrink, gint level, gboolean lossless, VipsForeignDzDepth depth, gboolean subifd, gboolean premultiply, VipsForeignKeep keep, double* background, int background_n, gint page_height, const char* profile);
|
||||
|
||||
int vipsgen_tiffsave_target(VipsImage* in, VipsTargetCustom* target);
|
||||
int vipsgen_tiffsave_target_with_options(VipsImage* in, VipsTargetCustom* target, VipsForeignTiffCompression compression, gint Q, VipsForeignTiffPredictor predictor, gboolean tile, gint tile_width, gint tile_height, gboolean pyramid, gboolean miniswhite, gint bitdepth, VipsForeignTiffResunit resunit, double xres, double yres, gboolean bigtiff, gboolean properties, VipsRegionShrink region_shrink, gint level, gboolean lossless, VipsForeignDzDepth depth, gboolean subifd, gboolean premultiply, VipsForeignKeep keep, double* background, int background_n, gint page_height, const char* profile);
|
||||
|
||||
int vipsgen_tilecache(VipsImage* in, VipsImage** out);
|
||||
int vipsgen_tilecache_with_options(VipsImage* in, VipsImage** out, gint tile_width, gint tile_height, gint max_tiles, VipsAccess access, gboolean threaded, gboolean persistent);
|
||||
|
||||
int vipsgen_tonelut(VipsImage** out);
|
||||
int vipsgen_tonelut_with_options(VipsImage** out, gint in_max, gint out_max, double Lb, double Lw, double Ps, double Pm, double Ph, double S, double M, double H);
|
||||
|
||||
int vipsgen_transpose3d(VipsImage* in, VipsImage** out);
|
||||
int vipsgen_transpose3d_with_options(VipsImage* in, VipsImage** out, gint page_height);
|
||||
|
||||
int vipsgen_unpremultiply(VipsImage* in, VipsImage** out);
|
||||
int vipsgen_unpremultiply_with_options(VipsImage* in, VipsImage** out, double max_alpha, gint alpha_band);
|
||||
|
||||
int vipsgen_vipsload(const char* filename, VipsImage** out);
|
||||
int vipsgen_vipsload_with_options(const char* filename, VipsImage** out, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_vipsload_source(VipsSourceCustom* source, VipsImage** out);
|
||||
int vipsgen_vipsload_source_with_options(VipsSourceCustom* source, VipsImage** out, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_vipssave(VipsImage* in, const char* filename);
|
||||
int vipsgen_vipssave_with_options(VipsImage* in, const char* filename, VipsForeignKeep keep, double* background, int background_n, gint page_height, const char* profile);
|
||||
|
||||
int vipsgen_vipssave_target(VipsImage* in, VipsTargetCustom* target);
|
||||
int vipsgen_vipssave_target_with_options(VipsImage* in, VipsTargetCustom* target, VipsForeignKeep keep, double* background, int background_n, gint page_height, const char* profile);
|
||||
|
||||
int vipsgen_webpload(const char* filename, VipsImage** out);
|
||||
int vipsgen_webpload_with_options(const char* filename, VipsImage** out, gint page, gint n, double scale, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_webpload_buffer(void* buf, size_t len, VipsImage** out);
|
||||
int vipsgen_webpload_buffer_with_options(void* buf, size_t len, VipsImage** out, gint page, gint n, double scale, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_webpload_source(VipsSourceCustom* source, VipsImage** out);
|
||||
int vipsgen_webpload_source_with_options(VipsSourceCustom* source, VipsImage** out, gint page, gint n, double scale, gboolean memory, VipsAccess access, VipsFailOn fail_on, gboolean revalidate);
|
||||
|
||||
int vipsgen_webpsave(VipsImage* in, const char* filename);
|
||||
int vipsgen_webpsave_with_options(VipsImage* in, const char* filename, gint Q, gboolean lossless, VipsForeignWebpPreset preset, gboolean smart_subsample, gboolean near_lossless, gint alpha_q, gboolean min_size, gint kmin, gint kmax, gint effort, gint target_size, gboolean mixed, gboolean smart_deblock, gint passes, VipsForeignKeep keep, double* background, int background_n, gint page_height, const char* profile);
|
||||
|
||||
int vipsgen_webpsave_buffer(VipsImage* in, void** buf, size_t* len);
|
||||
int vipsgen_webpsave_buffer_with_options(VipsImage* in, void** buf, size_t* len, gint Q, gboolean lossless, VipsForeignWebpPreset preset, gboolean smart_subsample, gboolean near_lossless, gint alpha_q, gboolean min_size, gint kmin, gint kmax, gint effort, gint target_size, gboolean mixed, gboolean smart_deblock, gint passes, VipsForeignKeep keep, double* background, int background_n, gint page_height, const char* profile);
|
||||
|
||||
int vipsgen_webpsave_target(VipsImage* in, VipsTargetCustom* target);
|
||||
int vipsgen_webpsave_target_with_options(VipsImage* in, VipsTargetCustom* target, gint Q, gboolean lossless, VipsForeignWebpPreset preset, gboolean smart_subsample, gboolean near_lossless, gint alpha_q, gboolean min_size, gint kmin, gint kmax, gint effort, gint target_size, gboolean mixed, gboolean smart_deblock, gint passes, VipsForeignKeep keep, double* background, int background_n, gint page_height, const char* profile);
|
||||
|
||||
int vipsgen_worley(VipsImage** out, gint width, gint height);
|
||||
int vipsgen_worley_with_options(VipsImage** out, gint width, gint height, gint cell_size, gint seed);
|
||||
|
||||
int vipsgen_wrap(VipsImage* in, VipsImage** out);
|
||||
int vipsgen_wrap_with_options(VipsImage* in, VipsImage** out, gint x, gint y);
|
||||
|
||||
int vipsgen_xyz(VipsImage** out, gint width, gint height);
|
||||
int vipsgen_xyz_with_options(VipsImage** out, gint width, gint height, gint csize, gint dsize, gint esize);
|
||||
|
||||
int vipsgen_zone(VipsImage** out, gint width, gint height);
|
||||
int vipsgen_zone_with_options(VipsImage** out, gint width, gint height, gboolean uchar);
|
||||
|
||||
int vipsgen_zoom(VipsImage* input, VipsImage** out, gint xfac, gint yfac);
|
||||
|
||||
|
||||
// Custom operations
|
||||
|
||||
int vipsgen_image_new_from_source(VipsSourceCustom *source, VipsImage **out);
|
||||
int vipsgen_image_new_from_source_with_option(VipsSourceCustom *source, VipsImage **out, const char *option_string);
|
||||
int vipsgen_image_new_from_file(const char *name, VipsImage **out);
|
||||
int vipsgen_image_new_from_buffer(const void *buf, size_t len, VipsImage **out);
|
||||
int vipsgen_image_new_from_buffer_with_option(const void *buf, size_t len, VipsImage **out, const char *option_string);
|
||||
int vipsgen_image_new_from_memory(const void *buf, size_t len, int width, int height, int bands, VipsImage **out);
|
||||
void vipsgen_clear_image(VipsImage **image);
|
||||
|
||||
int vipsgen_remove_exif(VipsImage *in, VipsImage **out);
|
||||
int vipsgen_embed_multi_page(VipsImage *in, VipsImage **out, int left, int top, int width, int height, int extend);
|
||||
int vipsgen_embed_multi_page_background(VipsImage *in, VipsImage **out, int left, int top, int width, int height, double r, double g, double b, double a);
|
||||
int vipsgen_extract_area_multi_page(VipsImage *in, VipsImage **out, int left, int top, int width, int height);
|
||||
int vipsgen_rot_multi_page(VipsImage *in, VipsImage **out, VipsAngle angle);
|
||||
int vipsgen_label(VipsImage *in, VipsImage **out, const char *text, const char *font, int x, int y, int size, VipsAlign align, double r, double g, double b, float opacity);
|
||||
24
vendor/github.com/davidbyttow/govips/v2/LICENSE
generated
vendored
24
vendor/github.com/davidbyttow/govips/v2/LICENSE
generated
vendored
@@ -1,24 +0,0 @@
|
||||
The MIT License
|
||||
|
||||
Copyright (c) Simple Things LLC and contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
71
vendor/github.com/davidbyttow/govips/v2/vips/arithmetic.c
generated
vendored
71
vendor/github.com/davidbyttow/govips/v2/vips/arithmetic.c
generated
vendored
@@ -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);
|
||||
}
|
||||
176
vendor/github.com/davidbyttow/govips/v2/vips/arithmetic.go
generated
vendored
176
vendor/github.com/davidbyttow/govips/v2/vips/arithmetic.go
generated
vendored
@@ -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
|
||||
}
|
||||
20
vendor/github.com/davidbyttow/govips/v2/vips/arithmetic.h
generated
vendored
20
vendor/github.com/davidbyttow/govips/v2/vips/arithmetic.h
generated
vendored
@@ -1,20 +0,0 @@
|
||||
// https://libvips.github.io/libvips/API/current/libvips-arithmetic.html
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <vips/vips.h>
|
||||
|
||||
int add(VipsImage *left, VipsImage *right, VipsImage **out);
|
||||
int multiply(VipsImage *left, VipsImage *right, VipsImage **out);
|
||||
int divide(VipsImage *left, VipsImage *right, VipsImage **out);
|
||||
int linear(VipsImage *in, VipsImage **out, double *a, double *b, int n);
|
||||
int linear1(VipsImage *in, VipsImage **out, double a, double b);
|
||||
int invert_image(VipsImage *in, VipsImage **out);
|
||||
int average(VipsImage *in, double *out);
|
||||
int find_trim(VipsImage *in, int *left, int *top, int *width, int *height,
|
||||
double threshold, double r, double g, double b);
|
||||
int getpoint(VipsImage *in, double **vector, int n, int x, int y);
|
||||
int stats(VipsImage *in, VipsImage **out);
|
||||
int hist_find(VipsImage *in, VipsImage **out);
|
||||
int hist_cum(VipsImage *in, VipsImage **out);
|
||||
int hist_norm(VipsImage *in, VipsImage **out);
|
||||
int hist_entropy(VipsImage *in, double *out);
|
||||
22
vendor/github.com/davidbyttow/govips/v2/vips/color.c
generated
vendored
22
vendor/github.com/davidbyttow/govips/v2/vips/color.c
generated
vendored
@@ -1,22 +0,0 @@
|
||||
#include "color.h"
|
||||
#include <unistd.h>
|
||||
|
||||
int is_colorspace_supported(VipsImage *in) {
|
||||
return vips_colourspace_issupported(in) ? 1 : 0;
|
||||
}
|
||||
|
||||
int to_colorspace(VipsImage *in, VipsImage **out, VipsInterpretation space) {
|
||||
return vips_colourspace(in, out, space, NULL);
|
||||
}
|
||||
|
||||
// https://libvips.github.io/libvips/API/8.6/libvips-colour.html#vips-icc-transform
|
||||
int icc_transform(VipsImage *in, VipsImage **out, const char *output_profile, const char *input_profile, VipsIntent intent,
|
||||
int depth, gboolean embedded) {
|
||||
return vips_icc_transform(
|
||||
in, out, output_profile,
|
||||
"input_profile", input_profile ? input_profile : "none",
|
||||
"intent", intent,
|
||||
"depth", depth ? depth : 8,
|
||||
"embedded", embedded,
|
||||
NULL);
|
||||
}
|
||||
96
vendor/github.com/davidbyttow/govips/v2/vips/color.go
generated
vendored
96
vendor/github.com/davidbyttow/govips/v2/vips/color.go
generated
vendored
@@ -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
|
||||
}
|
||||
10
vendor/github.com/davidbyttow/govips/v2/vips/color.h
generated
vendored
10
vendor/github.com/davidbyttow/govips/v2/vips/color.h
generated
vendored
@@ -1,10 +0,0 @@
|
||||
// https://libvips.github.io/libvips/API/current/libvips-colour.html
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <vips/vips.h>
|
||||
|
||||
int is_colorspace_supported(VipsImage *in);
|
||||
int to_colorspace(VipsImage *in, VipsImage **out, VipsInterpretation space);
|
||||
|
||||
int icc_transform(VipsImage *in, VipsImage **out, const char *output_profile, const char *input_profile, VipsIntent intent,
|
||||
int depth, gboolean embedded);
|
||||
27
vendor/github.com/davidbyttow/govips/v2/vips/composite.go
generated
vendored
27
vendor/github.com/davidbyttow/govips/v2/vips/composite.go
generated
vendored
@@ -1,27 +0,0 @@
|
||||
package vips
|
||||
|
||||
// #include <vips/vips.h>
|
||||
import "C"
|
||||
|
||||
// ImageComposite image to composite param
|
||||
type ImageComposite struct {
|
||||
Image *ImageRef
|
||||
BlendMode BlendMode
|
||||
X, Y int
|
||||
}
|
||||
|
||||
func toVipsCompositeStructs(r *ImageRef, datas []*ImageComposite) ([]*C.VipsImage, []C.int, []C.int, []C.int) {
|
||||
ins := []*C.VipsImage{r.image}
|
||||
modes := []C.int{}
|
||||
xs := []C.int{}
|
||||
ys := []C.int{}
|
||||
|
||||
for _, image := range datas {
|
||||
ins = append(ins, image.Image.image)
|
||||
modes = append(modes, C.int(image.BlendMode))
|
||||
xs = append(xs, C.int(image.X))
|
||||
ys = append(ys, C.int(image.Y))
|
||||
}
|
||||
|
||||
return ins, modes, xs, ys
|
||||
}
|
||||
380
vendor/github.com/davidbyttow/govips/v2/vips/conversion.c
generated
vendored
380
vendor/github.com/davidbyttow/govips/v2/vips/conversion.c
generated
vendored
@@ -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);
|
||||
}
|
||||
520
vendor/github.com/davidbyttow/govips/v2/vips/conversion.go
generated
vendored
520
vendor/github.com/davidbyttow/govips/v2/vips/conversion.go
generated
vendored
@@ -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
|
||||
}
|
||||
70
vendor/github.com/davidbyttow/govips/v2/vips/conversion.h
generated
vendored
70
vendor/github.com/davidbyttow/govips/v2/vips/conversion.h
generated
vendored
@@ -1,70 +0,0 @@
|
||||
// https://libvips.github.io/libvips/API/current/libvips-conversion.html
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <vips/vips.h>
|
||||
|
||||
int copy_image_changing_interpretation(VipsImage *in, VipsImage **out,
|
||||
VipsInterpretation interpretation);
|
||||
int copy_image_changing_resolution(VipsImage *in, VipsImage **out, double xres,
|
||||
double yres);
|
||||
int copy_image(VipsImage *in, VipsImage **out);
|
||||
|
||||
int embed_image(VipsImage *in, VipsImage **out, int left, int top, int width,
|
||||
int height, int extend);
|
||||
int embed_image_background(VipsImage *in, VipsImage **out, int left, int top, int width,
|
||||
int height, double r, double g, double b, double a);
|
||||
int embed_multi_page_image(VipsImage *in, VipsImage **out, int left, int top, int width,
|
||||
int height, int extend);
|
||||
int embed_multi_page_image_background(VipsImage *in, VipsImage **out, int left, int top,
|
||||
int width, int height, double r, double g, double b, double a);
|
||||
|
||||
int flip_image(VipsImage *in, VipsImage **out, int direction);
|
||||
|
||||
int recomb_image(VipsImage *in, VipsImage **out, VipsImage *m);
|
||||
|
||||
int extract_image_area(VipsImage *in, VipsImage **out, int left, int top,
|
||||
int width, int height);
|
||||
int extract_area_multi_page(VipsImage *in, VipsImage **out, int left, int top,
|
||||
int width, int height);
|
||||
|
||||
int extract_band(VipsImage *in, VipsImage **out, int band, int num);
|
||||
|
||||
int rot_image(VipsImage *in, VipsImage **out, VipsAngle angle);
|
||||
int autorot_image(VipsImage *in, VipsImage **out);
|
||||
|
||||
int zoom_image(VipsImage *in, VipsImage **out, int xfac, int yfac);
|
||||
int smartcrop(VipsImage *in, VipsImage **out, int width, int height,
|
||||
int interesting);
|
||||
int crop(VipsImage *in, VipsImage **out, int left, int top,
|
||||
int width, int height);
|
||||
|
||||
int bandjoin(VipsImage **in, VipsImage **out, int n);
|
||||
int bandjoin_const(VipsImage *in, VipsImage **out, double constants[], int n);
|
||||
int similarity(VipsImage *in, VipsImage **out, double scale, double angle,
|
||||
double r, double g, double b, double a, double idx, double idy,
|
||||
double odx, double ody);
|
||||
int flatten_image(VipsImage *in, VipsImage **out, double r, double g, double b);
|
||||
int add_alpha(VipsImage *in, VipsImage **out);
|
||||
int premultiply_alpha(VipsImage *in, VipsImage **out);
|
||||
int unpremultiply_alpha(VipsImage *in, VipsImage **out);
|
||||
int cast(VipsImage *in, VipsImage **out, int bandFormat);
|
||||
double max_alpha(VipsImage *in);
|
||||
|
||||
int composite_image(VipsImage **in, VipsImage **out, int n, int *mode, int *x,
|
||||
int *y);
|
||||
int composite2_image(VipsImage *base, VipsImage *overlay, VipsImage **out,
|
||||
int mode, gint x, gint y);
|
||||
|
||||
int insert_image(VipsImage *main, VipsImage *sub, VipsImage **out, int x, int y,
|
||||
int expand, double r, double g, double b, double a);
|
||||
|
||||
int join(VipsImage *in1, VipsImage *in2, VipsImage **out, int direction);
|
||||
int arrayjoin(VipsImage **in, VipsImage **out, int n, int across);
|
||||
|
||||
int is_16bit(VipsInterpretation interpretation);
|
||||
|
||||
int replicate(VipsImage *in, VipsImage **out, int across, int down);
|
||||
|
||||
int grid(VipsImage *in, VipsImage **out, int tileHeight, int across, int down);
|
||||
|
||||
int adjust_gamma(VipsImage *in, VipsImage **out, double g);
|
||||
14
vendor/github.com/davidbyttow/govips/v2/vips/convolution.c
generated
vendored
14
vendor/github.com/davidbyttow/govips/v2/vips/convolution.c
generated
vendored
@@ -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);
|
||||
}
|
||||
40
vendor/github.com/davidbyttow/govips/v2/vips/convolution.go
generated
vendored
40
vendor/github.com/davidbyttow/govips/v2/vips/convolution.go
generated
vendored
@@ -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
|
||||
}
|
||||
9
vendor/github.com/davidbyttow/govips/v2/vips/convolution.h
generated
vendored
9
vendor/github.com/davidbyttow/govips/v2/vips/convolution.h
generated
vendored
@@ -1,9 +0,0 @@
|
||||
// https://libvips.github.io/libvips/API/current/libvips-convolution.html
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <vips/vips.h>
|
||||
|
||||
int gaussian_blur_image(VipsImage *in, VipsImage **out, double sigma, double min_ampl);
|
||||
int sharpen_image(VipsImage *in, VipsImage **out, double sigma, double x1,
|
||||
double m2);
|
||||
int sobel_image(VipsImage *in, VipsImage **out);
|
||||
24
vendor/github.com/davidbyttow/govips/v2/vips/create.c
generated
vendored
24
vendor/github.com/davidbyttow/govips/v2/vips/create.c
generated
vendored
@@ -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);
|
||||
}
|
||||
}
|
||||
37
vendor/github.com/davidbyttow/govips/v2/vips/create.go
generated
vendored
37
vendor/github.com/davidbyttow/govips/v2/vips/create.go
generated
vendored
@@ -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
|
||||
}
|
||||
12
vendor/github.com/davidbyttow/govips/v2/vips/create.h
generated
vendored
12
vendor/github.com/davidbyttow/govips/v2/vips/create.h
generated
vendored
@@ -1,12 +0,0 @@
|
||||
// https://libvips.github.io/libvips/API/current/libvips-create.html
|
||||
|
||||
// clang-format off
|
||||
// include order matters
|
||||
#include <stdlib.h>
|
||||
#include <vips/vips.h>
|
||||
#include <vips/foreign.h>
|
||||
// clang-format on
|
||||
|
||||
int xyz(VipsImage **out, int width, int height);
|
||||
int black(VipsImage **out, int width, int height);
|
||||
int identity(VipsImage **out, int ushort);
|
||||
24
vendor/github.com/davidbyttow/govips/v2/vips/draw.c
generated
vendored
24
vendor/github.com/davidbyttow/govips/v2/vips/draw.c
generated
vendored
@@ -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);
|
||||
}
|
||||
}
|
||||
21
vendor/github.com/davidbyttow/govips/v2/vips/draw.go
generated
vendored
21
vendor/github.com/davidbyttow/govips/v2/vips/draw.go
generated
vendored
@@ -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
|
||||
}
|
||||
7
vendor/github.com/davidbyttow/govips/v2/vips/draw.h
generated
vendored
7
vendor/github.com/davidbyttow/govips/v2/vips/draw.h
generated
vendored
@@ -1,7 +0,0 @@
|
||||
// https://libvips.github.io/libvips/API/current/libvips-draw.html
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <vips/vips.h>
|
||||
|
||||
int draw_rect(VipsImage *in, double r, double g, double b, double a, int left,
|
||||
int top, int width, int height, int fill);
|
||||
39
vendor/github.com/davidbyttow/govips/v2/vips/error.go
generated
vendored
39
vendor/github.com/davidbyttow/govips/v2/vips/error.go
generated
vendored
@@ -1,39 +0,0 @@
|
||||
package vips
|
||||
|
||||
// #include <vips/vips.h>
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
dbg "runtime/debug"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrUnsupportedImageFormat when image type is unsupported
|
||||
ErrUnsupportedImageFormat = errors.New("unsupported image format")
|
||||
)
|
||||
|
||||
func handleImageError(out *C.VipsImage) error {
|
||||
if out != nil {
|
||||
clearImage(out)
|
||||
}
|
||||
|
||||
return handleVipsError()
|
||||
}
|
||||
|
||||
func handleSaveBufferError(out unsafe.Pointer) error {
|
||||
if out != nil {
|
||||
gFreePointer(out)
|
||||
}
|
||||
|
||||
return handleVipsError()
|
||||
}
|
||||
|
||||
func handleVipsError() error {
|
||||
s := C.GoString(C.vips_error_buffer())
|
||||
C.vips_error_clear()
|
||||
|
||||
return fmt.Errorf("%v\nStack:\n%s", s, dbg.Stack())
|
||||
}
|
||||
578
vendor/github.com/davidbyttow/govips/v2/vips/foreign.c
generated
vendored
578
vendor/github.com/davidbyttow/govips/v2/vips/foreign.c
generated
vendored
@@ -1,578 +0,0 @@
|
||||
#include "foreign.h"
|
||||
|
||||
#include "lang.h"
|
||||
|
||||
void set_bool_param(Param *p, gboolean b) {
|
||||
p->type = PARAM_TYPE_BOOL;
|
||||
p->value.b = b;
|
||||
p->is_set = TRUE;
|
||||
}
|
||||
|
||||
void set_int_param(Param *p, gint i) {
|
||||
p->type = PARAM_TYPE_INT;
|
||||
p->value.i = i;
|
||||
p->is_set = TRUE;
|
||||
}
|
||||
|
||||
void set_double_param(Param *p, gdouble d) {
|
||||
p->type = PARAM_TYPE_DOUBLE;
|
||||
p->value.d = d;
|
||||
p->is_set = TRUE;
|
||||
}
|
||||
|
||||
int load_image_buffer(LoadParams *params, void *buf, size_t len,
|
||||
VipsImage **out) {
|
||||
int code = 1;
|
||||
ImageType imageType = params->inputFormat;
|
||||
|
||||
if (imageType == JPEG) {
|
||||
// shrink: int, fail: bool, autorotate: bool
|
||||
code = vips_jpegload_buffer(buf, len, out, "fail", params->fail,
|
||||
"autorotate", params->autorotate, "shrink",
|
||||
params->jpegShrink, NULL);
|
||||
} else if (imageType == PNG) {
|
||||
code = vips_pngload_buffer(buf, len, out, NULL);
|
||||
} else if (imageType == WEBP) {
|
||||
// page: int, n: int, scale: double
|
||||
code = vips_webpload_buffer(buf, len, out, "page", params->page, "n",
|
||||
params->n, NULL);
|
||||
} else if (imageType == TIFF) {
|
||||
// page: int, n: int, autorotate: bool, subifd: int
|
||||
code =
|
||||
vips_tiffload_buffer(buf, len, out, "page", params->page, "n",
|
||||
params->n, "autorotate", params->autorotate, NULL);
|
||||
} else if (imageType == GIF) {
|
||||
// page: int, n: int, scale: double
|
||||
code = vips_gifload_buffer(buf, len, out, "page", params->page, "n",
|
||||
params->n, NULL);
|
||||
} else if (imageType == PDF) {
|
||||
// page: int, n: int, dpi: double, scale: double, background: color
|
||||
code = vips_pdfload_buffer(buf, len, out, "page", params->page, "n",
|
||||
params->n, "dpi", params->dpi, NULL);
|
||||
} else if (imageType == SVG) {
|
||||
// dpi: double, scale: double, unlimited: bool
|
||||
code = vips_svgload_buffer(buf, len, out, "dpi", params->dpi, "unlimited",
|
||||
params->svgUnlimited, NULL);
|
||||
} else if (imageType == HEIF) {
|
||||
// added autorotate on load as currently it addresses orientation issues
|
||||
// https://github.com/libvips/libvips/pull/1680
|
||||
// page: int, n: int, thumbnail: bool
|
||||
code = vips_heifload_buffer(buf, len, out, "page", params->page, "n",
|
||||
params->n, "thumbnail", params->heifThumbnail,
|
||||
"autorotate", TRUE, NULL);
|
||||
} else if (imageType == MAGICK) {
|
||||
// page: int, n: int, density: string
|
||||
code = vips_magickload_buffer(buf, len, out, "page", params->page, "n",
|
||||
params->n, NULL);
|
||||
} else if (imageType == AVIF) {
|
||||
code = vips_heifload_buffer(buf, len, out, "page", params->page, "n",
|
||||
params->n, "thumbnail", params->heifThumbnail,
|
||||
"autorotate", params->autorotate, NULL);
|
||||
|
||||
}
|
||||
#if (VIPS_MAJOR_VERSION >= 8) && (VIPS_MINOR_VERSION >= 11)
|
||||
else if (imageType == JP2K) {
|
||||
code = vips_jp2kload_buffer(buf, len, out, "page", params->page, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
#define MAYBE_SET_BOOL(OP, PARAM, NAME) \
|
||||
if (PARAM.is_set) { \
|
||||
vips_object_set(VIPS_OBJECT(OP), NAME, PARAM.value.b, NULL); \
|
||||
}
|
||||
|
||||
#define MAYBE_SET_INT(OP, PARAM, NAME) \
|
||||
if (PARAM.is_set) { \
|
||||
vips_object_set(VIPS_OBJECT(OP), NAME, PARAM.value.i, NULL); \
|
||||
}
|
||||
|
||||
#define MAYBE_SET_DOUBLE(OP, PARAM, NAME) \
|
||||
if (PARAM.is_set) { \
|
||||
vips_object_set(VIPS_OBJECT(OP), NAME, PARAM.value.d, NULL); \
|
||||
}
|
||||
|
||||
typedef int (*SetLoadOptionsFn)(VipsOperation *operation, LoadParams *params);
|
||||
|
||||
int set_jpegload_options(VipsOperation *operation, LoadParams *params) {
|
||||
MAYBE_SET_BOOL(operation, params->autorotate, "autorotate");
|
||||
MAYBE_SET_BOOL(operation, params->fail, "fail");
|
||||
MAYBE_SET_INT(operation, params->jpegShrink, "shrink");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int set_pngload_options(VipsOperation *operation, LoadParams *params) {
|
||||
MAYBE_SET_BOOL(operation, params->fail, "fail");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int set_webpload_options(VipsOperation *operation, LoadParams *params) {
|
||||
MAYBE_SET_INT(operation, params->page, "page");
|
||||
MAYBE_SET_INT(operation, params->n, "n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int set_tiffload_options(VipsOperation *operation, LoadParams *params) {
|
||||
MAYBE_SET_BOOL(operation, params->autorotate, "autorotate");
|
||||
MAYBE_SET_INT(operation, params->page, "page");
|
||||
MAYBE_SET_INT(operation, params->n, "n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int set_gifload_options(VipsOperation *operation, LoadParams *params) {
|
||||
MAYBE_SET_INT(operation, params->page, "page");
|
||||
MAYBE_SET_INT(operation, params->n, "n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int set_pdfload_options(VipsOperation *operation, LoadParams *params) {
|
||||
MAYBE_SET_INT(operation, params->page, "page");
|
||||
MAYBE_SET_INT(operation, params->n, "n");
|
||||
MAYBE_SET_DOUBLE(operation, params->dpi, "dpi");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int set_svgload_options(VipsOperation *operation, LoadParams *params) {
|
||||
MAYBE_SET_BOOL(operation, params->svgUnlimited, "unlimited");
|
||||
MAYBE_SET_DOUBLE(operation, params->dpi, "dpi");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int set_heifload_options(VipsOperation *operation, LoadParams *params) {
|
||||
MAYBE_SET_BOOL(operation, params->autorotate, "autorotate");
|
||||
MAYBE_SET_BOOL(operation, params->heifThumbnail, "thumbnail");
|
||||
MAYBE_SET_INT(operation, params->page, "page");
|
||||
MAYBE_SET_INT(operation, params->n, "n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int set_jp2kload_options(VipsOperation *operation, LoadParams *params) {
|
||||
MAYBE_SET_INT(operation, params->page, "page");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int set_jxlload_options(VipsOperation *operation, LoadParams *params) {
|
||||
// nothing need to do
|
||||
return 0;
|
||||
}
|
||||
|
||||
int set_magickload_options(VipsOperation *operation, LoadParams *params) {
|
||||
MAYBE_SET_INT(operation, params->page, "page");
|
||||
MAYBE_SET_INT(operation, params->n, "n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int load_buffer(const char *operationName, void *buf, size_t len,
|
||||
LoadParams *params, SetLoadOptionsFn setLoadOptions) {
|
||||
VipsBlob *blob = vips_blob_new(NULL, buf, len);
|
||||
|
||||
VipsOperation *operation = vips_operation_new(operationName);
|
||||
if (!operation) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (vips_object_set(VIPS_OBJECT(operation), "buffer", blob, NULL)) {
|
||||
vips_area_unref(VIPS_AREA(blob));
|
||||
return 1;
|
||||
}
|
||||
|
||||
vips_area_unref(VIPS_AREA(blob));
|
||||
|
||||
if (setLoadOptions(operation, params)) {
|
||||
vips_object_unref_outputs(VIPS_OBJECT(operation));
|
||||
g_object_unref(operation);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (vips_cache_operation_buildp(&operation)) {
|
||||
vips_object_unref_outputs(VIPS_OBJECT(operation));
|
||||
g_object_unref(operation);
|
||||
return 1;
|
||||
}
|
||||
|
||||
g_object_get(VIPS_OBJECT(operation), "out", ¶ms->outputImage, NULL);
|
||||
|
||||
vips_object_unref_outputs(VIPS_OBJECT(operation));
|
||||
g_object_unref(operation);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef int (*SetSaveOptionsFn)(VipsOperation *operation, SaveParams *params);
|
||||
|
||||
int save_buffer(const char *operationName, SaveParams *params,
|
||||
SetSaveOptionsFn setSaveOptions) {
|
||||
VipsBlob *blob;
|
||||
VipsOperation *operation = vips_operation_new(operationName);
|
||||
if (!operation) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (vips_object_set(VIPS_OBJECT(operation), "in", params->inputImage, NULL)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (setSaveOptions(operation, params)) {
|
||||
g_object_unref(operation);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (vips_cache_operation_buildp(&operation)) {
|
||||
vips_object_unref_outputs(VIPS_OBJECT(operation));
|
||||
g_object_unref(operation);
|
||||
return 1;
|
||||
}
|
||||
|
||||
g_object_get(VIPS_OBJECT(operation), "buffer", &blob, NULL);
|
||||
g_object_unref(operation);
|
||||
|
||||
VipsArea *area = VIPS_AREA(blob);
|
||||
|
||||
params->outputBuffer = (char *)(area->data);
|
||||
params->outputLen = area->length;
|
||||
area->free_fn = NULL;
|
||||
vips_area_unref(area);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// https://libvips.github.io/libvips/API/current/VipsForeignSave.html#vips-jpegsave-buffer
|
||||
int set_jpegsave_options(VipsOperation *operation, SaveParams *params) {
|
||||
int ret = vips_object_set(
|
||||
VIPS_OBJECT(operation), "strip", params->stripMetadata, "optimize_coding",
|
||||
params->jpegOptimizeCoding, "interlace", params->interlace,
|
||||
"subsample_mode", params->jpegSubsample, "trellis_quant",
|
||||
params->jpegTrellisQuant, "overshoot_deringing",
|
||||
params->jpegOvershootDeringing, "optimize_scans",
|
||||
params->jpegOptimizeScans, "quant_table", params->jpegQuantTable, NULL);
|
||||
|
||||
if (!ret && params->quality) {
|
||||
ret = vips_object_set(VIPS_OBJECT(operation), "Q", params->quality, NULL);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// https://libvips.github.io/libvips/API/current/VipsForeignSave.html#vips-pngsave-buffer
|
||||
int set_pngsave_options(VipsOperation *operation, SaveParams *params) {
|
||||
int ret =
|
||||
vips_object_set(VIPS_OBJECT(operation), "strip", params->stripMetadata,
|
||||
"compression", params->pngCompression, "interlace",
|
||||
params->interlace, "filter", params->pngFilter, "palette",
|
||||
params->pngPalette, NULL);
|
||||
|
||||
if (!ret && params->quality) {
|
||||
ret = vips_object_set(VIPS_OBJECT(operation), "Q", params->quality, NULL);
|
||||
}
|
||||
|
||||
if (!ret && params->pngDither) {
|
||||
ret = vips_object_set(VIPS_OBJECT(operation), "dither", params->pngDither, NULL);
|
||||
}
|
||||
|
||||
if (!ret && params->pngBitdepth) {
|
||||
ret = vips_object_set(VIPS_OBJECT(operation), "bitdepth", params->pngBitdepth, NULL);
|
||||
}
|
||||
|
||||
// TODO: Handle `profile` param.
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// https://github.com/libvips/libvips/blob/master/libvips/foreign/webpsave.c#L524
|
||||
// https://libvips.github.io/libvips/API/current/VipsForeignSave.html#vips-webpsave-buffer
|
||||
int set_webpsave_options(VipsOperation *operation, SaveParams *params) {
|
||||
int ret =
|
||||
vips_object_set(VIPS_OBJECT(operation),
|
||||
"strip", params->stripMetadata,
|
||||
"lossless", params->webpLossless,
|
||||
"near_lossless", params->webpNearLossless,
|
||||
"reduction_effort", params->webpReductionEffort,
|
||||
"profile", params->webpIccProfile ? params->webpIccProfile : "none",
|
||||
"min_size", params->webpMinSize,
|
||||
"kmin", params->webpKMin,
|
||||
"kmax", params->webpKMax,
|
||||
NULL);
|
||||
|
||||
if (!ret && params->quality) {
|
||||
ret = vips_object_set(VIPS_OBJECT(operation), "Q", params->quality, NULL);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// https://libvips.github.io/libvips/API/current/VipsForeignSave.html#vips-tiffsave-buffer
|
||||
int set_tiffsave_options(VipsOperation *operation, SaveParams *params) {
|
||||
int ret = vips_object_set(
|
||||
VIPS_OBJECT(operation), "strip", params->stripMetadata, "compression",
|
||||
params->tiffCompression, "predictor", params->tiffPredictor, "pyramid",
|
||||
params->tiffPyramid, "tile_height", params->tiffTileHeight, "tile_width",
|
||||
params->tiffTileWidth, "tile", params->tiffTile, NULL);
|
||||
|
||||
if (!ret && params->quality) {
|
||||
ret = vips_object_set(VIPS_OBJECT(operation), "Q", params->quality, NULL);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// https://libvips.github.io/libvips/API/current/VipsForeignSave.html#vips-magicksave-buffer
|
||||
int set_magicksave_options(VipsOperation *operation, SaveParams *params) {
|
||||
int ret = vips_object_set(VIPS_OBJECT(operation), "format", "GIF", "bitdepth", params->gifBitdepth, NULL);
|
||||
|
||||
if (!ret && params->quality) {
|
||||
ret = vips_object_set(VIPS_OBJECT(operation), "quality", params->quality,
|
||||
NULL);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// https://libvips.github.io/libvips/API/current/VipsForeignSave.html#vips-gifsave-buffer
|
||||
int set_gifsave_options(VipsOperation *operation, SaveParams *params) {
|
||||
int ret = 0;
|
||||
// See for argument values: https://www.libvips.org/API/current/VipsForeignSave.html#vips-gifsave
|
||||
if (params->gifDither > 0.0 && params->gifDither <= 10) {
|
||||
ret = vips_object_set(VIPS_OBJECT(operation), "dither", params->gifDither, NULL);
|
||||
}
|
||||
if (params->gifEffort >= 1 && params->gifEffort <= 10) {
|
||||
ret = vips_object_set(VIPS_OBJECT(operation), "effort", params->gifEffort, NULL);
|
||||
}
|
||||
if (params->gifBitdepth >= 1 && params->gifBitdepth <= 8) {
|
||||
ret = vips_object_set(VIPS_OBJECT(operation), "bitdepth", params->gifBitdepth, NULL);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// https://github.com/libvips/libvips/blob/master/libvips/foreign/heifsave.c#L653
|
||||
int set_heifsave_options(VipsOperation *operation, SaveParams *params) {
|
||||
int ret = vips_object_set(VIPS_OBJECT(operation), "lossless",
|
||||
params->heifLossless, NULL);
|
||||
|
||||
#if (VIPS_MAJOR_VERSION >= 8) && (VIPS_MINOR_VERSION >= 13)
|
||||
if (!ret && params->heifBitdepth && params->heifEffort) {
|
||||
ret = vips_object_set(VIPS_OBJECT(operation), "bitdepth",
|
||||
params->heifBitdepth, "effort", params->heifEffort,
|
||||
NULL);
|
||||
}
|
||||
#else
|
||||
if (!ret && params->heifEffort) {
|
||||
ret = vips_object_set(VIPS_OBJECT(operation), "speed", params->heifEffort,
|
||||
NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!ret && params->quality) {
|
||||
ret = vips_object_set(VIPS_OBJECT(operation), "Q", params->quality, NULL);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// https://github.com/libvips/libvips/blob/master/libvips/foreign/heifsave.c#L653
|
||||
int set_avifsave_options(VipsOperation *operation, SaveParams *params) {
|
||||
int ret = vips_object_set(VIPS_OBJECT(operation), "strip", params->stripMetadata, "compression",
|
||||
VIPS_FOREIGN_HEIF_COMPRESSION_AV1, "lossless",
|
||||
params->heifLossless, NULL);
|
||||
|
||||
#if (VIPS_MAJOR_VERSION >= 8) && (VIPS_MINOR_VERSION >= 13)
|
||||
if (!ret && params->heifBitdepth && params->heifEffort) {
|
||||
ret = vips_object_set(VIPS_OBJECT(operation), "bitdepth",
|
||||
params->heifBitdepth, "effort", params->heifEffort,
|
||||
NULL);
|
||||
}
|
||||
#else
|
||||
if (!ret && params->heifEffort) {
|
||||
ret = vips_object_set(VIPS_OBJECT(operation), "speed", params->heifEffort,
|
||||
NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!ret && params->quality) {
|
||||
ret = vips_object_set(VIPS_OBJECT(operation), "Q", params->quality, NULL);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int set_jp2ksave_options(VipsOperation *operation, SaveParams *params) {
|
||||
int ret = vips_object_set(
|
||||
VIPS_OBJECT(operation), "subsample_mode", params->jpegSubsample,
|
||||
"tile_height", params->jp2kTileHeight, "tile_width", params->jp2kTileWidth,
|
||||
"lossless", params->jp2kLossless, NULL);
|
||||
|
||||
if (!ret && params->quality) {
|
||||
ret = vips_object_set(VIPS_OBJECT(operation), "Q", params->quality, NULL);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int set_jxlsave_options(VipsOperation *operation, SaveParams *params) {
|
||||
int ret = vips_object_set(
|
||||
VIPS_OBJECT(operation), "tier", params->jxlTier,
|
||||
"distance", params->jxlDistance, "effort", params->jxlEffort,
|
||||
"lossless", params->jxlLossless, NULL);
|
||||
|
||||
if (!ret && params->quality) {
|
||||
ret = vips_object_set(VIPS_OBJECT(operation), "Q", params->quality, NULL);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int load_from_buffer(LoadParams *params, void *buf, size_t len) {
|
||||
switch (params->inputFormat) {
|
||||
case JPEG:
|
||||
return load_buffer("jpegload_buffer", buf, len, params,
|
||||
set_jpegload_options);
|
||||
case PNG:
|
||||
return load_buffer("pngload_buffer", buf, len, params,
|
||||
set_pngload_options);
|
||||
case WEBP:
|
||||
return load_buffer("webpload_buffer", buf, len, params,
|
||||
set_webpload_options);
|
||||
case HEIF:
|
||||
return load_buffer("heifload_buffer", buf, len, params,
|
||||
set_heifload_options);
|
||||
case TIFF:
|
||||
return load_buffer("tiffload_buffer", buf, len, params,
|
||||
set_tiffload_options);
|
||||
case SVG:
|
||||
return load_buffer("svgload_buffer", buf, len, params,
|
||||
set_svgload_options);
|
||||
case GIF:
|
||||
return load_buffer("gifload_buffer", buf, len, params,
|
||||
set_gifload_options);
|
||||
case PDF:
|
||||
return load_buffer("pdfload_buffer", buf, len, params,
|
||||
set_pdfload_options);
|
||||
case MAGICK:
|
||||
return load_buffer("magickload_buffer", buf, len, params,
|
||||
set_magickload_options);
|
||||
case AVIF:
|
||||
return load_buffer("heifload_buffer", buf, len, params,
|
||||
set_heifload_options);
|
||||
case JP2K:
|
||||
return load_buffer("jp2kload_buffer", buf, len, params,
|
||||
set_jp2kload_options);
|
||||
case JXL:
|
||||
return load_buffer("jxlload_buffer", buf, len, params,
|
||||
set_jxlload_options);
|
||||
default:
|
||||
g_warning("Unsupported input type given: %d", params->inputFormat);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int save_to_buffer(SaveParams *params) {
|
||||
switch (params->outputFormat) {
|
||||
case JPEG:
|
||||
return save_buffer("jpegsave_buffer", params, set_jpegsave_options);
|
||||
case PNG:
|
||||
return save_buffer("pngsave_buffer", params, set_pngsave_options);
|
||||
case WEBP:
|
||||
return save_buffer("webpsave_buffer", params, set_webpsave_options);
|
||||
case HEIF:
|
||||
return save_buffer("heifsave_buffer", params, set_heifsave_options);
|
||||
case TIFF:
|
||||
return save_buffer("tiffsave_buffer", params, set_tiffsave_options);
|
||||
case GIF:
|
||||
#if (VIPS_MAJOR_VERSION >= 8) && (VIPS_MINOR_VERSION >= 12)
|
||||
return save_buffer("gifsave_buffer", params, set_gifsave_options);
|
||||
#else
|
||||
return save_buffer("magicksave_buffer", params, set_magicksave_options);
|
||||
#endif
|
||||
case AVIF:
|
||||
return save_buffer("heifsave_buffer", params, set_avifsave_options);
|
||||
case JP2K:
|
||||
return save_buffer("jp2ksave_buffer", params, set_jp2ksave_options);
|
||||
case JXL:
|
||||
return save_buffer("jxlsave_buffer", params, set_jxlsave_options);
|
||||
default:
|
||||
g_warning("Unsupported output type given: %d", params->outputFormat);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
LoadParams create_load_params(ImageType inputFormat) {
|
||||
Param defaultParam = {};
|
||||
LoadParams p = {
|
||||
.inputFormat = inputFormat,
|
||||
.inputBlob = NULL,
|
||||
.outputImage = NULL,
|
||||
.autorotate = defaultParam,
|
||||
.fail = defaultParam,
|
||||
.page = defaultParam,
|
||||
.n = defaultParam,
|
||||
.dpi = defaultParam,
|
||||
.jpegShrink = defaultParam,
|
||||
.heifThumbnail = defaultParam,
|
||||
.svgUnlimited = defaultParam,
|
||||
};
|
||||
return p;
|
||||
}
|
||||
|
||||
// TODO: Change to same pattern as ImportParams
|
||||
|
||||
static SaveParams defaultSaveParams = {
|
||||
.inputImage = NULL,
|
||||
.outputBuffer = NULL,
|
||||
.outputFormat = JPEG,
|
||||
.outputLen = 0,
|
||||
|
||||
.interlace = FALSE,
|
||||
.quality = 0,
|
||||
.stripMetadata = FALSE,
|
||||
|
||||
.jpegOptimizeCoding = FALSE,
|
||||
.jpegSubsample = VIPS_FOREIGN_SUBSAMPLE_ON,
|
||||
.jpegTrellisQuant = FALSE,
|
||||
.jpegOvershootDeringing = FALSE,
|
||||
.jpegOptimizeScans = FALSE,
|
||||
.jpegQuantTable = 0,
|
||||
|
||||
.pngCompression = 6,
|
||||
.pngPalette = FALSE,
|
||||
.pngBitdepth = 0,
|
||||
.pngDither = 0,
|
||||
.pngFilter = VIPS_FOREIGN_PNG_FILTER_NONE,
|
||||
|
||||
.gifDither = 0.0,
|
||||
.gifEffort = 0,
|
||||
.gifBitdepth = 0,
|
||||
|
||||
.webpLossless = FALSE,
|
||||
.webpNearLossless = FALSE,
|
||||
.webpReductionEffort = 4,
|
||||
.webpIccProfile = NULL,
|
||||
.webpKMax = 0,
|
||||
.webpKMin = 0,
|
||||
.webpMinSize = FALSE,
|
||||
|
||||
.heifBitdepth = 8,
|
||||
.heifLossless = FALSE,
|
||||
.heifEffort = 5,
|
||||
|
||||
.tiffCompression = VIPS_FOREIGN_TIFF_COMPRESSION_LZW,
|
||||
.tiffPredictor = VIPS_FOREIGN_TIFF_PREDICTOR_HORIZONTAL,
|
||||
.tiffPyramid = FALSE,
|
||||
.tiffTile = FALSE,
|
||||
.tiffTileHeight = 256,
|
||||
.tiffTileWidth = 256,
|
||||
|
||||
.jp2kLossless = FALSE,
|
||||
.jp2kTileHeight = 512,
|
||||
.jp2kTileWidth = 512,
|
||||
|
||||
.jxlTier = 0,
|
||||
.jxlDistance = 1.0,
|
||||
.jxlEffort = 7,
|
||||
.jxlLossless = FALSE,
|
||||
};
|
||||
|
||||
SaveParams create_save_params(ImageType outputFormat) {
|
||||
SaveParams params = defaultSaveParams;
|
||||
params.outputFormat = outputFormat;
|
||||
return params;
|
||||
}
|
||||
512
vendor/github.com/davidbyttow/govips/v2/vips/foreign.go
generated
vendored
512
vendor/github.com/davidbyttow/govips/v2/vips/foreign.go
generated
vendored
@@ -1,512 +0,0 @@
|
||||
package vips
|
||||
|
||||
// #include "foreign.h"
|
||||
import "C"
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"golang.org/x/image/bmp"
|
||||
"golang.org/x/net/html/charset"
|
||||
"image/png"
|
||||
"math"
|
||||
"runtime"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// SubsampleMode correlates to a libvips subsample mode
|
||||
type SubsampleMode int
|
||||
|
||||
// SubsampleMode enum correlating to libvips subsample modes
|
||||
const (
|
||||
VipsForeignSubsampleAuto SubsampleMode = C.VIPS_FOREIGN_SUBSAMPLE_AUTO
|
||||
VipsForeignSubsampleOn SubsampleMode = C.VIPS_FOREIGN_SUBSAMPLE_ON
|
||||
VipsForeignSubsampleOff SubsampleMode = C.VIPS_FOREIGN_SUBSAMPLE_OFF
|
||||
VipsForeignSubsampleLast SubsampleMode = C.VIPS_FOREIGN_SUBSAMPLE_LAST
|
||||
)
|
||||
|
||||
// ImageType represents an image type
|
||||
type ImageType int
|
||||
|
||||
// ImageType enum
|
||||
const (
|
||||
ImageTypeUnknown ImageType = C.UNKNOWN
|
||||
ImageTypeGIF ImageType = C.GIF
|
||||
ImageTypeJPEG ImageType = C.JPEG
|
||||
ImageTypeMagick ImageType = C.MAGICK
|
||||
ImageTypePDF ImageType = C.PDF
|
||||
ImageTypePNG ImageType = C.PNG
|
||||
ImageTypeSVG ImageType = C.SVG
|
||||
ImageTypeTIFF ImageType = C.TIFF
|
||||
ImageTypeWEBP ImageType = C.WEBP
|
||||
ImageTypeHEIF ImageType = C.HEIF
|
||||
ImageTypeBMP ImageType = C.BMP
|
||||
ImageTypeAVIF ImageType = C.AVIF
|
||||
ImageTypeJP2K ImageType = C.JP2K
|
||||
ImageTypeJXL ImageType = C.JXL
|
||||
)
|
||||
|
||||
var imageTypeExtensionMap = map[ImageType]string{
|
||||
ImageTypeGIF: ".gif",
|
||||
ImageTypeJPEG: ".jpeg",
|
||||
ImageTypeMagick: ".magick",
|
||||
ImageTypePDF: ".pdf",
|
||||
ImageTypePNG: ".png",
|
||||
ImageTypeSVG: ".svg",
|
||||
ImageTypeTIFF: ".tiff",
|
||||
ImageTypeWEBP: ".webp",
|
||||
ImageTypeHEIF: ".heic",
|
||||
ImageTypeBMP: ".bmp",
|
||||
ImageTypeAVIF: ".avif",
|
||||
ImageTypeJP2K: ".jp2",
|
||||
ImageTypeJXL: ".jxl",
|
||||
}
|
||||
|
||||
// ImageTypes defines the various image types supported by govips
|
||||
var ImageTypes = map[ImageType]string{
|
||||
ImageTypeGIF: "gif",
|
||||
ImageTypeJPEG: "jpeg",
|
||||
ImageTypeMagick: "magick",
|
||||
ImageTypePDF: "pdf",
|
||||
ImageTypePNG: "png",
|
||||
ImageTypeSVG: "svg",
|
||||
ImageTypeTIFF: "tiff",
|
||||
ImageTypeWEBP: "webp",
|
||||
ImageTypeHEIF: "heif",
|
||||
ImageTypeBMP: "bmp",
|
||||
ImageTypeAVIF: "heif",
|
||||
ImageTypeJP2K: "jp2k",
|
||||
ImageTypeJXL: "jxl",
|
||||
}
|
||||
|
||||
// TiffCompression represents method for compressing a tiff at export
|
||||
type TiffCompression int
|
||||
|
||||
// TiffCompression enum
|
||||
const (
|
||||
TiffCompressionNone TiffCompression = C.VIPS_FOREIGN_TIFF_COMPRESSION_NONE
|
||||
TiffCompressionJpeg TiffCompression = C.VIPS_FOREIGN_TIFF_COMPRESSION_JPEG
|
||||
TiffCompressionDeflate TiffCompression = C.VIPS_FOREIGN_TIFF_COMPRESSION_DEFLATE
|
||||
TiffCompressionPackbits TiffCompression = C.VIPS_FOREIGN_TIFF_COMPRESSION_PACKBITS
|
||||
TiffCompressionFax4 TiffCompression = C.VIPS_FOREIGN_TIFF_COMPRESSION_CCITTFAX4
|
||||
TiffCompressionLzw TiffCompression = C.VIPS_FOREIGN_TIFF_COMPRESSION_LZW
|
||||
TiffCompressionWebp TiffCompression = C.VIPS_FOREIGN_TIFF_COMPRESSION_WEBP
|
||||
TiffCompressionZstd TiffCompression = C.VIPS_FOREIGN_TIFF_COMPRESSION_ZSTD
|
||||
)
|
||||
|
||||
// TiffPredictor represents method for compressing a tiff at export
|
||||
type TiffPredictor int
|
||||
|
||||
// TiffPredictor enum
|
||||
const (
|
||||
TiffPredictorNone TiffPredictor = C.VIPS_FOREIGN_TIFF_PREDICTOR_NONE
|
||||
TiffPredictorHorizontal TiffPredictor = C.VIPS_FOREIGN_TIFF_PREDICTOR_HORIZONTAL
|
||||
TiffPredictorFloat TiffPredictor = C.VIPS_FOREIGN_TIFF_PREDICTOR_FLOAT
|
||||
)
|
||||
|
||||
// PngFilter represents filter algorithms that can be applied before compression.
|
||||
// See https://www.w3.org/TR/PNG-Filters.html
|
||||
type PngFilter int
|
||||
|
||||
// PngFilter enum
|
||||
const (
|
||||
PngFilterNone PngFilter = C.VIPS_FOREIGN_PNG_FILTER_NONE
|
||||
PngFilterSub PngFilter = C.VIPS_FOREIGN_PNG_FILTER_SUB
|
||||
PngFilterUo PngFilter = C.VIPS_FOREIGN_PNG_FILTER_UP
|
||||
PngFilterAvg PngFilter = C.VIPS_FOREIGN_PNG_FILTER_AVG
|
||||
PngFilterPaeth PngFilter = C.VIPS_FOREIGN_PNG_FILTER_PAETH
|
||||
PngFilterAll PngFilter = C.VIPS_FOREIGN_PNG_FILTER_ALL
|
||||
)
|
||||
|
||||
// FileExt returns the canonical extension for the ImageType
|
||||
func (i ImageType) FileExt() string {
|
||||
if ext, ok := imageTypeExtensionMap[i]; ok {
|
||||
return ext
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// IsTypeSupported checks whether given image type is supported by govips
|
||||
func IsTypeSupported(imageType ImageType) bool {
|
||||
startupIfNeeded()
|
||||
|
||||
return supportedImageTypes[imageType]
|
||||
}
|
||||
|
||||
// DetermineImageType attempts to determine the image type of the given buffer
|
||||
func DetermineImageType(buf []byte) ImageType {
|
||||
if len(buf) < 12 {
|
||||
return ImageTypeUnknown
|
||||
} else if isJPEG(buf) {
|
||||
return ImageTypeJPEG
|
||||
} else if isPNG(buf) {
|
||||
return ImageTypePNG
|
||||
} else if isGIF(buf) {
|
||||
return ImageTypeGIF
|
||||
} else if isTIFF(buf) {
|
||||
return ImageTypeTIFF
|
||||
} else if isWEBP(buf) {
|
||||
return ImageTypeWEBP
|
||||
} else if isAVIF(buf) {
|
||||
return ImageTypeAVIF
|
||||
} else if isHEIF(buf) {
|
||||
return ImageTypeHEIF
|
||||
} else if isSVG(buf) {
|
||||
return ImageTypeSVG
|
||||
} else if isBMP(buf) {
|
||||
return ImageTypeBMP
|
||||
} else if isJP2K(buf) {
|
||||
return ImageTypeJP2K
|
||||
} else if isJXL(buf) {
|
||||
return ImageTypeJXL
|
||||
} else if isPDF(buf) {
|
||||
return ImageTypePDF
|
||||
} else {
|
||||
return ImageTypeUnknown
|
||||
}
|
||||
}
|
||||
|
||||
var jpeg = []byte("\xFF\xD8\xFF")
|
||||
|
||||
func isJPEG(buf []byte) bool {
|
||||
return bytes.HasPrefix(buf, jpeg)
|
||||
}
|
||||
|
||||
var gifHeader = []byte("\x47\x49\x46")
|
||||
|
||||
func isGIF(buf []byte) bool {
|
||||
return bytes.HasPrefix(buf, gifHeader)
|
||||
}
|
||||
|
||||
var pngHeader = []byte("\x89\x50\x4E\x47")
|
||||
|
||||
func isPNG(buf []byte) bool {
|
||||
return bytes.HasPrefix(buf, pngHeader)
|
||||
}
|
||||
|
||||
var tifII = []byte("\x49\x49\x2A\x00")
|
||||
var tifMM = []byte("\x4D\x4D\x00\x2A")
|
||||
|
||||
func isTIFF(buf []byte) bool {
|
||||
return bytes.HasPrefix(buf, tifII) || bytes.HasPrefix(buf, tifMM)
|
||||
}
|
||||
|
||||
var webpHeader = []byte("\x57\x45\x42\x50")
|
||||
|
||||
func isWEBP(buf []byte) bool {
|
||||
return bytes.Equal(buf[8:12], webpHeader)
|
||||
}
|
||||
|
||||
// https://github.com/strukturag/libheif/blob/master/libheif/heif.cc
|
||||
var ftyp = []byte("ftyp")
|
||||
var heic = []byte("heic")
|
||||
var mif1 = []byte("mif1")
|
||||
var msf1 = []byte("msf1")
|
||||
var avif = []byte("avif")
|
||||
|
||||
func isHEIF(buf []byte) bool {
|
||||
return bytes.Equal(buf[4:8], ftyp) && (bytes.Equal(buf[8:12], heic) ||
|
||||
bytes.Equal(buf[8:12], mif1) ||
|
||||
bytes.Equal(buf[8:12], msf1)) ||
|
||||
isAVIF(buf)
|
||||
}
|
||||
|
||||
func isAVIF(buf []byte) bool {
|
||||
return bytes.Equal(buf[4:8], ftyp) && bytes.Equal(buf[8:12], avif)
|
||||
}
|
||||
|
||||
var svg = []byte("<svg")
|
||||
|
||||
func isSVG(buf []byte) bool {
|
||||
sub := buf[:int(math.Min(1024.0, float64(len(buf))))]
|
||||
if bytes.Contains(sub, svg) {
|
||||
data := &struct {
|
||||
XMLName xml.Name `xml:"svg"`
|
||||
}{}
|
||||
reader := bytes.NewReader(buf)
|
||||
decoder := xml.NewDecoder(reader)
|
||||
decoder.Strict = false
|
||||
decoder.CharsetReader = charset.NewReaderLabel
|
||||
|
||||
err := decoder.Decode(data)
|
||||
|
||||
return err == nil && data.XMLName.Local == "svg"
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
var pdf = []byte("\x25\x50\x44\x46")
|
||||
|
||||
func isPDF(buf []byte) bool {
|
||||
if len(buf) <= 1024 {
|
||||
return bytes.Contains(buf, pdf)
|
||||
}
|
||||
return bytes.Contains(buf[:1024], pdf)
|
||||
}
|
||||
|
||||
var bmpHeader = []byte("BM")
|
||||
|
||||
func isBMP(buf []byte) bool {
|
||||
return bytes.HasPrefix(buf, bmpHeader)
|
||||
}
|
||||
|
||||
// X'0000 000C 6A50 2020 0D0A 870A'
|
||||
var jp2kHeader = []byte("\x00\x00\x00\x0C\x6A\x50\x20\x20\x0D\x0A\x87\x0A")
|
||||
|
||||
// https://datatracker.ietf.org/doc/html/rfc3745
|
||||
func isJP2K(buf []byte) bool {
|
||||
return bytes.HasPrefix(buf, jp2kHeader)
|
||||
}
|
||||
|
||||
// As a 'naked' codestream
|
||||
var jxlHeader = []byte("\xff\x0a")
|
||||
|
||||
// As an ISOBMFF-based container: 0x0000000C 4A584C20 0D0A870A
|
||||
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)
|
||||
}
|
||||
|
||||
func vipsLoadFromBuffer(buf []byte, params *ImportParams) (*C.VipsImage, ImageType, ImageType, error) {
|
||||
src := buf
|
||||
// Reference src here so it's not garbage collected during image initialization.
|
||||
defer runtime.KeepAlive(src)
|
||||
|
||||
var err error
|
||||
|
||||
originalType := DetermineImageType(src)
|
||||
currentType := originalType
|
||||
|
||||
if originalType == ImageTypeBMP {
|
||||
src, err = bmpToPNG(src)
|
||||
if err != nil {
|
||||
return nil, currentType, originalType, err
|
||||
}
|
||||
|
||||
currentType = ImageTypePNG
|
||||
}
|
||||
|
||||
if !IsTypeSupported(currentType) {
|
||||
govipsLog("govips", LogLevelInfo, fmt.Sprintf("failed to understand image format size=%d", len(src)))
|
||||
return nil, currentType, originalType, ErrUnsupportedImageFormat
|
||||
}
|
||||
|
||||
importParams := createImportParams(currentType, params)
|
||||
|
||||
if err := C.load_from_buffer(&importParams, unsafe.Pointer(&src[0]), C.size_t(len(src))); err != 0 {
|
||||
return nil, currentType, originalType, handleImageError(importParams.outputImage)
|
||||
}
|
||||
|
||||
return importParams.outputImage, currentType, originalType, nil
|
||||
}
|
||||
|
||||
func bmpToPNG(src []byte) ([]byte, error) {
|
||||
i, err := bmp.Decode(bytes.NewReader(src))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var w bytes.Buffer
|
||||
pngEnc := png.Encoder{
|
||||
CompressionLevel: png.NoCompression,
|
||||
}
|
||||
err = pngEnc.Encode(&w, i)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return w.Bytes(), nil
|
||||
}
|
||||
|
||||
func maybeSetBoolParam(p BoolParameter, cp *C.Param) {
|
||||
if p.IsSet() {
|
||||
C.set_bool_param(cp, toGboolean(p.Get()))
|
||||
}
|
||||
}
|
||||
|
||||
func maybeSetIntParam(p IntParameter, cp *C.Param) {
|
||||
if p.IsSet() {
|
||||
C.set_int_param(cp, C.int(p.Get()))
|
||||
}
|
||||
}
|
||||
|
||||
func createImportParams(format ImageType, params *ImportParams) C.LoadParams {
|
||||
p := C.create_load_params(C.ImageType(format))
|
||||
|
||||
maybeSetBoolParam(params.AutoRotate, &p.autorotate)
|
||||
maybeSetBoolParam(params.FailOnError, &p.fail)
|
||||
maybeSetIntParam(params.Page, &p.page)
|
||||
maybeSetIntParam(params.NumPages, &p.n)
|
||||
maybeSetIntParam(params.JpegShrinkFactor, &p.jpegShrink)
|
||||
maybeSetBoolParam(params.HeifThumbnail, &p.heifThumbnail)
|
||||
maybeSetBoolParam(params.SvgUnlimited, &p.svgUnlimited)
|
||||
|
||||
if params.Density.IsSet() {
|
||||
C.set_double_param(&p.dpi, C.gdouble(params.Density.Get()))
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
func vipsSaveJPEGToBuffer(in *C.VipsImage, params JpegExportParams) ([]byte, error) {
|
||||
incOpCounter("save_jpeg_buffer")
|
||||
|
||||
p := C.create_save_params(C.JPEG)
|
||||
p.inputImage = in
|
||||
p.stripMetadata = C.int(boolToInt(params.StripMetadata))
|
||||
p.quality = C.int(params.Quality)
|
||||
p.interlace = C.int(boolToInt(params.Interlace))
|
||||
p.jpegOptimizeCoding = C.int(boolToInt(params.OptimizeCoding))
|
||||
p.jpegSubsample = C.VipsForeignSubsample(params.SubsampleMode)
|
||||
p.jpegTrellisQuant = C.int(boolToInt(params.TrellisQuant))
|
||||
p.jpegOvershootDeringing = C.int(boolToInt(params.OvershootDeringing))
|
||||
p.jpegOptimizeScans = C.int(boolToInt(params.OptimizeScans))
|
||||
p.jpegQuantTable = C.int(params.QuantTable)
|
||||
|
||||
return vipsSaveToBuffer(p)
|
||||
}
|
||||
|
||||
func vipsSavePNGToBuffer(in *C.VipsImage, params PngExportParams) ([]byte, error) {
|
||||
incOpCounter("save_png_buffer")
|
||||
|
||||
p := C.create_save_params(C.PNG)
|
||||
p.inputImage = in
|
||||
p.quality = C.int(params.Quality)
|
||||
p.stripMetadata = C.int(boolToInt(params.StripMetadata))
|
||||
p.interlace = C.int(boolToInt(params.Interlace))
|
||||
p.pngCompression = C.int(params.Compression)
|
||||
p.pngFilter = C.VipsForeignPngFilter(params.Filter)
|
||||
p.pngPalette = C.int(boolToInt(params.Palette))
|
||||
p.pngDither = C.double(params.Dither)
|
||||
p.pngBitdepth = C.int(params.Bitdepth)
|
||||
|
||||
return vipsSaveToBuffer(p)
|
||||
}
|
||||
|
||||
func vipsSaveWebPToBuffer(in *C.VipsImage, params WebpExportParams) ([]byte, error) {
|
||||
incOpCounter("save_webp_buffer")
|
||||
|
||||
p := C.create_save_params(C.WEBP)
|
||||
p.inputImage = in
|
||||
p.stripMetadata = C.int(boolToInt(params.StripMetadata))
|
||||
p.quality = C.int(params.Quality)
|
||||
p.webpLossless = C.int(boolToInt(params.Lossless))
|
||||
p.webpNearLossless = C.int(boolToInt(params.NearLossless))
|
||||
p.webpReductionEffort = C.int(params.ReductionEffort)
|
||||
p.webpMinSize = C.int(boolToInt(params.MinSize))
|
||||
p.webpKMin = C.int(params.MinKeyFrames)
|
||||
p.webpKMax = C.int(params.MaxKeyFrames)
|
||||
|
||||
if params.IccProfile != "" {
|
||||
p.webpIccProfile = C.CString(params.IccProfile)
|
||||
defer C.free(unsafe.Pointer(p.webpIccProfile))
|
||||
}
|
||||
|
||||
return vipsSaveToBuffer(p)
|
||||
}
|
||||
|
||||
func vipsSaveTIFFToBuffer(in *C.VipsImage, params TiffExportParams) ([]byte, error) {
|
||||
incOpCounter("save_tiff_buffer")
|
||||
|
||||
p := C.create_save_params(C.TIFF)
|
||||
p.inputImage = in
|
||||
p.stripMetadata = C.int(boolToInt(params.StripMetadata))
|
||||
p.quality = C.int(params.Quality)
|
||||
p.tiffCompression = C.VipsForeignTiffCompression(params.Compression)
|
||||
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)
|
||||
|
||||
return vipsSaveToBuffer(p)
|
||||
}
|
||||
|
||||
func vipsSaveHEIFToBuffer(in *C.VipsImage, params HeifExportParams) ([]byte, error) {
|
||||
incOpCounter("save_heif_buffer")
|
||||
|
||||
p := C.create_save_params(C.HEIF)
|
||||
p.inputImage = in
|
||||
p.outputFormat = C.HEIF
|
||||
p.quality = C.int(params.Quality)
|
||||
p.heifLossless = C.int(boolToInt(params.Lossless))
|
||||
p.heifBitdepth = C.int(params.Bitdepth)
|
||||
p.heifEffort = C.int(params.Effort)
|
||||
|
||||
return vipsSaveToBuffer(p)
|
||||
}
|
||||
|
||||
func vipsSaveAVIFToBuffer(in *C.VipsImage, params AvifExportParams) ([]byte, error) {
|
||||
incOpCounter("save_heif_buffer")
|
||||
|
||||
// Speed was deprecated but we want to avoid breaking code that still uses it:
|
||||
effort := params.Effort
|
||||
if params.Speed != 0 {
|
||||
effort = params.Speed
|
||||
}
|
||||
|
||||
p := C.create_save_params(C.AVIF)
|
||||
p.inputImage = in
|
||||
p.stripMetadata = C.int(boolToInt(params.StripMetadata))
|
||||
p.outputFormat = C.AVIF
|
||||
p.quality = C.int(params.Quality)
|
||||
p.heifLossless = C.int(boolToInt(params.Lossless))
|
||||
p.heifBitdepth = C.int(params.Bitdepth)
|
||||
p.heifEffort = C.int(effort)
|
||||
|
||||
return vipsSaveToBuffer(p)
|
||||
}
|
||||
|
||||
func vipsSaveJP2KToBuffer(in *C.VipsImage, params Jp2kExportParams) ([]byte, error) {
|
||||
incOpCounter("save_jp2k_buffer")
|
||||
|
||||
p := C.create_save_params(C.JP2K)
|
||||
p.inputImage = in
|
||||
p.outputFormat = C.JP2K
|
||||
p.quality = C.int(params.Quality)
|
||||
p.jp2kLossless = C.int(boolToInt(params.Lossless))
|
||||
p.jp2kTileWidth = C.int(params.TileWidth)
|
||||
p.jp2kTileHeight = C.int(params.TileHeight)
|
||||
p.jpegSubsample = C.VipsForeignSubsample(params.SubsampleMode)
|
||||
|
||||
return vipsSaveToBuffer(p)
|
||||
}
|
||||
|
||||
func vipsSaveGIFToBuffer(in *C.VipsImage, params GifExportParams) ([]byte, error) {
|
||||
incOpCounter("save_gif_buffer")
|
||||
|
||||
p := C.create_save_params(C.GIF)
|
||||
p.inputImage = in
|
||||
p.quality = C.int(params.Quality)
|
||||
p.gifDither = C.double(params.Dither)
|
||||
p.gifEffort = C.int(params.Effort)
|
||||
p.gifBitdepth = C.int(params.Bitdepth)
|
||||
|
||||
return vipsSaveToBuffer(p)
|
||||
}
|
||||
|
||||
func vipsSaveJxlToBuffer(in *C.VipsImage, params JxlExportParams) ([]byte, error) {
|
||||
incOpCounter("save_jxl_buffer")
|
||||
|
||||
p := C.create_save_params(C.JXL)
|
||||
p.inputImage = in
|
||||
p.outputFormat = C.JXL
|
||||
p.quality = C.int(params.Quality)
|
||||
p.jxlLossless = C.int(boolToInt(params.Lossless))
|
||||
p.jxlTier = C.int(params.Tier)
|
||||
p.jxlDistance = C.double(params.Distance)
|
||||
p.jxlEffort = C.int(params.Effort)
|
||||
|
||||
return vipsSaveToBuffer(p)
|
||||
}
|
||||
|
||||
func vipsSaveToBuffer(params C.struct_SaveParams) ([]byte, error) {
|
||||
if err := C.save_to_buffer(¶ms); err != 0 {
|
||||
return nil, handleSaveBufferError(params.outputBuffer)
|
||||
}
|
||||
|
||||
buf := C.GoBytes(params.outputBuffer, C.int(params.outputLen))
|
||||
defer gFreePointer(params.outputBuffer)
|
||||
|
||||
return buf, nil
|
||||
}
|
||||
141
vendor/github.com/davidbyttow/govips/v2/vips/foreign.h
generated
vendored
141
vendor/github.com/davidbyttow/govips/v2/vips/foreign.h
generated
vendored
@@ -1,141 +0,0 @@
|
||||
// https://libvips.github.io/libvips/API/current/VipsForeignSave.html
|
||||
|
||||
// clang-format off
|
||||
// include order matters
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <vips/vips.h>
|
||||
#include <vips/foreign.h>
|
||||
// clang-format n
|
||||
|
||||
#ifndef BOOL
|
||||
#define BOOL int
|
||||
#endif
|
||||
|
||||
typedef enum types {
|
||||
UNKNOWN = 0,
|
||||
JPEG,
|
||||
WEBP,
|
||||
PNG,
|
||||
TIFF,
|
||||
GIF,
|
||||
PDF,
|
||||
SVG,
|
||||
MAGICK,
|
||||
HEIF,
|
||||
BMP,
|
||||
AVIF,
|
||||
JP2K,
|
||||
JXL
|
||||
} ImageType;
|
||||
|
||||
typedef enum ParamType {
|
||||
PARAM_TYPE_NULL,
|
||||
PARAM_TYPE_BOOL,
|
||||
PARAM_TYPE_INT,
|
||||
PARAM_TYPE_DOUBLE,
|
||||
} ParamType;
|
||||
|
||||
typedef struct Param {
|
||||
ParamType type;
|
||||
|
||||
union Value {
|
||||
gboolean b;
|
||||
gint i;
|
||||
gdouble d;
|
||||
} value;
|
||||
|
||||
gboolean is_set;
|
||||
|
||||
} Param;
|
||||
|
||||
void set_bool_param(Param *p, gboolean b);
|
||||
void set_int_param(Param *p, gint i);
|
||||
void set_double_param(Param *p, gdouble d);
|
||||
|
||||
typedef struct LoadParams {
|
||||
ImageType inputFormat;
|
||||
VipsBlob *inputBlob;
|
||||
VipsImage *outputImage;
|
||||
|
||||
Param autorotate;
|
||||
Param fail;
|
||||
Param page;
|
||||
Param n;
|
||||
Param dpi;
|
||||
Param jpegShrink;
|
||||
Param heifThumbnail;
|
||||
Param svgUnlimited;
|
||||
|
||||
} LoadParams;
|
||||
|
||||
LoadParams create_load_params(ImageType inputFormat);
|
||||
int load_from_buffer(LoadParams *params, void *buf, size_t len);
|
||||
|
||||
typedef struct SaveParams {
|
||||
VipsImage *inputImage;
|
||||
void *outputBuffer;
|
||||
ImageType outputFormat;
|
||||
size_t outputLen;
|
||||
|
||||
BOOL stripMetadata;
|
||||
int quality;
|
||||
BOOL interlace;
|
||||
|
||||
// JPEG
|
||||
BOOL jpegOptimizeCoding;
|
||||
VipsForeignSubsample jpegSubsample;
|
||||
BOOL jpegTrellisQuant;
|
||||
BOOL jpegOvershootDeringing;
|
||||
BOOL jpegOptimizeScans;
|
||||
int jpegQuantTable;
|
||||
|
||||
// PNG
|
||||
int pngCompression;
|
||||
VipsForeignPngFilter pngFilter;
|
||||
BOOL pngPalette;
|
||||
double pngDither;
|
||||
int pngBitdepth;
|
||||
|
||||
// GIF (with CGIF)
|
||||
double gifDither;
|
||||
int gifEffort;
|
||||
int gifBitdepth;
|
||||
|
||||
// WEBP
|
||||
BOOL webpLossless;
|
||||
BOOL webpNearLossless;
|
||||
int webpReductionEffort;
|
||||
char *webpIccProfile;
|
||||
BOOL webpMinSize;
|
||||
int webpKMin;
|
||||
int webpKMax;
|
||||
|
||||
// HEIF - https://github.com/libvips/libvips/blob/master/libvips/foreign/heifsave.c#L71
|
||||
int heifBitdepth; // Bitdepth to save at for >8 bit images
|
||||
BOOL heifLossless; // Lossless compression
|
||||
int heifEffort; // CPU effort (0 - 9)
|
||||
|
||||
// TIFF
|
||||
VipsForeignTiffCompression tiffCompression;
|
||||
VipsForeignTiffPredictor tiffPredictor;
|
||||
BOOL tiffPyramid;
|
||||
BOOL tiffTile;
|
||||
int tiffTileHeight;
|
||||
int tiffTileWidth;
|
||||
|
||||
// JPEG2000
|
||||
BOOL jp2kLossless;
|
||||
int jp2kTileWidth;
|
||||
int jp2kTileHeight;
|
||||
|
||||
// JXL
|
||||
int jxlTier;
|
||||
double jxlDistance;
|
||||
int jxlEffort;
|
||||
BOOL jxlLossless;
|
||||
} SaveParams;
|
||||
|
||||
SaveParams create_save_params(ImageType outputFormat);
|
||||
int save_to_buffer(SaveParams *params);
|
||||
|
||||
27
vendor/github.com/davidbyttow/govips/v2/vips/govips.c
generated
vendored
27
vendor/github.com/davidbyttow/govips/v2/vips/govips.c
generated
vendored
@@ -1,27 +0,0 @@
|
||||
#include "govips.h"
|
||||
|
||||
static void govips_logging_handler(const gchar *log_domain,
|
||||
GLogLevelFlags log_level,
|
||||
const gchar *message, gpointer user_data) {
|
||||
govipsLoggingHandler((char *)log_domain, (int)log_level, (char *)message);
|
||||
}
|
||||
|
||||
static void null_logging_handler(const gchar *log_domain,
|
||||
GLogLevelFlags log_level, const gchar *message,
|
||||
gpointer user_data) {}
|
||||
|
||||
void vips_set_logging_handler(void) {
|
||||
g_log_set_default_handler(govips_logging_handler, NULL);
|
||||
}
|
||||
|
||||
void vips_unset_logging_handler(void) {
|
||||
g_log_set_default_handler(null_logging_handler, NULL);
|
||||
}
|
||||
|
||||
/* This function skips the Govips logging handler and logs
|
||||
directly to stdout. To be used only for testing and debugging.
|
||||
Needed for CI because of a Go macOS bug which doesn't clean cgo callbacks on
|
||||
exit. */
|
||||
void vips_default_logging_handler(void) {
|
||||
g_log_set_default_handler(g_log_default_handler, NULL);
|
||||
}
|
||||
265
vendor/github.com/davidbyttow/govips/v2/vips/govips.go
generated
vendored
265
vendor/github.com/davidbyttow/govips/v2/vips/govips.go
generated
vendored
@@ -1,265 +0,0 @@
|
||||
// Package vips provides go bindings for libvips, a fast image processing library.
|
||||
package vips
|
||||
|
||||
// #cgo pkg-config: vips
|
||||
// #include <vips/vips.h>
|
||||
// #include "govips.h"
|
||||
import "C"
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultConcurrencyLevel = 1
|
||||
defaultMaxCacheMem = 50 * 1024 * 1024
|
||||
defaultMaxCacheSize = 100
|
||||
defaultMaxCacheFiles = 0
|
||||
)
|
||||
|
||||
var (
|
||||
// Version is the full libvips version string (x.y.z)
|
||||
Version = C.GoString(C.vips_version_string())
|
||||
|
||||
// MajorVersion is the libvips major component of the version string (x in x.y.z)
|
||||
MajorVersion = int(C.vips_version(0))
|
||||
|
||||
// MinorVersion is the libvips minor component of the version string (y in x.y.z)
|
||||
MinorVersion = int(C.vips_version(1))
|
||||
|
||||
// MicroVersion is the libvips micro component of the version string (z in x.y.z)
|
||||
// Also known as patch version
|
||||
MicroVersion = int(C.vips_version(2))
|
||||
|
||||
running = false
|
||||
hasShutdown = false
|
||||
initLock sync.Mutex
|
||||
statCollectorDone chan struct{}
|
||||
once sync.Once
|
||||
typeLoaders = make(map[string]ImageType)
|
||||
supportedImageTypes = make(map[ImageType]bool)
|
||||
)
|
||||
|
||||
// Config allows fine-tuning of libvips library
|
||||
type Config struct {
|
||||
ConcurrencyLevel int
|
||||
MaxCacheFiles int
|
||||
MaxCacheMem int
|
||||
MaxCacheSize int
|
||||
ReportLeaks bool
|
||||
CacheTrace bool
|
||||
CollectStats bool
|
||||
}
|
||||
|
||||
// Startup sets up the libvips support and ensures the versions are correct. Pass in nil for
|
||||
// default configuration.
|
||||
func Startup(config *Config) {
|
||||
if hasShutdown {
|
||||
panic("govips cannot be stopped and restarted")
|
||||
}
|
||||
|
||||
initLock.Lock()
|
||||
defer initLock.Unlock()
|
||||
|
||||
runtime.LockOSThread()
|
||||
defer runtime.UnlockOSThread()
|
||||
|
||||
if running {
|
||||
govipsLog("govips", LogLevelInfo, "warning libvips already started")
|
||||
return
|
||||
}
|
||||
|
||||
if MajorVersion < 8 {
|
||||
panic("govips requires libvips version 8.10+")
|
||||
}
|
||||
|
||||
if MajorVersion == 8 && MinorVersion < 10 {
|
||||
panic("govips requires libvips version 8.10+")
|
||||
}
|
||||
|
||||
cName := C.CString("govips")
|
||||
defer freeCString(cName)
|
||||
|
||||
// Initialize govips logging handler and verbosity filter to historical default
|
||||
if !currentLoggingOverridden {
|
||||
govipsLoggingSettings(nil, LogLevelInfo)
|
||||
}
|
||||
|
||||
// Override default glib logging handler to intercept logging messages
|
||||
enableLogging()
|
||||
|
||||
err := C.vips_init(cName)
|
||||
if err != 0 {
|
||||
panic(fmt.Sprintf("Failed to start vips code=%v", err))
|
||||
}
|
||||
|
||||
running = true
|
||||
|
||||
if config != nil {
|
||||
if config.CollectStats {
|
||||
statCollectorDone = collectStats()
|
||||
}
|
||||
|
||||
C.vips_leak_set(toGboolean(config.ReportLeaks))
|
||||
|
||||
if config.ConcurrencyLevel >= 0 {
|
||||
C.vips_concurrency_set(C.int(config.ConcurrencyLevel))
|
||||
} else {
|
||||
C.vips_concurrency_set(defaultConcurrencyLevel)
|
||||
}
|
||||
|
||||
if config.MaxCacheFiles >= 0 {
|
||||
C.vips_cache_set_max_files(C.int(config.MaxCacheFiles))
|
||||
} else {
|
||||
C.vips_cache_set_max_files(defaultMaxCacheFiles)
|
||||
}
|
||||
|
||||
if config.MaxCacheMem >= 0 {
|
||||
C.vips_cache_set_max_mem(C.size_t(config.MaxCacheMem))
|
||||
} else {
|
||||
C.vips_cache_set_max_mem(defaultMaxCacheMem)
|
||||
}
|
||||
|
||||
if config.MaxCacheSize >= 0 {
|
||||
C.vips_cache_set_max(C.int(config.MaxCacheSize))
|
||||
} else {
|
||||
C.vips_cache_set_max(defaultMaxCacheSize)
|
||||
}
|
||||
|
||||
if config.CacheTrace {
|
||||
C.vips_cache_set_trace(toGboolean(true))
|
||||
}
|
||||
} else {
|
||||
C.vips_concurrency_set(defaultConcurrencyLevel)
|
||||
C.vips_cache_set_max(defaultMaxCacheSize)
|
||||
C.vips_cache_set_max_mem(defaultMaxCacheMem)
|
||||
C.vips_cache_set_max_files(defaultMaxCacheFiles)
|
||||
}
|
||||
|
||||
govipsLog("govips", LogLevelInfo, fmt.Sprintf("vips %s started with concurrency=%d cache_max_files=%d cache_max_mem=%d cache_max=%d",
|
||||
Version,
|
||||
int(C.vips_concurrency_get()),
|
||||
int(C.vips_cache_get_max_files()),
|
||||
int(C.vips_cache_get_max_mem()),
|
||||
int(C.vips_cache_get_max())))
|
||||
|
||||
initTypes()
|
||||
}
|
||||
|
||||
func enableLogging() {
|
||||
C.vips_set_logging_handler()
|
||||
}
|
||||
|
||||
func disableLogging() {
|
||||
C.vips_unset_logging_handler()
|
||||
}
|
||||
|
||||
// consoleLogging overrides the Govips logging handler and makes glib
|
||||
// use its default logging handler which outputs everything to console.
|
||||
// Needed for CI unit testing due to a macOS bug in Go (doesn't clean cgo callbacks on exit)
|
||||
func consoleLogging() {
|
||||
C.vips_default_logging_handler()
|
||||
}
|
||||
|
||||
// Shutdown libvips
|
||||
func Shutdown() {
|
||||
hasShutdown = true
|
||||
|
||||
if statCollectorDone != nil {
|
||||
statCollectorDone <- struct{}{}
|
||||
}
|
||||
|
||||
initLock.Lock()
|
||||
defer initLock.Unlock()
|
||||
|
||||
runtime.LockOSThread()
|
||||
defer runtime.UnlockOSThread()
|
||||
|
||||
if !running {
|
||||
govipsLog("govips", LogLevelInfo, "warning libvips not started")
|
||||
return
|
||||
}
|
||||
|
||||
if temporaryDirectory != "" {
|
||||
os.RemoveAll(temporaryDirectory)
|
||||
}
|
||||
|
||||
C.vips_shutdown()
|
||||
disableLogging()
|
||||
running = false
|
||||
}
|
||||
|
||||
// ShutdownThread clears the cache for for the given thread. This needs to be
|
||||
// called when a thread using vips exits.
|
||||
func ShutdownThread() {
|
||||
C.vips_thread_shutdown()
|
||||
}
|
||||
|
||||
// ClearCache drops the whole operation cache, handy for leak tracking.
|
||||
func ClearCache() {
|
||||
C.vips_cache_drop_all()
|
||||
}
|
||||
|
||||
// PrintCache prints the whole operation cache to stdout for debugging purposes.
|
||||
func PrintCache() {
|
||||
C.vips_cache_print()
|
||||
}
|
||||
|
||||
// PrintObjectReport outputs all of the current internal objects in libvips
|
||||
func PrintObjectReport(label string) {
|
||||
govipsLog("govips", LogLevelInfo, fmt.Sprintf("\n=======================================\nvips live objects: %s...\n", label))
|
||||
C.vips_object_print_all()
|
||||
govipsLog("govips", LogLevelInfo, "=======================================\n\n")
|
||||
}
|
||||
|
||||
// MemoryStats is a data structure that houses various memory statistics from ReadVipsMemStats()
|
||||
type MemoryStats struct {
|
||||
Mem int64
|
||||
MemHigh int64
|
||||
Files int64
|
||||
Allocs int64
|
||||
}
|
||||
|
||||
// ReadVipsMemStats returns various memory statistics such as allocated memory and open files.
|
||||
func ReadVipsMemStats(stats *MemoryStats) {
|
||||
stats.Mem = int64(C.vips_tracked_get_mem())
|
||||
stats.MemHigh = int64(C.vips_tracked_get_mem_highwater())
|
||||
stats.Allocs = int64(C.vips_tracked_get_allocs())
|
||||
stats.Files = int64(C.vips_tracked_get_files())
|
||||
}
|
||||
|
||||
func startupIfNeeded() {
|
||||
if !running {
|
||||
govipsLog("govips", LogLevelInfo, "libvips was forcibly started automatically, consider calling Startup/Shutdown yourself")
|
||||
Startup(nil)
|
||||
}
|
||||
}
|
||||
|
||||
// InitTypes initializes caches and figures out which image types are supported
|
||||
func initTypes() {
|
||||
once.Do(func() {
|
||||
cType := C.CString("VipsOperation")
|
||||
defer freeCString(cType)
|
||||
|
||||
for k, v := range ImageTypes {
|
||||
name := strings.ToLower("VipsForeignLoad" + v)
|
||||
typeLoaders[name] = k
|
||||
typeLoaders[name+"buffer"] = k
|
||||
|
||||
cFunc := C.CString(v + "load")
|
||||
//noinspection GoDeferInLoop
|
||||
defer freeCString(cFunc)
|
||||
|
||||
ret := C.vips_type_find(cType, cFunc)
|
||||
|
||||
supportedImageTypes[k] = int(ret) != 0
|
||||
|
||||
if supportedImageTypes[k] {
|
||||
govipsLog("govips", LogLevelInfo, fmt.Sprintf("registered image type loader type=%s", v))
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
122
vendor/github.com/davidbyttow/govips/v2/vips/header.c
generated
vendored
122
vendor/github.com/davidbyttow/govips/v2/vips/header.c
generated
vendored
@@ -1,122 +0,0 @@
|
||||
#include "header.h"
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
unsigned long has_icc_profile(VipsImage *in) {
|
||||
return vips_image_get_typeof(in, VIPS_META_ICC_NAME);
|
||||
}
|
||||
|
||||
unsigned long get_icc_profile(VipsImage *in, const void **data,
|
||||
size_t *dataLength) {
|
||||
return image_get_blob(in, VIPS_META_ICC_NAME, data, dataLength);
|
||||
}
|
||||
|
||||
gboolean remove_icc_profile(VipsImage *in) {
|
||||
return vips_image_remove(in, VIPS_META_ICC_NAME);
|
||||
}
|
||||
|
||||
unsigned long has_iptc(VipsImage *in) {
|
||||
return vips_image_get_typeof(in, VIPS_META_IPTC_NAME);
|
||||
}
|
||||
|
||||
char **image_get_fields(VipsImage *in) { return vips_image_get_fields(in); }
|
||||
|
||||
void image_set_string(VipsImage *in, const char *name, const char *str) {
|
||||
vips_image_set_string(in, name, str);
|
||||
}
|
||||
|
||||
unsigned long image_get_string(VipsImage *in, const char *name,
|
||||
const char **out) {
|
||||
return vips_image_get_string(in, name, out);
|
||||
}
|
||||
|
||||
unsigned long image_get_as_string(VipsImage *in, const char *name, char **out) {
|
||||
return vips_image_get_as_string(in, name, out);
|
||||
}
|
||||
|
||||
void remove_field(VipsImage *in, char *field) { vips_image_remove(in, field); }
|
||||
|
||||
int get_meta_orientation(VipsImage *in) {
|
||||
int orientation = 0;
|
||||
if (vips_image_get_typeof(in, VIPS_META_ORIENTATION) != 0) {
|
||||
vips_image_get_int(in, VIPS_META_ORIENTATION, &orientation);
|
||||
}
|
||||
|
||||
return orientation;
|
||||
}
|
||||
|
||||
void remove_meta_orientation(VipsImage *in) {
|
||||
vips_image_remove(in, VIPS_META_ORIENTATION);
|
||||
}
|
||||
|
||||
void set_meta_orientation(VipsImage *in, int orientation) {
|
||||
vips_image_set_int(in, VIPS_META_ORIENTATION, orientation);
|
||||
}
|
||||
|
||||
// https://libvips.github.io/libvips/API/current/libvips-header.html#vips-image-get-n-pages
|
||||
int get_image_n_pages(VipsImage *in) {
|
||||
int n_pages = 0;
|
||||
n_pages = vips_image_get_n_pages(in);
|
||||
return n_pages;
|
||||
}
|
||||
|
||||
void set_image_n_pages(VipsImage *in, int n_pages) {
|
||||
vips_image_set_int(in, VIPS_META_N_PAGES, n_pages);
|
||||
}
|
||||
|
||||
// https://www.libvips.org/API/current/libvips-header.html#vips-image-get-page-height
|
||||
int get_page_height(VipsImage *in) {
|
||||
int page_height = 0;
|
||||
page_height = vips_image_get_page_height(in);
|
||||
return page_height;
|
||||
}
|
||||
|
||||
void set_page_height(VipsImage *in, int height) {
|
||||
vips_image_set_int(in, VIPS_META_PAGE_HEIGHT, height);
|
||||
}
|
||||
|
||||
int get_meta_loader(const VipsImage *in, const char **out) {
|
||||
return vips_image_get_string(in, VIPS_META_LOADER, out);
|
||||
}
|
||||
|
||||
int get_image_delay(VipsImage *in, int **out) {
|
||||
return vips_image_get_array_int(in, "delay", out, NULL);
|
||||
}
|
||||
|
||||
void set_image_delay(VipsImage *in, const int *array, int n) {
|
||||
return vips_image_set_array_int(in, "delay", array, n);
|
||||
}
|
||||
|
||||
void image_set_double(VipsImage *in, const char *name, double i) {
|
||||
vips_image_set_double(in, name, i);
|
||||
}
|
||||
|
||||
unsigned long image_get_double(VipsImage *in, const char *name, double *out) {
|
||||
return vips_image_get_double(in, name, out);
|
||||
}
|
||||
|
||||
void image_set_int(VipsImage *in, const char *name, int i) {
|
||||
vips_image_set_int(in, name, i);
|
||||
}
|
||||
|
||||
unsigned long image_get_int(VipsImage *in, const char *name, int *out) {
|
||||
return vips_image_get_int(in, name, out);
|
||||
}
|
||||
|
||||
void image_set_blob(VipsImage *in, const char *name, const void *data,
|
||||
size_t dataLength) {
|
||||
vips_image_set_blob_copy(in, name, data, dataLength);
|
||||
}
|
||||
|
||||
unsigned long image_get_blob(VipsImage *in, const char *name, const void **data,
|
||||
size_t *dataLength) {
|
||||
if (vips_image_get_typeof(in, name) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (vips_image_get_blob(in, name, data, dataLength)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
289
vendor/github.com/davidbyttow/govips/v2/vips/header.go
generated
vendored
289
vendor/github.com/davidbyttow/govips/v2/vips/header.go
generated
vendored
@@ -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 ""
|
||||
}
|
||||
41
vendor/github.com/davidbyttow/govips/v2/vips/header.h
generated
vendored
41
vendor/github.com/davidbyttow/govips/v2/vips/header.h
generated
vendored
@@ -1,41 +0,0 @@
|
||||
// https://libvips.github.io/libvips/API/current/libvips-header.html
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <vips/vips.h>
|
||||
|
||||
unsigned long has_icc_profile(VipsImage *in);
|
||||
unsigned long get_icc_profile(VipsImage *in, const void **data,
|
||||
size_t *dataLength);
|
||||
int remove_icc_profile(VipsImage *in);
|
||||
|
||||
unsigned long has_iptc(VipsImage *in);
|
||||
char **image_get_fields(VipsImage *in);
|
||||
|
||||
void image_set_string(VipsImage *in, const char *name, const char *str);
|
||||
unsigned long image_get_string(VipsImage *in, const char *name,
|
||||
const char **out);
|
||||
unsigned long image_get_as_string(VipsImage *in, const char *name, char **out);
|
||||
|
||||
void remove_field(VipsImage *in, char *field);
|
||||
|
||||
int get_meta_orientation(VipsImage *in);
|
||||
void remove_meta_orientation(VipsImage *in);
|
||||
void set_meta_orientation(VipsImage *in, int orientation);
|
||||
int get_image_n_pages(VipsImage *in);
|
||||
void set_image_n_pages(VipsImage *in, int n_pages);
|
||||
int get_page_height(VipsImage *in);
|
||||
void set_page_height(VipsImage *in, int height);
|
||||
int get_meta_loader(const VipsImage *in, const char **out);
|
||||
int get_image_delay(VipsImage *in, int **out);
|
||||
void set_image_delay(VipsImage *in, const int *array, int n);
|
||||
|
||||
void image_set_blob(VipsImage *in, const char *name, const void *data,
|
||||
size_t dataLength);
|
||||
unsigned long image_get_blob(VipsImage *in, const char *name, const void **data,
|
||||
size_t *dataLength);
|
||||
|
||||
void image_set_double(VipsImage *in, const char *name, double i);
|
||||
unsigned long image_get_double(VipsImage *in, const char *name, double *out);
|
||||
|
||||
void image_set_int(VipsImage *in, const char *name, int i);
|
||||
unsigned long image_get_int(VipsImage *in, const char *name, int *out);
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user