This commit is contained in:
Tomáš Dvořák
2025-10-03 16:26:44 +02:00
parent 0fc92f8464
commit cdb8bcd3e9
5928 changed files with 1054476 additions and 72 deletions
+191
View File
@@ -0,0 +1,191 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction, and
distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by the copyright
owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all other entities
that control, are controlled by, or are under common control with that entity.
For the purposes of this definition, "control" means (i) the power, direct or
indirect, to cause the direction or management of such entity, whether by
contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity exercising
permissions granted by this License.
"Source" form shall mean the preferred form for making modifications, including
but not limited to software source code, documentation source, and configuration
files.
"Object" form shall mean any form resulting from mechanical transformation or
translation of a Source form, including but not limited to compiled object code,
generated documentation, and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or Object form, made
available under the License, as indicated by a copyright notice that is included
in or attached to the work (an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object form, that
is based on (or derived from) the Work and for which the editorial revisions,
annotations, elaborations, or other modifications represent, as a whole, an
original work of authorship. For the purposes of this License, Derivative Works
shall not include works that remain separable from, or merely link (or bind by
name) to the interfaces of, the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including the original version
of the Work and any modifications or additions to that Work or Derivative Works
thereof, that is intentionally submitted to Licensor for inclusion in the Work
by the copyright owner or by an individual or Legal Entity authorized to submit
on behalf of the copyright owner. For the purposes of this definition,
"submitted" means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems, and
issue tracking systems that are managed by, or on behalf of, the Licensor for
the purpose of discussing and improving the Work, but excluding communication
that is conspicuously marked or otherwise designated in writing by the copyright
owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
of whom a Contribution has been received by Licensor and subsequently
incorporated within the Work.
2. Grant of Copyright License.
Subject to the terms and conditions of this License, each Contributor hereby
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
irrevocable copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the Work and such
Derivative Works in Source or Object form.
3. Grant of Patent License.
Subject to the terms and conditions of this License, each Contributor hereby
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
irrevocable (except as stated in this section) patent license to make, have
made, use, offer to sell, sell, import, and otherwise transfer the Work, where
such license applies only to those patent claims licensable by such Contributor
that are necessarily infringed by their Contribution(s) alone or by combination
of their Contribution(s) with the Work to which such Contribution(s) was
submitted. If You institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work or a
Contribution incorporated within the Work constitutes direct or contributory
patent infringement, then any patent licenses granted to You under this License
for that Work shall terminate as of the date such litigation is filed.
4. Redistribution.
You may reproduce and distribute copies of the Work or Derivative Works thereof
in any medium, with or without modifications, and in Source or Object form,
provided that You meet the following conditions:
You must give any other recipients of the Work or Derivative Works a copy of
this License; and
You must cause any modified files to carry prominent notices stating that You
changed the files; and
You must retain, in the Source form of any Derivative Works that You distribute,
all copyright, patent, trademark, and attribution notices from the Source form
of the Work, excluding those notices that do not pertain to any part of the
Derivative Works; and
If the Work includes a "NOTICE" text file as part of its distribution, then any
Derivative Works that You distribute must include a readable copy of the
attribution notices contained within such NOTICE file, excluding those notices
that do not pertain to any part of the Derivative Works, in at least one of the
following places: within a NOTICE text file distributed as part of the
Derivative Works; within the Source form or documentation, if provided along
with the Derivative Works; or, within a display generated by the Derivative
Works, if and wherever such third-party notices normally appear. The contents of
the NOTICE file are for informational purposes only and do not modify the
License. You may add Your own attribution notices within Derivative Works that
You distribute, alongside or as an addendum to the NOTICE text from the Work,
provided that such additional attribution notices cannot be construed as
modifying the License.
You may add Your own copyright statement to Your modifications and may provide
additional or different license terms and conditions for use, reproduction, or
distribution of Your modifications, or for any such Derivative Works as a whole,
provided Your use, reproduction, and distribution of the Work otherwise complies
with the conditions stated in this License.
5. Submission of Contributions.
Unless You explicitly state otherwise, any Contribution intentionally submitted
for inclusion in the Work by You to the Licensor shall be under the terms and
conditions of this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify the terms of
any separate license agreement you may have executed with Licensor regarding
such Contributions.
6. Trademarks.
This License does not grant permission to use the trade names, trademarks,
service marks, or product names of the Licensor, except as required for
reasonable and customary use in describing the origin of the Work and
reproducing the content of the NOTICE file.
7. Disclaimer of Warranty.
Unless required by applicable law or agreed to in writing, Licensor provides the
Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
including, without limitation, any warranties or conditions of TITLE,
NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
solely responsible for determining the appropriateness of using or
redistributing the Work and assume any risks associated with Your exercise of
permissions under this License.
8. Limitation of Liability.
In no event and under no legal theory, whether in tort (including negligence),
contract, or otherwise, unless required by applicable law (such as deliberate
and grossly negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special, incidental,
or consequential damages of any character arising as a result of this License or
out of the use or inability to use the Work (including but not limited to
damages for loss of goodwill, work stoppage, computer failure or malfunction, or
any and all other commercial damages or losses), even if such Contributor has
been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability.
While redistributing the Work or Derivative Works thereof, You may choose to
offer, and charge a fee for, acceptance of support, warranty, indemnity, or
other liability obligations and/or rights consistent with this License. However,
in accepting such obligations, You may act only on Your own behalf and on Your
sole responsibility, not on behalf of any other Contributor, and only if You
agree to indemnify, defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason of your
accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work
To apply the Apache License to your work, attach the following boilerplate
notice, with the fields enclosed by brackets "[]" replaced with your own
identifying information. (Don't include the brackets!) The text should be
enclosed in the appropriate comment syntax for the file format. We also
recommend that a file or class name and description of purpose be included on
the same "printed page" as the copyright notice for easier identification within
third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
+114
View File
@@ -0,0 +1,114 @@
# sharp
<img src="https://cdn.jsdelivr.net/gh/lovell/sharp@main/docs/image/sharp-logo.svg" width="160" height="160" alt="sharp logo" align="right">
The typical use case for this high speed Node.js module
is to convert large images in common formats to
smaller, web-friendly JPEG, PNG, WebP, GIF and AVIF images of varying dimensions.
Resizing an image is typically 4x-5x faster than using the
quickest ImageMagick and GraphicsMagick settings
due to its use of [libvips](https://github.com/libvips/libvips).
Colour spaces, embedded ICC profiles and alpha transparency channels are all handled correctly.
Lanczos resampling ensures quality is not sacrificed for speed.
As well as image resizing, operations such as
rotation, extraction, compositing and gamma correction are available.
Most modern macOS, Windows and Linux systems running Node.js >= 14.15.0
do not require any additional install or runtime dependencies.
## Documentation
Visit [sharp.pixelplumbing.com](https://sharp.pixelplumbing.com/) for complete
[installation instructions](https://sharp.pixelplumbing.com/install),
[API documentation](https://sharp.pixelplumbing.com/api-constructor),
[benchmark tests](https://sharp.pixelplumbing.com/performance) and
[changelog](https://sharp.pixelplumbing.com/changelog).
## Examples
```sh
npm install sharp
```
```javascript
const sharp = require('sharp');
```
### Callback
```javascript
sharp(inputBuffer)
.resize(320, 240)
.toFile('output.webp', (err, info) => { ... });
```
### Promise
```javascript
sharp('input.jpg')
.rotate()
.resize(200)
.jpeg({ mozjpeg: true })
.toBuffer()
.then( data => { ... })
.catch( err => { ... });
```
### Async/await
```javascript
const semiTransparentRedPng = await sharp({
create: {
width: 48,
height: 48,
channels: 4,
background: { r: 255, g: 0, b: 0, alpha: 0.5 }
}
})
.png()
.toBuffer();
```
### Stream
```javascript
const roundedCorners = Buffer.from(
'<svg><rect x="0" y="0" width="200" height="200" rx="50" ry="50"/></svg>'
);
const roundedCornerResizer =
sharp()
.resize(200, 200)
.composite([{
input: roundedCorners,
blend: 'dest-in'
}])
.png();
readableStream
.pipe(roundedCornerResizer)
.pipe(writableStream);
```
## Contributing
A [guide for contributors](https://github.com/lovell/sharp/blob/main/.github/CONTRIBUTING.md)
covers reporting bugs, requesting features and submitting code changes.
## Licensing
Copyright 2013 Lovell Fuller and others.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
[https://www.apache.org/licenses/LICENSE-2.0](https://www.apache.org/licenses/LICENSE-2.0)
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
+236
View File
@@ -0,0 +1,236 @@
{
'variables': {
'vips_version': '<!(node -p "require(\'./lib/libvips\').minimumLibvipsVersion")',
'platform_and_arch': '<!(node -p "require(\'./lib/platform\')()")',
'sharp_vendor_dir': './vendor/<(vips_version)/<(platform_and_arch)'
},
'targets': [{
'target_name': 'libvips-cpp',
'conditions': [
['OS == "win"', {
# Build libvips C++ binding for Windows due to MSVC std library ABI changes
'type': 'shared_library',
'defines': [
'VIPS_CPLUSPLUS_EXPORTS',
'_ALLOW_KEYWORD_MACROS'
],
'sources': [
'src/libvips/cplusplus/VConnection.cpp',
'src/libvips/cplusplus/VError.cpp',
'src/libvips/cplusplus/VImage.cpp',
'src/libvips/cplusplus/VInterpolate.cpp',
'src/libvips/cplusplus/VRegion.cpp'
],
'include_dirs': [
'<(sharp_vendor_dir)/include',
'<(sharp_vendor_dir)/include/glib-2.0',
'<(sharp_vendor_dir)/lib/glib-2.0/include'
],
'link_settings': {
'library_dirs': ['<(sharp_vendor_dir)/lib'],
'libraries': [
'libvips.lib',
'libglib-2.0.lib',
'libgobject-2.0.lib'
],
},
'configurations': {
'Release': {
'msvs_settings': {
'VCCLCompilerTool': {
'ExceptionHandling': 1,
'Optimization': 1,
'WholeProgramOptimization': 'true'
},
'VCLibrarianTool': {
'AdditionalOptions': [
'/LTCG:INCREMENTAL'
]
},
'VCLinkerTool': {
'ImageHasSafeExceptionHandlers': 'false',
'OptimizeReferences': 2,
'EnableCOMDATFolding': 2,
'LinkIncremental': 1,
'AdditionalOptions': [
'/LTCG:INCREMENTAL'
]
}
},
'msvs_disabled_warnings': [
4275
]
}
}
}, {
# Ignore this target for non-Windows
'type': 'none'
}]
]
}, {
'target_name': 'sharp-<(platform_and_arch)',
'defines': [
'NAPI_VERSION=7',
'NODE_ADDON_API_DISABLE_DEPRECATED',
'NODE_API_SWALLOW_UNTHROWABLE_EXCEPTIONS'
],
'dependencies': [
'<!(node -p "require(\'node-addon-api\').gyp")',
'libvips-cpp'
],
'variables': {
'runtime_link%': 'shared',
'conditions': [
['OS != "win"', {
'pkg_config_path': '<!(node -p "require(\'./lib/libvips\').pkgConfigPath()")',
'use_global_libvips': '<!(node -p "Boolean(require(\'./lib/libvips\').useGlobalLibvips()).toString()")'
}, {
'pkg_config_path': '',
'use_global_libvips': ''
}]
]
},
'sources': [
'src/common.cc',
'src/metadata.cc',
'src/stats.cc',
'src/operations.cc',
'src/pipeline.cc',
'src/utilities.cc',
'src/sharp.cc'
],
'include_dirs': [
'<!(node -p "require(\'node-addon-api\').include_dir")',
],
'conditions': [
['use_global_libvips == "true"', {
# Use pkg-config for include and lib
'include_dirs': ['<!@(PKG_CONFIG_PATH="<(pkg_config_path)" pkg-config --cflags-only-I vips-cpp vips glib-2.0 | sed s\/-I//g)'],
'conditions': [
['runtime_link == "static"', {
'libraries': ['<!@(PKG_CONFIG_PATH="<(pkg_config_path)" pkg-config --libs --static vips-cpp)']
}, {
'libraries': ['<!@(PKG_CONFIG_PATH="<(pkg_config_path)" pkg-config --libs vips-cpp)']
}],
['OS == "linux"', {
'defines': [
# Inspect libvips-cpp.so to determine which C++11 ABI version was used and set _GLIBCXX_USE_CXX11_ABI accordingly. This is quite horrible.
'_GLIBCXX_USE_CXX11_ABI=<!(if readelf -Ws "$(PKG_CONFIG_PATH="<(pkg_config_path)" pkg-config --variable libdir vips-cpp)/libvips-cpp.so" | c++filt | grep -qF __cxx11;then echo "1";else echo "0";fi)'
]
}]
]
}, {
# Use pre-built libvips stored locally within node_modules
'include_dirs': [
'<(sharp_vendor_dir)/include',
'<(sharp_vendor_dir)/include/glib-2.0',
'<(sharp_vendor_dir)/lib/glib-2.0/include'
],
'conditions': [
['OS == "win"', {
'defines': [
'_ALLOW_KEYWORD_MACROS',
'_FILE_OFFSET_BITS=64'
],
'link_settings': {
'library_dirs': ['<(sharp_vendor_dir)/lib'],
'libraries': [
'libvips.lib',
'libglib-2.0.lib',
'libgobject-2.0.lib'
]
}
}],
['OS == "mac"', {
'link_settings': {
'library_dirs': ['../<(sharp_vendor_dir)/lib'],
'libraries': [
'libvips-cpp.42.dylib'
]
},
'xcode_settings': {
'OTHER_LDFLAGS': [
# Ensure runtime linking is relative to sharp.node
'-Wl,-rpath,\'@loader_path/../../<(sharp_vendor_dir)/lib\''
]
}
}],
['OS == "linux"', {
'defines': [
'_GLIBCXX_USE_CXX11_ABI=1'
],
'link_settings': {
'library_dirs': ['../<(sharp_vendor_dir)/lib'],
'libraries': [
'-l:libvips-cpp.so.42'
],
'ldflags': [
# Ensure runtime linking is relative to sharp.node
'-Wl,-s -Wl,--disable-new-dtags -Wl,-rpath=\'$$ORIGIN/../../<(sharp_vendor_dir)/lib\''
]
}
}]
]
}]
],
'cflags_cc': [
'-std=c++0x',
'-fexceptions',
'-Wall',
'-Os'
],
'xcode_settings': {
'CLANG_CXX_LANGUAGE_STANDARD': 'c++11',
'MACOSX_DEPLOYMENT_TARGET': '10.13',
'GCC_ENABLE_CPP_EXCEPTIONS': 'YES',
'GCC_ENABLE_CPP_RTTI': 'YES',
'OTHER_CPLUSPLUSFLAGS': [
'-fexceptions',
'-Wall',
'-Oz'
]
},
'configurations': {
'Release': {
'conditions': [
['OS == "linux"', {
'cflags_cc': [
'-Wno-cast-function-type'
]
}],
['target_arch == "arm"', {
'cflags_cc': [
'-Wno-psabi'
]
}],
['OS == "win"', {
'msvs_settings': {
'VCCLCompilerTool': {
'ExceptionHandling': 1,
'Optimization': 1,
'WholeProgramOptimization': 'true'
},
'VCLibrarianTool': {
'AdditionalOptions': [
'/LTCG:INCREMENTAL'
]
},
'VCLinkerTool': {
'ImageHasSafeExceptionHandlers': 'false',
'OptimizeReferences': 2,
'EnableCOMDATFolding': 2,
'LinkIncremental': 1,
'AdditionalOptions': [
'/LTCG:INCREMENTAL'
]
}
},
'msvs_disabled_warnings': [
4275
]
}]
]
}
},
}]
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+14
View File
@@ -0,0 +1,14 @@
// Copyright 2013 Lovell Fuller and others.
// SPDX-License-Identifier: Apache-2.0
'use strict';
const libvips = require('../lib/libvips');
try {
if (!(libvips.useGlobalLibvips() || libvips.hasVendoredLibvips())) {
process.exitCode = 1;
}
} catch (err) {
process.exitCode = 1;
}
+40
View File
@@ -0,0 +1,40 @@
// Copyright 2013 Lovell Fuller and others.
// SPDX-License-Identifier: Apache-2.0
'use strict';
const fs = require('fs');
const path = require('path');
const libvips = require('../lib/libvips');
const platform = require('../lib/platform');
const minimumLibvipsVersion = libvips.minimumLibvipsVersion;
const platformAndArch = platform();
if (platformAndArch.startsWith('win32')) {
const buildReleaseDir = path.join(__dirname, '..', 'build', 'Release');
libvips.log(`Creating ${buildReleaseDir}`);
try {
libvips.mkdirSync(buildReleaseDir);
} catch (err) {}
const vendorLibDir = path.join(__dirname, '..', 'vendor', minimumLibvipsVersion, platformAndArch, 'lib');
libvips.log(`Copying DLLs from ${vendorLibDir} to ${buildReleaseDir}`);
try {
fs
.readdirSync(vendorLibDir)
.filter(function (filename) {
return /\.dll$/.test(filename);
})
.forEach(function (filename) {
fs.copyFileSync(
path.join(vendorLibDir, filename),
path.join(buildReleaseDir, filename)
);
});
} catch (err) {
libvips.log(err);
process.exit(1);
}
}
+222
View File
@@ -0,0 +1,222 @@
// Copyright 2013 Lovell Fuller and others.
// SPDX-License-Identifier: Apache-2.0
'use strict';
const fs = require('fs');
const os = require('os');
const path = require('path');
const stream = require('stream');
const zlib = require('zlib');
const { createHash } = require('crypto');
const detectLibc = require('detect-libc');
const semverCoerce = require('semver/functions/coerce');
const semverLessThan = require('semver/functions/lt');
const semverSatisfies = require('semver/functions/satisfies');
const simpleGet = require('simple-get');
const tarFs = require('tar-fs');
const agent = require('../lib/agent');
const libvips = require('../lib/libvips');
const platform = require('../lib/platform');
const minimumGlibcVersionByArch = {
arm: '2.28',
arm64: '2.17',
x64: '2.17'
};
const hasSharpPrebuild = [
'darwin-x64',
'darwin-arm64',
'linux-arm64',
'linux-x64',
'linuxmusl-x64',
'linuxmusl-arm64',
'win32-ia32',
'win32-x64'
];
const { minimumLibvipsVersion, minimumLibvipsVersionLabelled } = libvips;
const localLibvipsDir = process.env.npm_config_sharp_libvips_local_prebuilds || '';
const distHost = process.env.npm_config_sharp_libvips_binary_host || 'https://github.com/lovell/sharp-libvips/releases/download';
const distBaseUrl = process.env.npm_config_sharp_dist_base_url || process.env.SHARP_DIST_BASE_URL || `${distHost}/v${minimumLibvipsVersionLabelled}/`;
const installationForced = !!(process.env.npm_config_sharp_install_force || process.env.SHARP_INSTALL_FORCE);
const fail = function (err) {
libvips.log(err);
if (err.code === 'EACCES') {
libvips.log('Are you trying to install as a root or sudo user?');
libvips.log('- For npm <= v6, try again with the "--unsafe-perm" flag');
libvips.log('- For npm >= v8, the user must own the directory "npm install" is run in');
}
libvips.log('Please see https://sharp.pixelplumbing.com/install for required dependencies');
process.exit(1);
};
const handleError = function (err) {
if (installationForced) {
libvips.log(`Installation warning: ${err.message}`);
} else {
throw err;
}
};
const verifyIntegrity = function (platformAndArch) {
const expected = libvips.integrity(platformAndArch);
if (installationForced || !expected) {
libvips.log(`Integrity check skipped for ${platformAndArch}`);
return new stream.PassThrough();
}
const hash = createHash('sha512');
return new stream.Transform({
transform: function (chunk, _encoding, done) {
hash.update(chunk);
done(null, chunk);
},
flush: function (done) {
const digest = `sha512-${hash.digest('base64')}`;
if (expected !== digest) {
try {
libvips.removeVendoredLibvips();
} catch (err) {
libvips.log(err.message);
}
libvips.log(`Integrity expected: ${expected}`);
libvips.log(`Integrity received: ${digest}`);
done(new Error(`Integrity check failed for ${platformAndArch}`));
} else {
libvips.log(`Integrity check passed for ${platformAndArch}`);
done();
}
}
});
};
const extractTarball = function (tarPath, platformAndArch) {
const versionedVendorPath = path.join(__dirname, '..', 'vendor', minimumLibvipsVersion, platformAndArch);
libvips.mkdirSync(versionedVendorPath);
const ignoreVendorInclude = hasSharpPrebuild.includes(platformAndArch) && !process.env.npm_config_build_from_source;
const ignore = function (name) {
return ignoreVendorInclude && name.includes('include/');
};
stream.pipeline(
fs.createReadStream(tarPath),
verifyIntegrity(platformAndArch),
new zlib.BrotliDecompress(),
tarFs.extract(versionedVendorPath, { ignore }),
function (err) {
if (err) {
if (/unexpected end of file/.test(err.message)) {
fail(new Error(`Please delete ${tarPath} as it is not a valid tarball`));
}
fail(err);
}
}
);
};
try {
const useGlobalLibvips = libvips.useGlobalLibvips();
if (useGlobalLibvips) {
const globalLibvipsVersion = libvips.globalLibvipsVersion();
libvips.log(`Detected globally-installed libvips v${globalLibvipsVersion}`);
libvips.log('Building from source via node-gyp');
process.exit(1);
} else if (libvips.hasVendoredLibvips()) {
libvips.log(`Using existing vendored libvips v${minimumLibvipsVersion}`);
} else {
// Is this arch/platform supported?
const arch = process.env.npm_config_arch || process.arch;
const platformAndArch = platform();
if (arch === 'ia32' && !platformAndArch.startsWith('win32')) {
throw new Error(`Intel Architecture 32-bit systems require manual installation of libvips >= ${minimumLibvipsVersion}`);
}
if (platformAndArch === 'freebsd-x64' || platformAndArch === 'openbsd-x64' || platformAndArch === 'sunos-x64') {
throw new Error(`BSD/SunOS systems require manual installation of libvips >= ${minimumLibvipsVersion}`);
}
// Linux libc version check
const libcVersionRaw = detectLibc.versionSync();
if (libcVersionRaw) {
const libcFamily = detectLibc.familySync();
const libcVersion = semverCoerce(libcVersionRaw).version;
if (libcFamily === detectLibc.GLIBC && minimumGlibcVersionByArch[arch]) {
if (semverLessThan(libcVersion, semverCoerce(minimumGlibcVersionByArch[arch]).version)) {
handleError(new Error(`Use with glibc ${libcVersionRaw} requires manual installation of libvips >= ${minimumLibvipsVersion}`));
}
}
if (libcFamily === detectLibc.MUSL) {
if (semverLessThan(libcVersion, '1.1.24')) {
handleError(new Error(`Use with musl ${libcVersionRaw} requires manual installation of libvips >= ${minimumLibvipsVersion}`));
}
}
}
// Node.js minimum version check
const supportedNodeVersion = process.env.npm_package_engines_node || require('../package.json').engines.node;
if (!semverSatisfies(process.versions.node, supportedNodeVersion)) {
handleError(new Error(`Expected Node.js version ${supportedNodeVersion} but found ${process.versions.node}`));
}
// Download to per-process temporary file
const tarFilename = ['libvips', minimumLibvipsVersionLabelled, platformAndArch].join('-') + '.tar.br';
const tarPathCache = path.join(libvips.cachePath(), tarFilename);
if (fs.existsSync(tarPathCache)) {
libvips.log(`Using cached ${tarPathCache}`);
extractTarball(tarPathCache, platformAndArch);
} else if (localLibvipsDir) {
// If localLibvipsDir is given try to use binaries from local directory
const tarPathLocal = path.join(path.resolve(localLibvipsDir), `v${minimumLibvipsVersionLabelled}`, tarFilename);
libvips.log(`Using local libvips from ${tarPathLocal}`);
extractTarball(tarPathLocal, platformAndArch);
} else {
const url = distBaseUrl + tarFilename;
libvips.log(`Downloading ${url}`);
simpleGet({ url: url, agent: agent(libvips.log) }, function (err, response) {
if (err) {
fail(err);
} else if (response.statusCode === 404) {
fail(new Error(`Prebuilt libvips ${minimumLibvipsVersion} binaries are not yet available for ${platformAndArch}`));
} else if (response.statusCode !== 200) {
fail(new Error(`Status ${response.statusCode} ${response.statusMessage}`));
} else {
const tarPathTemp = path.join(os.tmpdir(), `${process.pid}-${tarFilename}`);
const tmpFileStream = fs.createWriteStream(tarPathTemp);
response
.on('error', function (err) {
tmpFileStream.destroy(err);
})
.on('close', function () {
if (!response.complete) {
tmpFileStream.destroy(new Error('Download incomplete (connection was terminated)'));
}
})
.pipe(tmpFileStream);
tmpFileStream
.on('error', function (err) {
// Clean up temporary file
try {
fs.unlinkSync(tarPathTemp);
} catch (e) {}
fail(err);
})
.on('close', function () {
try {
// Attempt to rename
fs.renameSync(tarPathTemp, tarPathCache);
} catch (err) {
// Fall back to copy and unlink
fs.copyFileSync(tarPathTemp, tarPathCache);
fs.unlinkSync(tarPathTemp);
}
extractTarball(tarPathCache, platformAndArch);
});
}
});
}
}
} catch (err) {
fail(err);
}
+44
View File
@@ -0,0 +1,44 @@
// Copyright 2013 Lovell Fuller and others.
// SPDX-License-Identifier: Apache-2.0
'use strict';
const url = require('url');
const tunnelAgent = require('tunnel-agent');
const is = require('./is');
const proxies = [
'HTTPS_PROXY',
'https_proxy',
'HTTP_PROXY',
'http_proxy',
'npm_config_https_proxy',
'npm_config_proxy'
];
function env (key) {
return process.env[key];
}
module.exports = function (log) {
try {
const proxy = new url.URL(proxies.map(env).find(is.string));
const tunnel = proxy.protocol === 'https:'
? tunnelAgent.httpsOverHttps
: tunnelAgent.httpsOverHttp;
const proxyAuth = proxy.username && proxy.password
? `${decodeURIComponent(proxy.username)}:${decodeURIComponent(proxy.password)}`
: null;
log(`Via proxy ${proxy.protocol}//${proxy.hostname}:${proxy.port} ${proxyAuth ? 'with' : 'no'} credentials`);
return tunnel({
proxy: {
port: Number(proxy.port),
host: proxy.hostname,
proxyAuth
}
});
} catch (err) {
return null;
}
};
+174
View File
@@ -0,0 +1,174 @@
// Copyright 2013 Lovell Fuller and others.
// SPDX-License-Identifier: Apache-2.0
'use strict';
const is = require('./is');
/**
* Boolean operations for bandbool.
* @private
*/
const bool = {
and: 'and',
or: 'or',
eor: 'eor'
};
/**
* Remove alpha channel, if any. This is a no-op if the image does not have an alpha channel.
*
* See also {@link /api-operation#flatten|flatten}.
*
* @example
* sharp('rgba.png')
* .removeAlpha()
* .toFile('rgb.png', function(err, info) {
* // rgb.png is a 3 channel image without an alpha channel
* });
*
* @returns {Sharp}
*/
function removeAlpha () {
this.options.removeAlpha = true;
return this;
}
/**
* Ensure the output image has an alpha transparency channel.
* If missing, the added alpha channel will have the specified
* transparency level, defaulting to fully-opaque (1).
* This is a no-op if the image already has an alpha channel.
*
* @since 0.21.2
*
* @example
* // rgba.png will be a 4 channel image with a fully-opaque alpha channel
* await sharp('rgb.jpg')
* .ensureAlpha()
* .toFile('rgba.png')
*
* @example
* // rgba is a 4 channel image with a fully-transparent alpha channel
* const rgba = await sharp(rgb)
* .ensureAlpha(0)
* .toBuffer();
*
* @param {number} [alpha=1] - alpha transparency level (0=fully-transparent, 1=fully-opaque)
* @returns {Sharp}
* @throws {Error} Invalid alpha transparency level
*/
function ensureAlpha (alpha) {
if (is.defined(alpha)) {
if (is.number(alpha) && is.inRange(alpha, 0, 1)) {
this.options.ensureAlpha = alpha;
} else {
throw is.invalidParameterError('alpha', 'number between 0 and 1', alpha);
}
} else {
this.options.ensureAlpha = 1;
}
return this;
}
/**
* Extract a single channel from a multi-channel image.
*
* @example
* // green.jpg is a greyscale image containing the green channel of the input
* await sharp(input)
* .extractChannel('green')
* .toFile('green.jpg');
*
* @example
* // red1 is the red value of the first pixel, red2 the second pixel etc.
* const [red1, red2, ...] = await sharp(input)
* .extractChannel(0)
* .raw()
* .toBuffer();
*
* @param {number|string} channel - zero-indexed channel/band number to extract, or `red`, `green`, `blue` or `alpha`.
* @returns {Sharp}
* @throws {Error} Invalid channel
*/
function extractChannel (channel) {
const channelMap = { red: 0, green: 1, blue: 2, alpha: 3 };
if (Object.keys(channelMap).includes(channel)) {
channel = channelMap[channel];
}
if (is.integer(channel) && is.inRange(channel, 0, 4)) {
this.options.extractChannel = channel;
} else {
throw is.invalidParameterError('channel', 'integer or one of: red, green, blue, alpha', channel);
}
return this;
}
/**
* Join one or more channels to the image.
* The meaning of the added channels depends on the output colourspace, set with `toColourspace()`.
* By default the output image will be web-friendly sRGB, with additional channels interpreted as alpha channels.
* Channel ordering follows vips convention:
* - sRGB: 0: Red, 1: Green, 2: Blue, 3: Alpha.
* - CMYK: 0: Magenta, 1: Cyan, 2: Yellow, 3: Black, 4: Alpha.
*
* Buffers may be any of the image formats supported by sharp.
* For raw pixel input, the `options` object should contain a `raw` attribute, which follows the format of the attribute of the same name in the `sharp()` constructor.
*
* @param {Array<string|Buffer>|string|Buffer} images - one or more images (file paths, Buffers).
* @param {Object} options - image options, see `sharp()` constructor.
* @returns {Sharp}
* @throws {Error} Invalid parameters
*/
function joinChannel (images, options) {
if (Array.isArray(images)) {
images.forEach(function (image) {
this.options.joinChannelIn.push(this._createInputDescriptor(image, options));
}, this);
} else {
this.options.joinChannelIn.push(this._createInputDescriptor(images, options));
}
return this;
}
/**
* Perform a bitwise boolean operation on all input image channels (bands) to produce a single channel output image.
*
* @example
* sharp('3-channel-rgb-input.png')
* .bandbool(sharp.bool.and)
* .toFile('1-channel-output.png', function (err, info) {
* // The output will be a single channel image where each pixel `P = R & G & B`.
* // If `I(1,1) = [247, 170, 14] = [0b11110111, 0b10101010, 0b00001111]`
* // then `O(1,1) = 0b11110111 & 0b10101010 & 0b00001111 = 0b00000010 = 2`.
* });
*
* @param {string} boolOp - one of `and`, `or` or `eor` to perform that bitwise operation, like the C logic operators `&`, `|` and `^` respectively.
* @returns {Sharp}
* @throws {Error} Invalid parameters
*/
function bandbool (boolOp) {
if (is.string(boolOp) && is.inArray(boolOp, ['and', 'or', 'eor'])) {
this.options.bandBoolOp = boolOp;
} else {
throw is.invalidParameterError('boolOp', 'one of: and, or, eor', boolOp);
}
return this;
}
/**
* Decorate the Sharp prototype with channel-related functions.
* @private
*/
module.exports = function (Sharp) {
Object.assign(Sharp.prototype, {
// Public instance functions
removeAlpha,
ensureAlpha,
extractChannel,
joinChannel,
bandbool
});
// Class attributes
Sharp.bool = bool;
};
+184
View File
@@ -0,0 +1,184 @@
// Copyright 2013 Lovell Fuller and others.
// SPDX-License-Identifier: Apache-2.0
'use strict';
const color = require('color');
const is = require('./is');
/**
* Colourspaces.
* @private
*/
const colourspace = {
multiband: 'multiband',
'b-w': 'b-w',
bw: 'b-w',
cmyk: 'cmyk',
srgb: 'srgb'
};
/**
* Tint the image using the provided chroma while preserving the image luminance.
* An alpha channel may be present and will be unchanged by the operation.
*
* @example
* const output = await sharp(input)
* .tint({ r: 255, g: 240, b: 16 })
* .toBuffer();
*
* @param {string|Object} rgb - parsed by the [color](https://www.npmjs.org/package/color) module to extract chroma values.
* @returns {Sharp}
* @throws {Error} Invalid parameter
*/
function tint (rgb) {
const colour = color(rgb);
this.options.tintA = colour.a();
this.options.tintB = colour.b();
return this;
}
/**
* Convert to 8-bit greyscale; 256 shades of grey.
* This is a linear operation. If the input image is in a non-linear colour space such as sRGB, use `gamma()` with `greyscale()` for the best results.
* By default the output image will be web-friendly sRGB and contain three (identical) color channels.
* This may be overridden by other sharp operations such as `toColourspace('b-w')`,
* which will produce an output image containing one color channel.
* An alpha channel may be present, and will be unchanged by the operation.
*
* @example
* const output = await sharp(input).greyscale().toBuffer();
*
* @param {Boolean} [greyscale=true]
* @returns {Sharp}
*/
function greyscale (greyscale) {
this.options.greyscale = is.bool(greyscale) ? greyscale : true;
return this;
}
/**
* Alternative spelling of `greyscale`.
* @param {Boolean} [grayscale=true]
* @returns {Sharp}
*/
function grayscale (grayscale) {
return this.greyscale(grayscale);
}
/**
* Set the pipeline colourspace.
*
* The input image will be converted to the provided colourspace at the start of the pipeline.
* All operations will use this colourspace before converting to the output colourspace,
* as defined by {@link #tocolourspace|toColourspace}.
*
* This feature is experimental and has not yet been fully-tested with all operations.
*
* @since 0.29.0
*
* @example
* // Run pipeline in 16 bits per channel RGB while converting final result to 8 bits per channel sRGB.
* await sharp(input)
* .pipelineColourspace('rgb16')
* .toColourspace('srgb')
* .toFile('16bpc-pipeline-to-8bpc-output.png')
*
* @param {string} [colourspace] - pipeline colourspace e.g. `rgb16`, `scrgb`, `lab`, `grey16` [...](https://github.com/libvips/libvips/blob/41cff4e9d0838498487a00623462204eb10ee5b8/libvips/iofuncs/enumtypes.c#L774)
* @returns {Sharp}
* @throws {Error} Invalid parameters
*/
function pipelineColourspace (colourspace) {
if (!is.string(colourspace)) {
throw is.invalidParameterError('colourspace', 'string', colourspace);
}
this.options.colourspaceInput = colourspace;
return this;
}
/**
* Alternative spelling of `pipelineColourspace`.
* @param {string} [colorspace] - pipeline colorspace.
* @returns {Sharp}
* @throws {Error} Invalid parameters
*/
function pipelineColorspace (colorspace) {
return this.pipelineColourspace(colorspace);
}
/**
* Set the output colourspace.
* By default output image will be web-friendly sRGB, with additional channels interpreted as alpha channels.
*
* @example
* // Output 16 bits per pixel RGB
* await sharp(input)
* .toColourspace('rgb16')
* .toFile('16-bpp.png')
*
* @param {string} [colourspace] - output colourspace e.g. `srgb`, `rgb`, `cmyk`, `lab`, `b-w` [...](https://github.com/libvips/libvips/blob/3c0bfdf74ce1dc37a6429bed47fa76f16e2cd70a/libvips/iofuncs/enumtypes.c#L777-L794)
* @returns {Sharp}
* @throws {Error} Invalid parameters
*/
function toColourspace (colourspace) {
if (!is.string(colourspace)) {
throw is.invalidParameterError('colourspace', 'string', colourspace);
}
this.options.colourspace = colourspace;
return this;
}
/**
* Alternative spelling of `toColourspace`.
* @param {string} [colorspace] - output colorspace.
* @returns {Sharp}
* @throws {Error} Invalid parameters
*/
function toColorspace (colorspace) {
return this.toColourspace(colorspace);
}
/**
* Update a colour attribute of the this.options Object.
* @private
* @param {string} key
* @param {string|Object} value
* @throws {Error} Invalid value
*/
function _setBackgroundColourOption (key, value) {
if (is.defined(value)) {
if (is.object(value) || is.string(value)) {
const colour = color(value);
this.options[key] = [
colour.red(),
colour.green(),
colour.blue(),
Math.round(colour.alpha() * 255)
];
} else {
throw is.invalidParameterError('background', 'object or string', value);
}
}
}
/**
* Decorate the Sharp prototype with colour-related functions.
* @private
*/
module.exports = function (Sharp) {
Object.assign(Sharp.prototype, {
// Public
tint,
greyscale,
grayscale,
pipelineColourspace,
pipelineColorspace,
toColourspace,
toColorspace,
// Private
_setBackgroundColourOption
});
// Class attributes
Sharp.colourspace = colourspace;
Sharp.colorspace = colourspace;
};
+210
View File
@@ -0,0 +1,210 @@
// Copyright 2013 Lovell Fuller and others.
// SPDX-License-Identifier: Apache-2.0
'use strict';
const is = require('./is');
/**
* Blend modes.
* @member
* @private
*/
const blend = {
clear: 'clear',
source: 'source',
over: 'over',
in: 'in',
out: 'out',
atop: 'atop',
dest: 'dest',
'dest-over': 'dest-over',
'dest-in': 'dest-in',
'dest-out': 'dest-out',
'dest-atop': 'dest-atop',
xor: 'xor',
add: 'add',
saturate: 'saturate',
multiply: 'multiply',
screen: 'screen',
overlay: 'overlay',
darken: 'darken',
lighten: 'lighten',
'colour-dodge': 'colour-dodge',
'color-dodge': 'colour-dodge',
'colour-burn': 'colour-burn',
'color-burn': 'colour-burn',
'hard-light': 'hard-light',
'soft-light': 'soft-light',
difference: 'difference',
exclusion: 'exclusion'
};
/**
* Composite image(s) over the processed (resized, extracted etc.) image.
*
* The images to composite must be the same size or smaller than the processed image.
* If both `top` and `left` options are provided, they take precedence over `gravity`.
*
* Any resize, rotate or extract operations in the same processing pipeline
* will always be applied to the input image before composition.
*
* The `blend` option can be one of `clear`, `source`, `over`, `in`, `out`, `atop`,
* `dest`, `dest-over`, `dest-in`, `dest-out`, `dest-atop`,
* `xor`, `add`, `saturate`, `multiply`, `screen`, `overlay`, `darken`, `lighten`,
* `colour-dodge`, `color-dodge`, `colour-burn`,`color-burn`,
* `hard-light`, `soft-light`, `difference`, `exclusion`.
*
* More information about blend modes can be found at
* https://www.libvips.org/API/current/libvips-conversion.html#VipsBlendMode
* and https://www.cairographics.org/operators/
*
* @since 0.22.0
*
* @example
* await sharp(background)
* .composite([
* { input: layer1, gravity: 'northwest' },
* { input: layer2, gravity: 'southeast' },
* ])
* .toFile('combined.png');
*
* @example
* const output = await sharp('input.gif', { animated: true })
* .composite([
* { input: 'overlay.png', tile: true, blend: 'saturate' }
* ])
* .toBuffer();
*
* @example
* sharp('input.png')
* .rotate(180)
* .resize(300)
* .flatten( { background: '#ff6600' } )
* .composite([{ input: 'overlay.png', gravity: 'southeast' }])
* .sharpen()
* .withMetadata()
* .webp( { quality: 90 } )
* .toBuffer()
* .then(function(outputBuffer) {
* // outputBuffer contains upside down, 300px wide, alpha channel flattened
* // onto orange background, composited with overlay.png with SE gravity,
* // sharpened, with metadata, 90% quality WebP image data. Phew!
* });
*
* @param {Object[]} images - Ordered list of images to composite
* @param {Buffer|String} [images[].input] - Buffer containing image data, String containing the path to an image file, or Create object (see below)
* @param {Object} [images[].input.create] - describes a blank overlay to be created.
* @param {Number} [images[].input.create.width]
* @param {Number} [images[].input.create.height]
* @param {Number} [images[].input.create.channels] - 3-4
* @param {String|Object} [images[].input.create.background] - parsed by the [color](https://www.npmjs.org/package/color) module to extract values for red, green, blue and alpha.
* @param {Object} [images[].input.text] - describes a new text image to be created.
* @param {string} [images[].input.text.text] - text to render as a UTF-8 string. It can contain Pango markup, for example `<i>Le</i>Monde`.
* @param {string} [images[].input.text.font] - font name to render with.
* @param {string} [images[].input.text.fontfile] - absolute filesystem path to a font file that can be used by `font`.
* @param {number} [images[].input.text.width=0] - integral number of pixels to word-wrap at. Lines of text wider than this will be broken at word boundaries.
* @param {number} [images[].input.text.height=0] - integral number of pixels high. When defined, `dpi` will be ignored and the text will automatically fit the pixel resolution defined by `width` and `height`. Will be ignored if `width` is not specified or set to 0.
* @param {string} [images[].input.text.align='left'] - text alignment (`'left'`, `'centre'`, `'center'`, `'right'`).
* @param {boolean} [images[].input.text.justify=false] - set this to true to apply justification to the text.
* @param {number} [images[].input.text.dpi=72] - the resolution (size) at which to render the text. Does not take effect if `height` is specified.
* @param {boolean} [images[].input.text.rgba=false] - set this to true to enable RGBA output. This is useful for colour emoji rendering, or support for Pango markup features like `<span foreground="red">Red!</span>`.
* @param {number} [images[].input.text.spacing=0] - text line height in points. Will use the font line height if none is specified.
* @param {String} [images[].blend='over'] - how to blend this image with the image below.
* @param {String} [images[].gravity='centre'] - gravity at which to place the overlay.
* @param {Number} [images[].top] - the pixel offset from the top edge.
* @param {Number} [images[].left] - the pixel offset from the left edge.
* @param {Boolean} [images[].tile=false] - set to true to repeat the overlay image across the entire image with the given `gravity`.
* @param {Boolean} [images[].premultiplied=false] - set to true to avoid premultiplying the image below. Equivalent to the `--premultiplied` vips option.
* @param {Number} [images[].density=72] - number representing the DPI for vector overlay image.
* @param {Object} [images[].raw] - describes overlay when using raw pixel data.
* @param {Number} [images[].raw.width]
* @param {Number} [images[].raw.height]
* @param {Number} [images[].raw.channels]
* @param {boolean} [images[].animated=false] - Set to `true` to read all frames/pages of an animated image.
* @param {string} [images[].failOn='warning'] - @see {@link /api-constructor#parameters|constructor parameters}
* @param {number|boolean} [images[].limitInputPixels=268402689] - @see {@link /api-constructor#parameters|constructor parameters}
* @returns {Sharp}
* @throws {Error} Invalid parameters
*/
function composite (images) {
if (!Array.isArray(images)) {
throw is.invalidParameterError('images to composite', 'array', images);
}
this.options.composite = images.map(image => {
if (!is.object(image)) {
throw is.invalidParameterError('image to composite', 'object', image);
}
const inputOptions = this._inputOptionsFromObject(image);
const composite = {
input: this._createInputDescriptor(image.input, inputOptions, { allowStream: false }),
blend: 'over',
tile: false,
left: 0,
top: 0,
hasOffset: false,
gravity: 0,
premultiplied: false
};
if (is.defined(image.blend)) {
if (is.string(blend[image.blend])) {
composite.blend = blend[image.blend];
} else {
throw is.invalidParameterError('blend', 'valid blend name', image.blend);
}
}
if (is.defined(image.tile)) {
if (is.bool(image.tile)) {
composite.tile = image.tile;
} else {
throw is.invalidParameterError('tile', 'boolean', image.tile);
}
}
if (is.defined(image.left)) {
if (is.integer(image.left)) {
composite.left = image.left;
} else {
throw is.invalidParameterError('left', 'integer', image.left);
}
}
if (is.defined(image.top)) {
if (is.integer(image.top)) {
composite.top = image.top;
} else {
throw is.invalidParameterError('top', 'integer', image.top);
}
}
if (is.defined(image.top) !== is.defined(image.left)) {
throw new Error('Expected both left and top to be set');
} else {
composite.hasOffset = is.integer(image.top) && is.integer(image.left);
}
if (is.defined(image.gravity)) {
if (is.integer(image.gravity) && is.inRange(image.gravity, 0, 8)) {
composite.gravity = image.gravity;
} else if (is.string(image.gravity) && is.integer(this.constructor.gravity[image.gravity])) {
composite.gravity = this.constructor.gravity[image.gravity];
} else {
throw is.invalidParameterError('gravity', 'valid gravity', image.gravity);
}
}
if (is.defined(image.premultiplied)) {
if (is.bool(image.premultiplied)) {
composite.premultiplied = image.premultiplied;
} else {
throw is.invalidParameterError('premultiplied', 'boolean', image.premultiplied);
}
}
return composite;
});
return this;
}
/**
* Decorate the Sharp prototype with composite-related functions.
* @private
*/
module.exports = function (Sharp) {
Sharp.prototype.composite = composite;
Sharp.blend = blend;
};
+439
View File
@@ -0,0 +1,439 @@
// Copyright 2013 Lovell Fuller and others.
// SPDX-License-Identifier: Apache-2.0
'use strict';
const util = require('util');
const stream = require('stream');
const is = require('./is');
require('./libvips').hasVendoredLibvips();
require('./sharp');
// Use NODE_DEBUG=sharp to enable libvips warnings
const debuglog = util.debuglog('sharp');
/**
* Constructor factory to create an instance of `sharp`, to which further methods are chained.
*
* JPEG, PNG, WebP, GIF, AVIF or TIFF format image data can be streamed out from this object.
* When using Stream based output, derived attributes are available from the `info` event.
*
* Non-critical problems encountered during processing are emitted as `warning` events.
*
* Implements the [stream.Duplex](http://nodejs.org/api/stream.html#stream_class_stream_duplex) class.
*
* @constructs Sharp
*
* @emits Sharp#info
* @emits Sharp#warning
*
* @example
* sharp('input.jpg')
* .resize(300, 200)
* .toFile('output.jpg', function(err) {
* // output.jpg is a 300 pixels wide and 200 pixels high image
* // containing a scaled and cropped version of input.jpg
* });
*
* @example
* // Read image data from readableStream,
* // resize to 300 pixels wide,
* // emit an 'info' event with calculated dimensions
* // and finally write image data to writableStream
* var transformer = sharp()
* .resize(300)
* .on('info', function(info) {
* console.log('Image height is ' + info.height);
* });
* readableStream.pipe(transformer).pipe(writableStream);
*
* @example
* // Create a blank 300x200 PNG image of semi-translucent red pixels
* sharp({
* create: {
* width: 300,
* height: 200,
* channels: 4,
* background: { r: 255, g: 0, b: 0, alpha: 0.5 }
* }
* })
* .png()
* .toBuffer()
* .then( ... );
*
* @example
* // Convert an animated GIF to an animated WebP
* await sharp('in.gif', { animated: true }).toFile('out.webp');
*
* @example
* // Read a raw array of pixels and save it to a png
* const input = Uint8Array.from([255, 255, 255, 0, 0, 0]); // or Uint8ClampedArray
* const image = sharp(input, {
* // because the input does not contain its dimensions or how many channels it has
* // we need to specify it in the constructor options
* raw: {
* width: 2,
* height: 1,
* channels: 3
* }
* });
* await image.toFile('my-two-pixels.png');
*
* @example
* // Generate RGB Gaussian noise
* await sharp({
* create: {
* width: 300,
* height: 200,
* channels: 3,
* noise: {
* type: 'gaussian',
* mean: 128,
* sigma: 30
* }
* }
* }).toFile('noise.png');
*
* @example
* // Generate an image from text
* await sharp({
* text: {
* text: 'Hello, world!',
* width: 400, // max width
* height: 300 // max height
* }
* }).toFile('text_bw.png');
*
* @example
* // Generate an rgba image from text using pango markup and font
* await sharp({
* text: {
* text: '<span foreground="red">Red!</span><span background="cyan">blue</span>',
* font: 'sans',
* rgba: true,
* dpi: 300
* }
* }).toFile('text_rgba.png');
*
* @param {(Buffer|ArrayBuffer|Uint8Array|Uint8ClampedArray|Int8Array|Uint16Array|Int16Array|Uint32Array|Int32Array|Float32Array|Float64Array|string)} [input] - if present, can be
* a Buffer / ArrayBuffer / Uint8Array / Uint8ClampedArray containing JPEG, PNG, WebP, AVIF, GIF, SVG or TIFF image data, or
* a TypedArray containing raw pixel image data, or
* a String containing the filesystem path to an JPEG, PNG, WebP, AVIF, GIF, SVG or TIFF image file.
* JPEG, PNG, WebP, AVIF, GIF, SVG, TIFF or raw pixel image data can be streamed into the object when not present.
* @param {Object} [options] - if present, is an Object with optional attributes.
* @param {string} [options.failOn='warning'] - when to abort processing of invalid pixel data, one of (in order of sensitivity): 'none' (least), 'truncated', 'error' or 'warning' (most), higher levels imply lower levels, invalid metadata will always abort.
* @param {number|boolean} [options.limitInputPixels=268402689] - Do not process input images where the number of pixels
* (width x height) exceeds this limit. Assumes image dimensions contained in the input metadata can be trusted.
* An integral Number of pixels, zero or false to remove limit, true to use default limit of 268402689 (0x3FFF x 0x3FFF).
* @param {boolean} [options.unlimited=false] - Set this to `true` to remove safety features that help prevent memory exhaustion (JPEG, PNG, SVG, HEIF).
* @param {boolean} [options.sequentialRead=true] - Set this to `false` to use random access rather than sequential read. Some operations will do this automatically.
* @param {number} [options.density=72] - number representing the DPI for vector images in the range 1 to 100000.
* @param {number} [options.ignoreIcc=false] - should the embedded ICC profile, if any, be ignored.
* @param {number} [options.pages=1] - Number of pages to extract for multi-page input (GIF, WebP, TIFF), use -1 for all pages.
* @param {number} [options.page=0] - Page number to start extracting from for multi-page input (GIF, WebP, TIFF), zero based.
* @param {number} [options.subifd=-1] - subIFD (Sub Image File Directory) to extract for OME-TIFF, defaults to main image.
* @param {number} [options.level=0] - level to extract from a multi-level input (OpenSlide), zero based.
* @param {boolean} [options.animated=false] - Set to `true` to read all frames/pages of an animated image (GIF, WebP, TIFF), equivalent of setting `pages` to `-1`.
* @param {Object} [options.raw] - describes raw pixel input image data. See `raw()` for pixel ordering.
* @param {number} [options.raw.width] - integral number of pixels wide.
* @param {number} [options.raw.height] - integral number of pixels high.
* @param {number} [options.raw.channels] - integral number of channels, between 1 and 4.
* @param {boolean} [options.raw.premultiplied] - specifies that the raw input has already been premultiplied, set to `true`
* to avoid sharp premultiplying the image. (optional, default `false`)
* @param {Object} [options.create] - describes a new image to be created.
* @param {number} [options.create.width] - integral number of pixels wide.
* @param {number} [options.create.height] - integral number of pixels high.
* @param {number} [options.create.channels] - integral number of channels, either 3 (RGB) or 4 (RGBA).
* @param {string|Object} [options.create.background] - parsed by the [color](https://www.npmjs.org/package/color) module to extract values for red, green, blue and alpha.
* @param {Object} [options.create.noise] - describes a noise to be created.
* @param {string} [options.create.noise.type] - type of generated noise, currently only `gaussian` is supported.
* @param {number} [options.create.noise.mean] - mean of pixels in generated noise.
* @param {number} [options.create.noise.sigma] - standard deviation of pixels in generated noise.
* @param {Object} [options.text] - describes a new text image to be created.
* @param {string} [options.text.text] - text to render as a UTF-8 string. It can contain Pango markup, for example `<i>Le</i>Monde`.
* @param {string} [options.text.font] - font name to render with.
* @param {string} [options.text.fontfile] - absolute filesystem path to a font file that can be used by `font`.
* @param {number} [options.text.width=0] - Integral number of pixels to word-wrap at. Lines of text wider than this will be broken at word boundaries.
* @param {number} [options.text.height=0] - Maximum integral number of pixels high. When defined, `dpi` will be ignored and the text will automatically fit the pixel resolution defined by `width` and `height`. Will be ignored if `width` is not specified or set to 0.
* @param {string} [options.text.align='left'] - Alignment style for multi-line text (`'left'`, `'centre'`, `'center'`, `'right'`).
* @param {boolean} [options.text.justify=false] - set this to true to apply justification to the text.
* @param {number} [options.text.dpi=72] - the resolution (size) at which to render the text. Does not take effect if `height` is specified.
* @param {boolean} [options.text.rgba=false] - set this to true to enable RGBA output. This is useful for colour emoji rendering, or support for pango markup features like `<span foreground="red">Red!</span>`.
* @param {number} [options.text.spacing=0] - text line height in points. Will use the font line height if none is specified.
* @param {string} [options.text.wrap='word'] - word wrapping style when width is provided, one of: 'word', 'char', 'charWord' (prefer char, fallback to word) or 'none'.
* @returns {Sharp}
* @throws {Error} Invalid parameters
*/
const Sharp = function (input, options) {
if (arguments.length === 1 && !is.defined(input)) {
throw new Error('Invalid input');
}
if (!(this instanceof Sharp)) {
return new Sharp(input, options);
}
stream.Duplex.call(this);
this.options = {
// resize options
topOffsetPre: -1,
leftOffsetPre: -1,
widthPre: -1,
heightPre: -1,
topOffsetPost: -1,
leftOffsetPost: -1,
widthPost: -1,
heightPost: -1,
width: -1,
height: -1,
canvas: 'crop',
position: 0,
resizeBackground: [0, 0, 0, 255],
useExifOrientation: false,
angle: 0,
rotationAngle: 0,
rotationBackground: [0, 0, 0, 255],
rotateBeforePreExtract: false,
flip: false,
flop: false,
extendTop: 0,
extendBottom: 0,
extendLeft: 0,
extendRight: 0,
extendBackground: [0, 0, 0, 255],
extendWith: 'background',
withoutEnlargement: false,
withoutReduction: false,
affineMatrix: [],
affineBackground: [0, 0, 0, 255],
affineIdx: 0,
affineIdy: 0,
affineOdx: 0,
affineOdy: 0,
affineInterpolator: this.constructor.interpolators.bilinear,
kernel: 'lanczos3',
fastShrinkOnLoad: true,
// operations
tintA: 128,
tintB: 128,
flatten: false,
flattenBackground: [0, 0, 0],
unflatten: false,
negate: false,
negateAlpha: true,
medianSize: 0,
blurSigma: 0,
sharpenSigma: 0,
sharpenM1: 1,
sharpenM2: 2,
sharpenX1: 2,
sharpenY2: 10,
sharpenY3: 20,
threshold: 0,
thresholdGrayscale: true,
trimBackground: [],
trimThreshold: 0,
gamma: 0,
gammaOut: 0,
greyscale: false,
normalise: false,
normaliseLower: 1,
normaliseUpper: 99,
claheWidth: 0,
claheHeight: 0,
claheMaxSlope: 3,
brightness: 1,
saturation: 1,
hue: 0,
lightness: 0,
booleanBufferIn: null,
booleanFileIn: '',
joinChannelIn: [],
extractChannel: -1,
removeAlpha: false,
ensureAlpha: -1,
colourspace: 'srgb',
colourspaceInput: 'last',
composite: [],
// output
fileOut: '',
formatOut: 'input',
streamOut: false,
withMetadata: false,
withMetadataOrientation: -1,
withMetadataDensity: 0,
withMetadataIcc: '',
withMetadataStrs: {},
resolveWithObject: false,
// output format
jpegQuality: 80,
jpegProgressive: false,
jpegChromaSubsampling: '4:2:0',
jpegTrellisQuantisation: false,
jpegOvershootDeringing: false,
jpegOptimiseScans: false,
jpegOptimiseCoding: true,
jpegQuantisationTable: 0,
pngProgressive: false,
pngCompressionLevel: 6,
pngAdaptiveFiltering: false,
pngPalette: false,
pngQuality: 100,
pngEffort: 7,
pngBitdepth: 8,
pngDither: 1,
jp2Quality: 80,
jp2TileHeight: 512,
jp2TileWidth: 512,
jp2Lossless: false,
jp2ChromaSubsampling: '4:4:4',
webpQuality: 80,
webpAlphaQuality: 100,
webpLossless: false,
webpNearLossless: false,
webpSmartSubsample: false,
webpPreset: 'default',
webpEffort: 4,
webpMinSize: false,
webpMixed: false,
gifBitdepth: 8,
gifEffort: 7,
gifDither: 1,
gifInterFrameMaxError: 0,
gifInterPaletteMaxError: 3,
gifReuse: true,
gifProgressive: false,
tiffQuality: 80,
tiffCompression: 'jpeg',
tiffPredictor: 'horizontal',
tiffPyramid: false,
tiffBitdepth: 8,
tiffTile: false,
tiffTileHeight: 256,
tiffTileWidth: 256,
tiffXres: 1.0,
tiffYres: 1.0,
tiffResolutionUnit: 'inch',
heifQuality: 50,
heifLossless: false,
heifCompression: 'av1',
heifEffort: 4,
heifChromaSubsampling: '4:4:4',
jxlDistance: 1,
jxlDecodingTier: 0,
jxlEffort: 7,
jxlLossless: false,
rawDepth: 'uchar',
tileSize: 256,
tileOverlap: 0,
tileContainer: 'fs',
tileLayout: 'dz',
tileFormat: 'last',
tileDepth: 'last',
tileAngle: 0,
tileSkipBlanks: -1,
tileBackground: [255, 255, 255, 255],
tileCentre: false,
tileId: 'https://example.com/iiif',
tileBasename: '',
timeoutSeconds: 0,
linearA: [],
linearB: [],
// Function to notify of libvips warnings
debuglog: warning => {
this.emit('warning', warning);
debuglog(warning);
},
// Function to notify of queue length changes
queueListener: function (queueLength) {
Sharp.queue.emit('change', queueLength);
}
};
this.options.input = this._createInputDescriptor(input, options, { allowStream: true });
return this;
};
Object.setPrototypeOf(Sharp.prototype, stream.Duplex.prototype);
Object.setPrototypeOf(Sharp, stream.Duplex);
/**
* Take a "snapshot" of the Sharp instance, returning a new instance.
* Cloned instances inherit the input of their parent instance.
* This allows multiple output Streams and therefore multiple processing pipelines to share a single input Stream.
*
* @example
* const pipeline = sharp().rotate();
* pipeline.clone().resize(800, 600).pipe(firstWritableStream);
* pipeline.clone().extract({ left: 20, top: 20, width: 100, height: 100 }).pipe(secondWritableStream);
* readableStream.pipe(pipeline);
* // firstWritableStream receives auto-rotated, resized readableStream
* // secondWritableStream receives auto-rotated, extracted region of readableStream
*
* @example
* // Create a pipeline that will download an image, resize it and format it to different files
* // Using Promises to know when the pipeline is complete
* const fs = require("fs");
* const got = require("got");
* const sharpStream = sharp({ failOn: 'none' });
*
* const promises = [];
*
* promises.push(
* sharpStream
* .clone()
* .jpeg({ quality: 100 })
* .toFile("originalFile.jpg")
* );
*
* promises.push(
* sharpStream
* .clone()
* .resize({ width: 500 })
* .jpeg({ quality: 80 })
* .toFile("optimized-500.jpg")
* );
*
* promises.push(
* sharpStream
* .clone()
* .resize({ width: 500 })
* .webp({ quality: 80 })
* .toFile("optimized-500.webp")
* );
*
* // https://github.com/sindresorhus/got/blob/main/documentation/3-streams.md
* got.stream("https://www.example.com/some-file.jpg").pipe(sharpStream);
*
* Promise.all(promises)
* .then(res => { console.log("Done!", res); })
* .catch(err => {
* console.error("Error processing files, let's clean it up", err);
* try {
* fs.unlinkSync("originalFile.jpg");
* fs.unlinkSync("optimized-500.jpg");
* fs.unlinkSync("optimized-500.webp");
* } catch (e) {}
* });
*
* @returns {Sharp}
*/
function clone () {
// Clone existing options
const clone = this.constructor.call();
clone.options = Object.assign({}, this.options);
// Pass 'finish' event to clone for Stream-based input
if (this._isStreamInput()) {
this.on('finish', () => {
// Clone inherits input data
this._flattenBufferIn();
clone.options.bufferIn = this.options.bufferIn;
clone.emit('finish');
});
}
return clone;
}
Object.assign(Sharp.prototype, { clone });
/**
* Export constructor.
* @private
*/
module.exports = Sharp;
+1661
View File
File diff suppressed because it is too large Load Diff
+16
View File
@@ -0,0 +1,16 @@
// Copyright 2013 Lovell Fuller and others.
// SPDX-License-Identifier: Apache-2.0
'use strict';
const Sharp = require('./constructor');
require('./input')(Sharp);
require('./resize')(Sharp);
require('./composite')(Sharp);
require('./operation')(Sharp);
require('./colour')(Sharp);
require('./channel')(Sharp);
require('./output')(Sharp);
require('./utility')(Sharp);
module.exports = Sharp;
+631
View File
@@ -0,0 +1,631 @@
// Copyright 2013 Lovell Fuller and others.
// SPDX-License-Identifier: Apache-2.0
'use strict';
const color = require('color');
const is = require('./is');
const sharp = require('./sharp');
/**
* Justication alignment
* @member
* @private
*/
const align = {
left: 'low',
center: 'centre',
centre: 'centre',
right: 'high'
};
/**
* Extract input options, if any, from an object.
* @private
*/
function _inputOptionsFromObject (obj) {
const { raw, density, limitInputPixels, ignoreIcc, unlimited, sequentialRead, failOn, failOnError, animated, page, pages, subifd } = obj;
return [raw, density, limitInputPixels, ignoreIcc, unlimited, sequentialRead, failOn, failOnError, animated, page, pages, subifd].some(is.defined)
? { raw, density, limitInputPixels, ignoreIcc, unlimited, sequentialRead, failOn, failOnError, animated, page, pages, subifd }
: undefined;
}
/**
* Create Object containing input and input-related options.
* @private
*/
function _createInputDescriptor (input, inputOptions, containerOptions) {
const inputDescriptor = {
failOn: 'warning',
limitInputPixels: Math.pow(0x3FFF, 2),
ignoreIcc: false,
unlimited: false,
sequentialRead: true
};
if (is.string(input)) {
// filesystem
inputDescriptor.file = input;
} else if (is.buffer(input)) {
// Buffer
if (input.length === 0) {
throw Error('Input Buffer is empty');
}
inputDescriptor.buffer = input;
} else if (is.arrayBuffer(input)) {
if (input.byteLength === 0) {
throw Error('Input bit Array is empty');
}
inputDescriptor.buffer = Buffer.from(input, 0, input.byteLength);
} else if (is.typedArray(input)) {
if (input.length === 0) {
throw Error('Input Bit Array is empty');
}
inputDescriptor.buffer = Buffer.from(input.buffer, input.byteOffset, input.byteLength);
} else if (is.plainObject(input) && !is.defined(inputOptions)) {
// Plain Object descriptor, e.g. create
inputOptions = input;
if (_inputOptionsFromObject(inputOptions)) {
// Stream with options
inputDescriptor.buffer = [];
}
} else if (!is.defined(input) && !is.defined(inputOptions) && is.object(containerOptions) && containerOptions.allowStream) {
// Stream without options
inputDescriptor.buffer = [];
} else {
throw new Error(`Unsupported input '${input}' of type ${typeof input}${
is.defined(inputOptions) ? ` when also providing options of type ${typeof inputOptions}` : ''
}`);
}
if (is.object(inputOptions)) {
// Deprecated: failOnError
if (is.defined(inputOptions.failOnError)) {
if (is.bool(inputOptions.failOnError)) {
inputDescriptor.failOn = inputOptions.failOnError ? 'warning' : 'none';
} else {
throw is.invalidParameterError('failOnError', 'boolean', inputOptions.failOnError);
}
}
// failOn
if (is.defined(inputOptions.failOn)) {
if (is.string(inputOptions.failOn) && is.inArray(inputOptions.failOn, ['none', 'truncated', 'error', 'warning'])) {
inputDescriptor.failOn = inputOptions.failOn;
} else {
throw is.invalidParameterError('failOn', 'one of: none, truncated, error, warning', inputOptions.failOn);
}
}
// Density
if (is.defined(inputOptions.density)) {
if (is.inRange(inputOptions.density, 1, 100000)) {
inputDescriptor.density = inputOptions.density;
} else {
throw is.invalidParameterError('density', 'number between 1 and 100000', inputOptions.density);
}
}
// Ignore embeddded ICC profile
if (is.defined(inputOptions.ignoreIcc)) {
if (is.bool(inputOptions.ignoreIcc)) {
inputDescriptor.ignoreIcc = inputOptions.ignoreIcc;
} else {
throw is.invalidParameterError('ignoreIcc', 'boolean', inputOptions.ignoreIcc);
}
}
// limitInputPixels
if (is.defined(inputOptions.limitInputPixels)) {
if (is.bool(inputOptions.limitInputPixels)) {
inputDescriptor.limitInputPixels = inputOptions.limitInputPixels
? Math.pow(0x3FFF, 2)
: 0;
} else if (is.integer(inputOptions.limitInputPixels) && is.inRange(inputOptions.limitInputPixels, 0, Number.MAX_SAFE_INTEGER)) {
inputDescriptor.limitInputPixels = inputOptions.limitInputPixels;
} else {
throw is.invalidParameterError('limitInputPixels', 'positive integer', inputOptions.limitInputPixels);
}
}
// unlimited
if (is.defined(inputOptions.unlimited)) {
if (is.bool(inputOptions.unlimited)) {
inputDescriptor.unlimited = inputOptions.unlimited;
} else {
throw is.invalidParameterError('unlimited', 'boolean', inputOptions.unlimited);
}
}
// sequentialRead
if (is.defined(inputOptions.sequentialRead)) {
if (is.bool(inputOptions.sequentialRead)) {
inputDescriptor.sequentialRead = inputOptions.sequentialRead;
} else {
throw is.invalidParameterError('sequentialRead', 'boolean', inputOptions.sequentialRead);
}
}
// Raw pixel input
if (is.defined(inputOptions.raw)) {
if (
is.object(inputOptions.raw) &&
is.integer(inputOptions.raw.width) && inputOptions.raw.width > 0 &&
is.integer(inputOptions.raw.height) && inputOptions.raw.height > 0 &&
is.integer(inputOptions.raw.channels) && is.inRange(inputOptions.raw.channels, 1, 4)
) {
inputDescriptor.rawWidth = inputOptions.raw.width;
inputDescriptor.rawHeight = inputOptions.raw.height;
inputDescriptor.rawChannels = inputOptions.raw.channels;
inputDescriptor.rawPremultiplied = !!inputOptions.raw.premultiplied;
switch (input.constructor) {
case Uint8Array:
case Uint8ClampedArray:
inputDescriptor.rawDepth = 'uchar';
break;
case Int8Array:
inputDescriptor.rawDepth = 'char';
break;
case Uint16Array:
inputDescriptor.rawDepth = 'ushort';
break;
case Int16Array:
inputDescriptor.rawDepth = 'short';
break;
case Uint32Array:
inputDescriptor.rawDepth = 'uint';
break;
case Int32Array:
inputDescriptor.rawDepth = 'int';
break;
case Float32Array:
inputDescriptor.rawDepth = 'float';
break;
case Float64Array:
inputDescriptor.rawDepth = 'double';
break;
default:
inputDescriptor.rawDepth = 'uchar';
break;
}
} else {
throw new Error('Expected width, height and channels for raw pixel input');
}
}
// Multi-page input (GIF, TIFF, PDF)
if (is.defined(inputOptions.animated)) {
if (is.bool(inputOptions.animated)) {
inputDescriptor.pages = inputOptions.animated ? -1 : 1;
} else {
throw is.invalidParameterError('animated', 'boolean', inputOptions.animated);
}
}
if (is.defined(inputOptions.pages)) {
if (is.integer(inputOptions.pages) && is.inRange(inputOptions.pages, -1, 100000)) {
inputDescriptor.pages = inputOptions.pages;
} else {
throw is.invalidParameterError('pages', 'integer between -1 and 100000', inputOptions.pages);
}
}
if (is.defined(inputOptions.page)) {
if (is.integer(inputOptions.page) && is.inRange(inputOptions.page, 0, 100000)) {
inputDescriptor.page = inputOptions.page;
} else {
throw is.invalidParameterError('page', 'integer between 0 and 100000', inputOptions.page);
}
}
// Multi-level input (OpenSlide)
if (is.defined(inputOptions.level)) {
if (is.integer(inputOptions.level) && is.inRange(inputOptions.level, 0, 256)) {
inputDescriptor.level = inputOptions.level;
} else {
throw is.invalidParameterError('level', 'integer between 0 and 256', inputOptions.level);
}
}
// Sub Image File Directory (TIFF)
if (is.defined(inputOptions.subifd)) {
if (is.integer(inputOptions.subifd) && is.inRange(inputOptions.subifd, -1, 100000)) {
inputDescriptor.subifd = inputOptions.subifd;
} else {
throw is.invalidParameterError('subifd', 'integer between -1 and 100000', inputOptions.subifd);
}
}
// Create new image
if (is.defined(inputOptions.create)) {
if (
is.object(inputOptions.create) &&
is.integer(inputOptions.create.width) && inputOptions.create.width > 0 &&
is.integer(inputOptions.create.height) && inputOptions.create.height > 0 &&
is.integer(inputOptions.create.channels)
) {
inputDescriptor.createWidth = inputOptions.create.width;
inputDescriptor.createHeight = inputOptions.create.height;
inputDescriptor.createChannels = inputOptions.create.channels;
// Noise
if (is.defined(inputOptions.create.noise)) {
if (!is.object(inputOptions.create.noise)) {
throw new Error('Expected noise to be an object');
}
if (!is.inArray(inputOptions.create.noise.type, ['gaussian'])) {
throw new Error('Only gaussian noise is supported at the moment');
}
if (!is.inRange(inputOptions.create.channels, 1, 4)) {
throw is.invalidParameterError('create.channels', 'number between 1 and 4', inputOptions.create.channels);
}
inputDescriptor.createNoiseType = inputOptions.create.noise.type;
if (is.number(inputOptions.create.noise.mean) && is.inRange(inputOptions.create.noise.mean, 0, 10000)) {
inputDescriptor.createNoiseMean = inputOptions.create.noise.mean;
} else {
throw is.invalidParameterError('create.noise.mean', 'number between 0 and 10000', inputOptions.create.noise.mean);
}
if (is.number(inputOptions.create.noise.sigma) && is.inRange(inputOptions.create.noise.sigma, 0, 10000)) {
inputDescriptor.createNoiseSigma = inputOptions.create.noise.sigma;
} else {
throw is.invalidParameterError('create.noise.sigma', 'number between 0 and 10000', inputOptions.create.noise.sigma);
}
} else if (is.defined(inputOptions.create.background)) {
if (!is.inRange(inputOptions.create.channels, 3, 4)) {
throw is.invalidParameterError('create.channels', 'number between 3 and 4', inputOptions.create.channels);
}
const background = color(inputOptions.create.background);
inputDescriptor.createBackground = [
background.red(),
background.green(),
background.blue(),
Math.round(background.alpha() * 255)
];
} else {
throw new Error('Expected valid noise or background to create a new input image');
}
delete inputDescriptor.buffer;
} else {
throw new Error('Expected valid width, height and channels to create a new input image');
}
}
// Create a new image with text
if (is.defined(inputOptions.text)) {
if (is.object(inputOptions.text) && is.string(inputOptions.text.text)) {
inputDescriptor.textValue = inputOptions.text.text;
if (is.defined(inputOptions.text.height) && is.defined(inputOptions.text.dpi)) {
throw new Error('Expected only one of dpi or height');
}
if (is.defined(inputOptions.text.font)) {
if (is.string(inputOptions.text.font)) {
inputDescriptor.textFont = inputOptions.text.font;
} else {
throw is.invalidParameterError('text.font', 'string', inputOptions.text.font);
}
}
if (is.defined(inputOptions.text.fontfile)) {
if (is.string(inputOptions.text.fontfile)) {
inputDescriptor.textFontfile = inputOptions.text.fontfile;
} else {
throw is.invalidParameterError('text.fontfile', 'string', inputOptions.text.fontfile);
}
}
if (is.defined(inputOptions.text.width)) {
if (is.number(inputOptions.text.width)) {
inputDescriptor.textWidth = inputOptions.text.width;
} else {
throw is.invalidParameterError('text.textWidth', 'number', inputOptions.text.width);
}
}
if (is.defined(inputOptions.text.height)) {
if (is.number(inputOptions.text.height)) {
inputDescriptor.textHeight = inputOptions.text.height;
} else {
throw is.invalidParameterError('text.height', 'number', inputOptions.text.height);
}
}
if (is.defined(inputOptions.text.align)) {
if (is.string(inputOptions.text.align) && is.string(this.constructor.align[inputOptions.text.align])) {
inputDescriptor.textAlign = this.constructor.align[inputOptions.text.align];
} else {
throw is.invalidParameterError('text.align', 'valid alignment', inputOptions.text.align);
}
}
if (is.defined(inputOptions.text.justify)) {
if (is.bool(inputOptions.text.justify)) {
inputDescriptor.textJustify = inputOptions.text.justify;
} else {
throw is.invalidParameterError('text.justify', 'boolean', inputOptions.text.justify);
}
}
if (is.defined(inputOptions.text.dpi)) {
if (is.number(inputOptions.text.dpi) && is.inRange(inputOptions.text.dpi, 1, 100000)) {
inputDescriptor.textDpi = inputOptions.text.dpi;
} else {
throw is.invalidParameterError('text.dpi', 'number between 1 and 100000', inputOptions.text.dpi);
}
}
if (is.defined(inputOptions.text.rgba)) {
if (is.bool(inputOptions.text.rgba)) {
inputDescriptor.textRgba = inputOptions.text.rgba;
} else {
throw is.invalidParameterError('text.rgba', 'bool', inputOptions.text.rgba);
}
}
if (is.defined(inputOptions.text.spacing)) {
if (is.number(inputOptions.text.spacing)) {
inputDescriptor.textSpacing = inputOptions.text.spacing;
} else {
throw is.invalidParameterError('text.spacing', 'number', inputOptions.text.spacing);
}
}
if (is.defined(inputOptions.text.wrap)) {
if (is.string(inputOptions.text.wrap) && is.inArray(inputOptions.text.wrap, ['word', 'char', 'wordChar', 'none'])) {
inputDescriptor.textWrap = inputOptions.text.wrap;
} else {
throw is.invalidParameterError('text.wrap', 'one of: word, char, wordChar, none', inputOptions.text.wrap);
}
}
delete inputDescriptor.buffer;
} else {
throw new Error('Expected a valid string to create an image with text.');
}
}
} else if (is.defined(inputOptions)) {
throw new Error('Invalid input options ' + inputOptions);
}
return inputDescriptor;
}
/**
* Handle incoming Buffer chunk on Writable Stream.
* @private
* @param {Buffer} chunk
* @param {string} encoding - unused
* @param {Function} callback
*/
function _write (chunk, encoding, callback) {
/* istanbul ignore else */
if (Array.isArray(this.options.input.buffer)) {
/* istanbul ignore else */
if (is.buffer(chunk)) {
if (this.options.input.buffer.length === 0) {
this.on('finish', () => {
this.streamInFinished = true;
});
}
this.options.input.buffer.push(chunk);
callback();
} else {
callback(new Error('Non-Buffer data on Writable Stream'));
}
} else {
callback(new Error('Unexpected data on Writable Stream'));
}
}
/**
* Flattens the array of chunks accumulated in input.buffer.
* @private
*/
function _flattenBufferIn () {
if (this._isStreamInput()) {
this.options.input.buffer = Buffer.concat(this.options.input.buffer);
}
}
/**
* Are we expecting Stream-based input?
* @private
* @returns {boolean}
*/
function _isStreamInput () {
return Array.isArray(this.options.input.buffer);
}
/**
* Fast access to (uncached) image metadata without decoding any compressed pixel data.
*
* This is read from the header of the input image.
* It does not take into consideration any operations to be applied to the output image,
* such as resize or rotate.
*
* Dimensions in the response will respect the `page` and `pages` properties of the
* {@link /api-constructor#parameters|constructor parameters}.
*
* A `Promise` is returned when `callback` is not provided.
*
* - `format`: Name of decoder used to decompress image data e.g. `jpeg`, `png`, `webp`, `gif`, `svg`
* - `size`: Total size of image in bytes, for Stream and Buffer input only
* - `width`: Number of pixels wide (EXIF orientation is not taken into consideration, see example below)
* - `height`: Number of pixels high (EXIF orientation is not taken into consideration, see example below)
* - `space`: Name of colour space interpretation e.g. `srgb`, `rgb`, `cmyk`, `lab`, `b-w` [...](https://www.libvips.org/API/current/VipsImage.html#VipsInterpretation)
* - `channels`: Number of bands e.g. `3` for sRGB, `4` for CMYK
* - `depth`: Name of pixel depth format e.g. `uchar`, `char`, `ushort`, `float` [...](https://www.libvips.org/API/current/VipsImage.html#VipsBandFormat)
* - `density`: Number of pixels per inch (DPI), if present
* - `chromaSubsampling`: String containing JPEG chroma subsampling, `4:2:0` or `4:4:4` for RGB, `4:2:0:4` or `4:4:4:4` for CMYK
* - `isProgressive`: Boolean indicating whether the image is interlaced using a progressive scan
* - `pages`: Number of pages/frames contained within the image, with support for TIFF, HEIF, PDF, animated GIF and animated WebP
* - `pageHeight`: Number of pixels high each page in a multi-page image will be.
* - `paletteBitDepth`: Bit depth of palette-based image (GIF, PNG).
* - `loop`: Number of times to loop an animated image, zero refers to a continuous loop.
* - `delay`: Delay in ms between each page in an animated image, provided as an array of integers.
* - `pagePrimary`: Number of the primary page in a HEIF image
* - `levels`: Details of each level in a multi-level image provided as an array of objects, requires libvips compiled with support for OpenSlide
* - `subifds`: Number of Sub Image File Directories in an OME-TIFF image
* - `background`: Default background colour, if present, for PNG (bKGD) and GIF images, either an RGB Object or a single greyscale value
* - `compression`: The encoder used to compress an HEIF file, `av1` (AVIF) or `hevc` (HEIC)
* - `resolutionUnit`: The unit of resolution (density), either `inch` or `cm`, if present
* - `hasProfile`: Boolean indicating the presence of an embedded ICC profile
* - `hasAlpha`: Boolean indicating the presence of an alpha transparency channel
* - `orientation`: Number value of the EXIF Orientation header, if present
* - `exif`: Buffer containing raw EXIF data, if present
* - `icc`: Buffer containing raw [ICC](https://www.npmjs.com/package/icc) profile data, if present
* - `iptc`: Buffer containing raw IPTC data, if present
* - `xmp`: Buffer containing raw XMP data, if present
* - `tifftagPhotoshop`: Buffer containing raw TIFFTAG_PHOTOSHOP data, if present
* - `formatMagick`: String containing format for images loaded via *magick
*
* @example
* const metadata = await sharp(input).metadata();
*
* @example
* const image = sharp(inputJpg);
* image
* .metadata()
* .then(function(metadata) {
* return image
* .resize(Math.round(metadata.width / 2))
* .webp()
* .toBuffer();
* })
* .then(function(data) {
* // data contains a WebP image half the width and height of the original JPEG
* });
*
* @example
* // Based on EXIF rotation metadata, get the right-side-up width and height:
*
* const size = getNormalSize(await sharp(input).metadata());
*
* function getNormalSize({ width, height, orientation }) {
* return (orientation || 0) >= 5
* ? { width: height, height: width }
* : { width, height };
* }
*
* @param {Function} [callback] - called with the arguments `(err, metadata)`
* @returns {Promise<Object>|Sharp}
*/
function metadata (callback) {
if (is.fn(callback)) {
if (this._isStreamInput()) {
this.on('finish', () => {
this._flattenBufferIn();
sharp.metadata(this.options, callback);
});
} else {
sharp.metadata(this.options, callback);
}
return this;
} else {
if (this._isStreamInput()) {
return new Promise((resolve, reject) => {
const finished = () => {
this._flattenBufferIn();
sharp.metadata(this.options, (err, metadata) => {
if (err) {
reject(err);
} else {
resolve(metadata);
}
});
};
if (this.writableFinished) {
finished();
} else {
this.once('finish', finished);
}
});
} else {
return new Promise((resolve, reject) => {
sharp.metadata(this.options, (err, metadata) => {
if (err) {
reject(err);
} else {
resolve(metadata);
}
});
});
}
}
}
/**
* Access to pixel-derived image statistics for every channel in the image.
* A `Promise` is returned when `callback` is not provided.
*
* - `channels`: Array of channel statistics for each channel in the image. Each channel statistic contains
* - `min` (minimum value in the channel)
* - `max` (maximum value in the channel)
* - `sum` (sum of all values in a channel)
* - `squaresSum` (sum of squared values in a channel)
* - `mean` (mean of the values in a channel)
* - `stdev` (standard deviation for the values in a channel)
* - `minX` (x-coordinate of one of the pixel where the minimum lies)
* - `minY` (y-coordinate of one of the pixel where the minimum lies)
* - `maxX` (x-coordinate of one of the pixel where the maximum lies)
* - `maxY` (y-coordinate of one of the pixel where the maximum lies)
* - `isOpaque`: Is the image fully opaque? Will be `true` if the image has no alpha channel or if every pixel is fully opaque.
* - `entropy`: Histogram-based estimation of greyscale entropy, discarding alpha channel if any.
* - `sharpness`: Estimation of greyscale sharpness based on the standard deviation of a Laplacian convolution, discarding alpha channel if any.
* - `dominant`: Object containing most dominant sRGB colour based on a 4096-bin 3D histogram.
*
* **Note**: Statistics are derived from the original input image. Any operations performed on the image must first be
* written to a buffer in order to run `stats` on the result (see third example).
*
* @example
* const image = sharp(inputJpg);
* image
* .stats()
* .then(function(stats) {
* // stats contains the channel-wise statistics array and the isOpaque value
* });
*
* @example
* const { entropy, sharpness, dominant } = await sharp(input).stats();
* const { r, g, b } = dominant;
*
* @example
* const image = sharp(input);
* // store intermediate result
* const part = await image.extract(region).toBuffer();
* // create new instance to obtain statistics of extracted region
* const stats = await sharp(part).stats();
*
* @param {Function} [callback] - called with the arguments `(err, stats)`
* @returns {Promise<Object>}
*/
function stats (callback) {
if (is.fn(callback)) {
if (this._isStreamInput()) {
this.on('finish', () => {
this._flattenBufferIn();
sharp.stats(this.options, callback);
});
} else {
sharp.stats(this.options, callback);
}
return this;
} else {
if (this._isStreamInput()) {
return new Promise((resolve, reject) => {
this.on('finish', function () {
this._flattenBufferIn();
sharp.stats(this.options, (err, stats) => {
if (err) {
reject(err);
} else {
resolve(stats);
}
});
});
});
} else {
return new Promise((resolve, reject) => {
sharp.stats(this.options, (err, stats) => {
if (err) {
reject(err);
} else {
resolve(stats);
}
});
});
}
}
}
/**
* Decorate the Sharp prototype with input-related functions.
* @private
*/
module.exports = function (Sharp) {
Object.assign(Sharp.prototype, {
// Private
_inputOptionsFromObject,
_createInputDescriptor,
_write,
_flattenBufferIn,
_isStreamInput,
// Public
metadata,
stats
});
// Class attributes
Sharp.align = align;
};
+155
View File
@@ -0,0 +1,155 @@
// Copyright 2013 Lovell Fuller and others.
// SPDX-License-Identifier: Apache-2.0
'use strict';
/**
* Is this value defined and not null?
* @private
*/
const defined = function (val) {
return typeof val !== 'undefined' && val !== null;
};
/**
* Is this value an object?
* @private
*/
const object = function (val) {
return typeof val === 'object';
};
/**
* Is this value a plain object?
* @private
*/
const plainObject = function (val) {
return Object.prototype.toString.call(val) === '[object Object]';
};
/**
* Is this value a function?
* @private
*/
const fn = function (val) {
return typeof val === 'function';
};
/**
* Is this value a boolean?
* @private
*/
const bool = function (val) {
return typeof val === 'boolean';
};
/**
* Is this value a Buffer object?
* @private
*/
const buffer = function (val) {
return val instanceof Buffer;
};
/**
* Is this value a typed array object?. E.g. Uint8Array or Uint8ClampedArray?
* @private
*/
const typedArray = function (val) {
if (defined(val)) {
switch (val.constructor) {
case Uint8Array:
case Uint8ClampedArray:
case Int8Array:
case Uint16Array:
case Int16Array:
case Uint32Array:
case Int32Array:
case Float32Array:
case Float64Array:
return true;
}
}
return false;
};
/**
* Is this value an ArrayBuffer object?
* @private
*/
const arrayBuffer = function (val) {
return val instanceof ArrayBuffer;
};
/**
* Is this value a non-empty string?
* @private
*/
const string = function (val) {
return typeof val === 'string' && val.length > 0;
};
/**
* Is this value a real number?
* @private
*/
const number = function (val) {
return typeof val === 'number' && !Number.isNaN(val);
};
/**
* Is this value an integer?
* @private
*/
const integer = function (val) {
return Number.isInteger(val);
};
/**
* Is this value within an inclusive given range?
* @private
*/
const inRange = function (val, min, max) {
return val >= min && val <= max;
};
/**
* Is this value within the elements of an array?
* @private
*/
const inArray = function (val, list) {
return list.includes(val);
};
/**
* Create an Error with a message relating to an invalid parameter.
*
* @param {string} name - parameter name.
* @param {string} expected - description of the type/value/range expected.
* @param {*} actual - the value received.
* @returns {Error} Containing the formatted message.
* @private
*/
const invalidParameterError = function (name, expected, actual) {
return new Error(
`Expected ${expected} for ${name} but received ${actual} of type ${typeof actual}`
);
};
module.exports = {
defined: defined,
object: object,
plainObject: plainObject,
fn: fn,
bool: bool,
buffer: buffer,
typedArray: typedArray,
arrayBuffer: arrayBuffer,
string: string,
number: number,
integer: integer,
inRange: inRange,
inArray: inArray,
invalidParameterError: invalidParameterError
};
+140
View File
@@ -0,0 +1,140 @@
// Copyright 2013 Lovell Fuller and others.
// SPDX-License-Identifier: Apache-2.0
'use strict';
const fs = require('fs');
const os = require('os');
const path = require('path');
const spawnSync = require('child_process').spawnSync;
const semverCoerce = require('semver/functions/coerce');
const semverGreaterThanOrEqualTo = require('semver/functions/gte');
const platform = require('./platform');
const { config } = require('../package.json');
const env = process.env;
const minimumLibvipsVersionLabelled = env.npm_package_config_libvips || /* istanbul ignore next */
config.libvips;
const minimumLibvipsVersion = semverCoerce(minimumLibvipsVersionLabelled).version;
const spawnSyncOptions = {
encoding: 'utf8',
shell: true
};
const vendorPath = path.join(__dirname, '..', 'vendor', minimumLibvipsVersion, platform());
const mkdirSync = function (dirPath) {
try {
fs.mkdirSync(dirPath, { recursive: true });
} catch (err) {
/* istanbul ignore next */
if (err.code !== 'EEXIST') {
throw err;
}
}
};
const cachePath = function () {
const npmCachePath = env.npm_config_cache || /* istanbul ignore next */
(env.APPDATA ? path.join(env.APPDATA, 'npm-cache') : path.join(os.homedir(), '.npm'));
mkdirSync(npmCachePath);
const libvipsCachePath = path.join(npmCachePath, '_libvips');
mkdirSync(libvipsCachePath);
return libvipsCachePath;
};
const integrity = function (platformAndArch) {
return env[`npm_package_config_integrity_${platformAndArch.replace('-', '_')}`] || config.integrity[platformAndArch];
};
const log = function (item) {
if (item instanceof Error) {
console.error(`sharp: Installation error: ${item.message}`);
} else {
console.log(`sharp: ${item}`);
}
};
const isRosetta = function () {
/* istanbul ignore next */
if (process.platform === 'darwin' && process.arch === 'x64') {
const translated = spawnSync('sysctl sysctl.proc_translated', spawnSyncOptions).stdout;
return (translated || '').trim() === 'sysctl.proc_translated: 1';
}
return false;
};
const globalLibvipsVersion = function () {
if (process.platform !== 'win32') {
const globalLibvipsVersion = spawnSync('pkg-config --modversion vips-cpp', {
...spawnSyncOptions,
env: {
...env,
PKG_CONFIG_PATH: pkgConfigPath()
}
}).stdout;
/* istanbul ignore next */
return (globalLibvipsVersion || '').trim();
} else {
return '';
}
};
const hasVendoredLibvips = function () {
return fs.existsSync(vendorPath);
};
/* istanbul ignore next */
const removeVendoredLibvips = function () {
fs.rmSync(vendorPath, { recursive: true, maxRetries: 3, force: true });
};
/* istanbul ignore next */
const pkgConfigPath = function () {
if (process.platform !== 'win32') {
const brewPkgConfigPath = spawnSync(
'which brew >/dev/null 2>&1 && brew environment --plain | grep PKG_CONFIG_LIBDIR | cut -d" " -f2',
spawnSyncOptions
).stdout || '';
return [
brewPkgConfigPath.trim(),
env.PKG_CONFIG_PATH,
'/usr/local/lib/pkgconfig',
'/usr/lib/pkgconfig',
'/usr/local/libdata/pkgconfig',
'/usr/libdata/pkgconfig'
].filter(Boolean).join(':');
} else {
return '';
}
};
const useGlobalLibvips = function () {
if (Boolean(env.SHARP_IGNORE_GLOBAL_LIBVIPS) === true) {
return false;
}
/* istanbul ignore next */
if (isRosetta()) {
log('Detected Rosetta, skipping search for globally-installed libvips');
return false;
}
const globalVipsVersion = globalLibvipsVersion();
return !!globalVipsVersion && /* istanbul ignore next */
semverGreaterThanOrEqualTo(globalVipsVersion, minimumLibvipsVersion);
};
module.exports = {
minimumLibvipsVersion,
minimumLibvipsVersionLabelled,
cachePath,
integrity,
log,
globalLibvipsVersion,
hasVendoredLibvips,
removeVendoredLibvips,
pkgConfigPath,
useGlobalLibvips,
mkdirSync
};
+919
View File
@@ -0,0 +1,919 @@
// Copyright 2013 Lovell Fuller and others.
// SPDX-License-Identifier: Apache-2.0
'use strict';
const color = require('color');
const is = require('./is');
/**
* Rotate the output image by either an explicit angle
* or auto-orient based on the EXIF `Orientation` tag.
*
* If an angle is provided, it is converted to a valid positive degree rotation.
* For example, `-450` will produce a 270 degree rotation.
*
* When rotating by an angle other than a multiple of 90,
* the background colour can be provided with the `background` option.
*
* If no angle is provided, it is determined from the EXIF data.
* Mirroring is supported and may infer the use of a flip operation.
*
* The use of `rotate` without an angle will remove the EXIF `Orientation` tag, if any.
*
* Only one rotation can occur per pipeline.
* Previous calls to `rotate` in the same pipeline will be ignored.
*
* Method order is important when rotating, resizing and/or extracting regions,
* for example `.rotate(x).extract(y)` will produce a different result to `.extract(y).rotate(x)`.
*
* @example
* const pipeline = sharp()
* .rotate()
* .resize(null, 200)
* .toBuffer(function (err, outputBuffer, info) {
* // outputBuffer contains 200px high JPEG image data,
* // auto-rotated using EXIF Orientation tag
* // info.width and info.height contain the dimensions of the resized image
* });
* readableStream.pipe(pipeline);
*
* @example
* const rotateThenResize = await sharp(input)
* .rotate(90)
* .resize({ width: 16, height: 8, fit: 'fill' })
* .toBuffer();
* const resizeThenRotate = await sharp(input)
* .resize({ width: 16, height: 8, fit: 'fill' })
* .rotate(90)
* .toBuffer();
*
* @param {number} [angle=auto] angle of rotation.
* @param {Object} [options] - if present, is an Object with optional attributes.
* @param {string|Object} [options.background="#000000"] parsed by the [color](https://www.npmjs.org/package/color) module to extract values for red, green, blue and alpha.
* @returns {Sharp}
* @throws {Error} Invalid parameters
*/
function rotate (angle, options) {
if (this.options.useExifOrientation || this.options.angle || this.options.rotationAngle) {
this.options.debuglog('ignoring previous rotate options');
}
if (!is.defined(angle)) {
this.options.useExifOrientation = true;
} else if (is.integer(angle) && !(angle % 90)) {
this.options.angle = angle;
} else if (is.number(angle)) {
this.options.rotationAngle = angle;
if (is.object(options) && options.background) {
const backgroundColour = color(options.background);
this.options.rotationBackground = [
backgroundColour.red(),
backgroundColour.green(),
backgroundColour.blue(),
Math.round(backgroundColour.alpha() * 255)
];
}
} else {
throw is.invalidParameterError('angle', 'numeric', angle);
}
return this;
}
/**
* Mirror the image vertically (up-down) about the x-axis.
* This always occurs before rotation, if any.
*
* This operation does not work correctly with multi-page images.
*
* @example
* const output = await sharp(input).flip().toBuffer();
*
* @param {Boolean} [flip=true]
* @returns {Sharp}
*/
function flip (flip) {
this.options.flip = is.bool(flip) ? flip : true;
return this;
}
/**
* Mirror the image horizontally (left-right) about the y-axis.
* This always occurs before rotation, if any.
*
* @example
* const output = await sharp(input).flop().toBuffer();
*
* @param {Boolean} [flop=true]
* @returns {Sharp}
*/
function flop (flop) {
this.options.flop = is.bool(flop) ? flop : true;
return this;
}
/**
* Perform an affine transform on an image. This operation will always occur after resizing, extraction and rotation, if any.
*
* You must provide an array of length 4 or a 2x2 affine transformation matrix.
* By default, new pixels are filled with a black background. You can provide a background color with the `background` option.
* A particular interpolator may also be specified. Set the `interpolator` option to an attribute of the `sharp.interpolators` Object e.g. `sharp.interpolators.nohalo`.
*
* In the case of a 2x2 matrix, the transform is:
* - X = `matrix[0, 0]` \* (x + `idx`) + `matrix[0, 1]` \* (y + `idy`) + `odx`
* - Y = `matrix[1, 0]` \* (x + `idx`) + `matrix[1, 1]` \* (y + `idy`) + `ody`
*
* where:
* - x and y are the coordinates in input image.
* - X and Y are the coordinates in output image.
* - (0,0) is the upper left corner.
*
* @since 0.27.0
*
* @example
* const pipeline = sharp()
* .affine([[1, 0.3], [0.1, 0.7]], {
* background: 'white',
* interpolator: sharp.interpolators.nohalo
* })
* .toBuffer((err, outputBuffer, info) => {
* // outputBuffer contains the transformed image
* // info.width and info.height contain the new dimensions
* });
*
* inputStream
* .pipe(pipeline);
*
* @param {Array<Array<number>>|Array<number>} matrix - affine transformation matrix
* @param {Object} [options] - if present, is an Object with optional attributes.
* @param {String|Object} [options.background="#000000"] - parsed by the [color](https://www.npmjs.org/package/color) module to extract values for red, green, blue and alpha.
* @param {Number} [options.idx=0] - input horizontal offset
* @param {Number} [options.idy=0] - input vertical offset
* @param {Number} [options.odx=0] - output horizontal offset
* @param {Number} [options.ody=0] - output vertical offset
* @param {String} [options.interpolator=sharp.interpolators.bicubic] - interpolator
* @returns {Sharp}
* @throws {Error} Invalid parameters
*/
function affine (matrix, options) {
const flatMatrix = [].concat(...matrix);
if (flatMatrix.length === 4 && flatMatrix.every(is.number)) {
this.options.affineMatrix = flatMatrix;
} else {
throw is.invalidParameterError('matrix', '1x4 or 2x2 array', matrix);
}
if (is.defined(options)) {
if (is.object(options)) {
this._setBackgroundColourOption('affineBackground', options.background);
if (is.defined(options.idx)) {
if (is.number(options.idx)) {
this.options.affineIdx = options.idx;
} else {
throw is.invalidParameterError('options.idx', 'number', options.idx);
}
}
if (is.defined(options.idy)) {
if (is.number(options.idy)) {
this.options.affineIdy = options.idy;
} else {
throw is.invalidParameterError('options.idy', 'number', options.idy);
}
}
if (is.defined(options.odx)) {
if (is.number(options.odx)) {
this.options.affineOdx = options.odx;
} else {
throw is.invalidParameterError('options.odx', 'number', options.odx);
}
}
if (is.defined(options.ody)) {
if (is.number(options.ody)) {
this.options.affineOdy = options.ody;
} else {
throw is.invalidParameterError('options.ody', 'number', options.ody);
}
}
if (is.defined(options.interpolator)) {
if (is.inArray(options.interpolator, Object.values(this.constructor.interpolators))) {
this.options.affineInterpolator = options.interpolator;
} else {
throw is.invalidParameterError('options.interpolator', 'valid interpolator name', options.interpolator);
}
}
} else {
throw is.invalidParameterError('options', 'object', options);
}
}
return this;
}
/**
* Sharpen the image.
*
* When used without parameters, performs a fast, mild sharpen of the output image.
*
* When a `sigma` is provided, performs a slower, more accurate sharpen of the L channel in the LAB colour space.
* Fine-grained control over the level of sharpening in "flat" (m1) and "jagged" (m2) areas is available.
*
* See {@link https://www.libvips.org/API/current/libvips-convolution.html#vips-sharpen|libvips sharpen} operation.
*
* @example
* const data = await sharp(input).sharpen().toBuffer();
*
* @example
* const data = await sharp(input).sharpen({ sigma: 2 }).toBuffer();
*
* @example
* const data = await sharp(input)
* .sharpen({
* sigma: 2,
* m1: 0,
* m2: 3,
* x1: 3,
* y2: 15,
* y3: 15,
* })
* .toBuffer();
*
* @param {Object|number} [options] - if present, is an Object with attributes
* @param {number} [options.sigma] - the sigma of the Gaussian mask, where `sigma = 1 + radius / 2`, between 0.000001 and 10
* @param {number} [options.m1=1.0] - the level of sharpening to apply to "flat" areas, between 0 and 1000000
* @param {number} [options.m2=2.0] - the level of sharpening to apply to "jagged" areas, between 0 and 1000000
* @param {number} [options.x1=2.0] - threshold between "flat" and "jagged", between 0 and 1000000
* @param {number} [options.y2=10.0] - maximum amount of brightening, between 0 and 1000000
* @param {number} [options.y3=20.0] - maximum amount of darkening, between 0 and 1000000
* @param {number} [flat] - (deprecated) see `options.m1`.
* @param {number} [jagged] - (deprecated) see `options.m2`.
* @returns {Sharp}
* @throws {Error} Invalid parameters
*/
function sharpen (options, flat, jagged) {
if (!is.defined(options)) {
// No arguments: default to mild sharpen
this.options.sharpenSigma = -1;
} else if (is.bool(options)) {
// Deprecated boolean argument: apply mild sharpen?
this.options.sharpenSigma = options ? -1 : 0;
} else if (is.number(options) && is.inRange(options, 0.01, 10000)) {
// Deprecated numeric argument: specific sigma
this.options.sharpenSigma = options;
// Deprecated control over flat areas
if (is.defined(flat)) {
if (is.number(flat) && is.inRange(flat, 0, 10000)) {
this.options.sharpenM1 = flat;
} else {
throw is.invalidParameterError('flat', 'number between 0 and 10000', flat);
}
}
// Deprecated control over jagged areas
if (is.defined(jagged)) {
if (is.number(jagged) && is.inRange(jagged, 0, 10000)) {
this.options.sharpenM2 = jagged;
} else {
throw is.invalidParameterError('jagged', 'number between 0 and 10000', jagged);
}
}
} else if (is.plainObject(options)) {
if (is.number(options.sigma) && is.inRange(options.sigma, 0.000001, 10)) {
this.options.sharpenSigma = options.sigma;
} else {
throw is.invalidParameterError('options.sigma', 'number between 0.000001 and 10', options.sigma);
}
if (is.defined(options.m1)) {
if (is.number(options.m1) && is.inRange(options.m1, 0, 1000000)) {
this.options.sharpenM1 = options.m1;
} else {
throw is.invalidParameterError('options.m1', 'number between 0 and 1000000', options.m1);
}
}
if (is.defined(options.m2)) {
if (is.number(options.m2) && is.inRange(options.m2, 0, 1000000)) {
this.options.sharpenM2 = options.m2;
} else {
throw is.invalidParameterError('options.m2', 'number between 0 and 1000000', options.m2);
}
}
if (is.defined(options.x1)) {
if (is.number(options.x1) && is.inRange(options.x1, 0, 1000000)) {
this.options.sharpenX1 = options.x1;
} else {
throw is.invalidParameterError('options.x1', 'number between 0 and 1000000', options.x1);
}
}
if (is.defined(options.y2)) {
if (is.number(options.y2) && is.inRange(options.y2, 0, 1000000)) {
this.options.sharpenY2 = options.y2;
} else {
throw is.invalidParameterError('options.y2', 'number between 0 and 1000000', options.y2);
}
}
if (is.defined(options.y3)) {
if (is.number(options.y3) && is.inRange(options.y3, 0, 1000000)) {
this.options.sharpenY3 = options.y3;
} else {
throw is.invalidParameterError('options.y3', 'number between 0 and 1000000', options.y3);
}
}
} else {
throw is.invalidParameterError('sigma', 'number between 0.01 and 10000', options);
}
return this;
}
/**
* Apply median filter.
* When used without parameters the default window is 3x3.
*
* @example
* const output = await sharp(input).median().toBuffer();
*
* @example
* const output = await sharp(input).median(5).toBuffer();
*
* @param {number} [size=3] square mask size: size x size
* @returns {Sharp}
* @throws {Error} Invalid parameters
*/
function median (size) {
if (!is.defined(size)) {
// No arguments: default to 3x3
this.options.medianSize = 3;
} else if (is.integer(size) && is.inRange(size, 1, 1000)) {
// Numeric argument: specific sigma
this.options.medianSize = size;
} else {
throw is.invalidParameterError('size', 'integer between 1 and 1000', size);
}
return this;
}
/**
* Blur the image.
*
* When used without parameters, performs a fast 3x3 box blur (equivalent to a box linear filter).
*
* When a `sigma` is provided, performs a slower, more accurate Gaussian blur.
*
* @example
* const boxBlurred = await sharp(input)
* .blur()
* .toBuffer();
*
* @example
* const gaussianBlurred = await sharp(input)
* .blur(5)
* .toBuffer();
*
* @param {number} [sigma] a value between 0.3 and 1000 representing the sigma of the Gaussian mask, where `sigma = 1 + radius / 2`.
* @returns {Sharp}
* @throws {Error} Invalid parameters
*/
function blur (sigma) {
if (!is.defined(sigma)) {
// No arguments: default to mild blur
this.options.blurSigma = -1;
} else if (is.bool(sigma)) {
// Boolean argument: apply mild blur?
this.options.blurSigma = sigma ? -1 : 0;
} else if (is.number(sigma) && is.inRange(sigma, 0.3, 1000)) {
// Numeric argument: specific sigma
this.options.blurSigma = sigma;
} else {
throw is.invalidParameterError('sigma', 'number between 0.3 and 1000', sigma);
}
return this;
}
/**
* Merge alpha transparency channel, if any, with a background, then remove the alpha channel.
*
* See also {@link /api-channel#removealpha|removeAlpha}.
*
* @example
* await sharp(rgbaInput)
* .flatten({ background: '#F0A703' })
* .toBuffer();
*
* @param {Object} [options]
* @param {string|Object} [options.background={r: 0, g: 0, b: 0}] - background colour, parsed by the [color](https://www.npmjs.org/package/color) module, defaults to black.
* @returns {Sharp}
*/
function flatten (options) {
this.options.flatten = is.bool(options) ? options : true;
if (is.object(options)) {
this._setBackgroundColourOption('flattenBackground', options.background);
}
return this;
}
/**
* Ensure the image has an alpha channel
* with all white pixel values made fully transparent.
*
* Existing alpha channel values for non-white pixels remain unchanged.
*
* This feature is experimental and the API may change.
*
* @since 0.32.1
*
* @example
* await sharp(rgbInput)
* .unflatten()
* .toBuffer();
*
* @example
* await sharp(rgbInput)
* .threshold(128, { grayscale: false }) // converter bright pixels to white
* .unflatten()
* .toBuffer();
*/
function unflatten () {
this.options.unflatten = true;
return this;
}
/**
* Apply a gamma correction by reducing the encoding (darken) pre-resize at a factor of `1/gamma`
* then increasing the encoding (brighten) post-resize at a factor of `gamma`.
* This can improve the perceived brightness of a resized image in non-linear colour spaces.
* JPEG and WebP input images will not take advantage of the shrink-on-load performance optimisation
* when applying a gamma correction.
*
* Supply a second argument to use a different output gamma value, otherwise the first value is used in both cases.
*
* @param {number} [gamma=2.2] value between 1.0 and 3.0.
* @param {number} [gammaOut] value between 1.0 and 3.0. (optional, defaults to same as `gamma`)
* @returns {Sharp}
* @throws {Error} Invalid parameters
*/
function gamma (gamma, gammaOut) {
if (!is.defined(gamma)) {
// Default gamma correction of 2.2 (sRGB)
this.options.gamma = 2.2;
} else if (is.number(gamma) && is.inRange(gamma, 1, 3)) {
this.options.gamma = gamma;
} else {
throw is.invalidParameterError('gamma', 'number between 1.0 and 3.0', gamma);
}
if (!is.defined(gammaOut)) {
// Default gamma correction for output is same as input
this.options.gammaOut = this.options.gamma;
} else if (is.number(gammaOut) && is.inRange(gammaOut, 1, 3)) {
this.options.gammaOut = gammaOut;
} else {
throw is.invalidParameterError('gammaOut', 'number between 1.0 and 3.0', gammaOut);
}
return this;
}
/**
* Produce the "negative" of the image.
*
* @example
* const output = await sharp(input)
* .negate()
* .toBuffer();
*
* @example
* const output = await sharp(input)
* .negate({ alpha: false })
* .toBuffer();
*
* @param {Object} [options]
* @param {Boolean} [options.alpha=true] Whether or not to negate any alpha channel
* @returns {Sharp}
*/
function negate (options) {
this.options.negate = is.bool(options) ? options : true;
if (is.plainObject(options) && 'alpha' in options) {
if (!is.bool(options.alpha)) {
throw is.invalidParameterError('alpha', 'should be boolean value', options.alpha);
} else {
this.options.negateAlpha = options.alpha;
}
}
return this;
}
/**
* Enhance output image contrast by stretching its luminance to cover a full dynamic range.
*
* Uses a histogram-based approach, taking a default range of 1% to 99% to reduce sensitivity to noise at the extremes.
*
* Luminance values below the `lower` percentile will be underexposed by clipping to zero.
* Luminance values above the `upper` percentile will be overexposed by clipping to the max pixel value.
*
* @example
* const output = await sharp(input)
* .normalise()
* .toBuffer();
*
* @example
* const output = await sharp(input)
* .normalise({ lower: 0, upper: 100 })
* .toBuffer();
*
* @param {Object} [options]
* @param {number} [options.lower=1] - Percentile below which luminance values will be underexposed.
* @param {number} [options.upper=99] - Percentile above which luminance values will be overexposed.
* @returns {Sharp}
*/
function normalise (options) {
if (is.plainObject(options)) {
if (is.defined(options.lower)) {
if (is.number(options.lower) && is.inRange(options.lower, 0, 99)) {
this.options.normaliseLower = options.lower;
} else {
throw is.invalidParameterError('lower', 'number between 0 and 99', options.lower);
}
}
if (is.defined(options.upper)) {
if (is.number(options.upper) && is.inRange(options.upper, 1, 100)) {
this.options.normaliseUpper = options.upper;
} else {
throw is.invalidParameterError('upper', 'number between 1 and 100', options.upper);
}
}
}
if (this.options.normaliseLower >= this.options.normaliseUpper) {
throw is.invalidParameterError('range', 'lower to be less than upper',
`${this.options.normaliseLower} >= ${this.options.normaliseUpper}`);
}
this.options.normalise = true;
return this;
}
/**
* Alternative spelling of normalise.
*
* @example
* const output = await sharp(input)
* .normalize()
* .toBuffer();
*
* @param {Object} [options]
* @param {number} [options.lower=1] - Percentile below which luminance values will be underexposed.
* @param {number} [options.upper=99] - Percentile above which luminance values will be overexposed.
* @returns {Sharp}
*/
function normalize (options) {
return this.normalise(options);
}
/**
* Perform contrast limiting adaptive histogram equalization
* {@link https://en.wikipedia.org/wiki/Adaptive_histogram_equalization#Contrast_Limited_AHE|CLAHE}.
*
* This will, in general, enhance the clarity of the image by bringing out darker details.
*
* @since 0.28.3
*
* @example
* const output = await sharp(input)
* .clahe({
* width: 3,
* height: 3,
* })
* .toBuffer();
*
* @param {Object} options
* @param {number} options.width - Integral width of the search window, in pixels.
* @param {number} options.height - Integral height of the search window, in pixels.
* @param {number} [options.maxSlope=3] - Integral level of brightening, between 0 and 100, where 0 disables contrast limiting.
* @returns {Sharp}
* @throws {Error} Invalid parameters
*/
function clahe (options) {
if (is.plainObject(options)) {
if (is.integer(options.width) && options.width > 0) {
this.options.claheWidth = options.width;
} else {
throw is.invalidParameterError('width', 'integer greater than zero', options.width);
}
if (is.integer(options.height) && options.height > 0) {
this.options.claheHeight = options.height;
} else {
throw is.invalidParameterError('height', 'integer greater than zero', options.height);
}
if (is.defined(options.maxSlope)) {
if (is.integer(options.maxSlope) && is.inRange(options.maxSlope, 0, 100)) {
this.options.claheMaxSlope = options.maxSlope;
} else {
throw is.invalidParameterError('maxSlope', 'integer between 0 and 100', options.maxSlope);
}
}
} else {
throw is.invalidParameterError('options', 'plain object', options);
}
return this;
}
/**
* Convolve the image with the specified kernel.
*
* @example
* sharp(input)
* .convolve({
* width: 3,
* height: 3,
* kernel: [-1, 0, 1, -2, 0, 2, -1, 0, 1]
* })
* .raw()
* .toBuffer(function(err, data, info) {
* // data contains the raw pixel data representing the convolution
* // of the input image with the horizontal Sobel operator
* });
*
* @param {Object} kernel
* @param {number} kernel.width - width of the kernel in pixels.
* @param {number} kernel.height - height of the kernel in pixels.
* @param {Array<number>} kernel.kernel - Array of length `width*height` containing the kernel values.
* @param {number} [kernel.scale=sum] - the scale of the kernel in pixels.
* @param {number} [kernel.offset=0] - the offset of the kernel in pixels.
* @returns {Sharp}
* @throws {Error} Invalid parameters
*/
function convolve (kernel) {
if (!is.object(kernel) || !Array.isArray(kernel.kernel) ||
!is.integer(kernel.width) || !is.integer(kernel.height) ||
!is.inRange(kernel.width, 3, 1001) || !is.inRange(kernel.height, 3, 1001) ||
kernel.height * kernel.width !== kernel.kernel.length
) {
// must pass in a kernel
throw new Error('Invalid convolution kernel');
}
// Default scale is sum of kernel values
if (!is.integer(kernel.scale)) {
kernel.scale = kernel.kernel.reduce(function (a, b) {
return a + b;
}, 0);
}
// Clip scale to a minimum value of 1
if (kernel.scale < 1) {
kernel.scale = 1;
}
if (!is.integer(kernel.offset)) {
kernel.offset = 0;
}
this.options.convKernel = kernel;
return this;
}
/**
* Any pixel value greater than or equal to the threshold value will be set to 255, otherwise it will be set to 0.
* @param {number} [threshold=128] - a value in the range 0-255 representing the level at which the threshold will be applied.
* @param {Object} [options]
* @param {Boolean} [options.greyscale=true] - convert to single channel greyscale.
* @param {Boolean} [options.grayscale=true] - alternative spelling for greyscale.
* @returns {Sharp}
* @throws {Error} Invalid parameters
*/
function threshold (threshold, options) {
if (!is.defined(threshold)) {
this.options.threshold = 128;
} else if (is.bool(threshold)) {
this.options.threshold = threshold ? 128 : 0;
} else if (is.integer(threshold) && is.inRange(threshold, 0, 255)) {
this.options.threshold = threshold;
} else {
throw is.invalidParameterError('threshold', 'integer between 0 and 255', threshold);
}
if (!is.object(options) || options.greyscale === true || options.grayscale === true) {
this.options.thresholdGrayscale = true;
} else {
this.options.thresholdGrayscale = false;
}
return this;
}
/**
* Perform a bitwise boolean operation with operand image.
*
* This operation creates an output image where each pixel is the result of
* the selected bitwise boolean `operation` between the corresponding pixels of the input images.
*
* @param {Buffer|string} operand - Buffer containing image data or string containing the path to an image file.
* @param {string} operator - one of `and`, `or` or `eor` to perform that bitwise operation, like the C logic operators `&`, `|` and `^` respectively.
* @param {Object} [options]
* @param {Object} [options.raw] - describes operand when using raw pixel data.
* @param {number} [options.raw.width]
* @param {number} [options.raw.height]
* @param {number} [options.raw.channels]
* @returns {Sharp}
* @throws {Error} Invalid parameters
*/
function boolean (operand, operator, options) {
this.options.boolean = this._createInputDescriptor(operand, options);
if (is.string(operator) && is.inArray(operator, ['and', 'or', 'eor'])) {
this.options.booleanOp = operator;
} else {
throw is.invalidParameterError('operator', 'one of: and, or, eor', operator);
}
return this;
}
/**
* Apply the linear formula `a` * input + `b` to the image to adjust image levels.
*
* When a single number is provided, it will be used for all image channels.
* When an array of numbers is provided, the array length must match the number of channels.
*
* @example
* await sharp(input)
* .linear(0.5, 2)
* .toBuffer();
*
* @example
* await sharp(rgbInput)
* .linear(
* [0.25, 0.5, 0.75],
* [150, 100, 50]
* )
* .toBuffer();
*
* @param {(number|number[])} [a=[]] multiplier
* @param {(number|number[])} [b=[]] offset
* @returns {Sharp}
* @throws {Error} Invalid parameters
*/
function linear (a, b) {
if (!is.defined(a) && is.number(b)) {
a = 1.0;
} else if (is.number(a) && !is.defined(b)) {
b = 0.0;
}
if (!is.defined(a)) {
this.options.linearA = [];
} else if (is.number(a)) {
this.options.linearA = [a];
} else if (Array.isArray(a) && a.length && a.every(is.number)) {
this.options.linearA = a;
} else {
throw is.invalidParameterError('a', 'number or array of numbers', a);
}
if (!is.defined(b)) {
this.options.linearB = [];
} else if (is.number(b)) {
this.options.linearB = [b];
} else if (Array.isArray(b) && b.length && b.every(is.number)) {
this.options.linearB = b;
} else {
throw is.invalidParameterError('b', 'number or array of numbers', b);
}
if (this.options.linearA.length !== this.options.linearB.length) {
throw new Error('Expected a and b to be arrays of the same length');
}
return this;
}
/**
* Recombine the image with the specified matrix.
*
* @since 0.21.1
*
* @example
* sharp(input)
* .recomb([
* [0.3588, 0.7044, 0.1368],
* [0.2990, 0.5870, 0.1140],
* [0.2392, 0.4696, 0.0912],
* ])
* .raw()
* .toBuffer(function(err, data, info) {
* // data contains the raw pixel data after applying the matrix
* // With this example input, a sepia filter has been applied
* });
*
* @param {Array<Array<number>>} inputMatrix - 3x3 Recombination matrix
* @returns {Sharp}
* @throws {Error} Invalid parameters
*/
function recomb (inputMatrix) {
if (!Array.isArray(inputMatrix) || inputMatrix.length !== 3 ||
inputMatrix[0].length !== 3 ||
inputMatrix[1].length !== 3 ||
inputMatrix[2].length !== 3
) {
// must pass in a kernel
throw new Error('Invalid recombination matrix');
}
this.options.recombMatrix = [
inputMatrix[0][0], inputMatrix[0][1], inputMatrix[0][2],
inputMatrix[1][0], inputMatrix[1][1], inputMatrix[1][2],
inputMatrix[2][0], inputMatrix[2][1], inputMatrix[2][2]
].map(Number);
return this;
}
/**
* Transforms the image using brightness, saturation, hue rotation, and lightness.
* Brightness and lightness both operate on luminance, with the difference being that
* brightness is multiplicative whereas lightness is additive.
*
* @since 0.22.1
*
* @example
* // increase brightness by a factor of 2
* const output = await sharp(input)
* .modulate({
* brightness: 2
* })
* .toBuffer();
*
* @example
* // hue-rotate by 180 degrees
* const output = await sharp(input)
* .modulate({
* hue: 180
* })
* .toBuffer();
*
* @example
* // increase lightness by +50
* const output = await sharp(input)
* .modulate({
* lightness: 50
* })
* .toBuffer();
*
* @example
* // decrease brightness and saturation while also hue-rotating by 90 degrees
* const output = await sharp(input)
* .modulate({
* brightness: 0.5,
* saturation: 0.5,
* hue: 90,
* })
* .toBuffer();
*
* @param {Object} [options]
* @param {number} [options.brightness] Brightness multiplier
* @param {number} [options.saturation] Saturation multiplier
* @param {number} [options.hue] Degrees for hue rotation
* @param {number} [options.lightness] Lightness addend
* @returns {Sharp}
*/
function modulate (options) {
if (!is.plainObject(options)) {
throw is.invalidParameterError('options', 'plain object', options);
}
if ('brightness' in options) {
if (is.number(options.brightness) && options.brightness >= 0) {
this.options.brightness = options.brightness;
} else {
throw is.invalidParameterError('brightness', 'number above zero', options.brightness);
}
}
if ('saturation' in options) {
if (is.number(options.saturation) && options.saturation >= 0) {
this.options.saturation = options.saturation;
} else {
throw is.invalidParameterError('saturation', 'number above zero', options.saturation);
}
}
if ('hue' in options) {
if (is.integer(options.hue)) {
this.options.hue = options.hue % 360;
} else {
throw is.invalidParameterError('hue', 'number', options.hue);
}
}
if ('lightness' in options) {
if (is.number(options.lightness)) {
this.options.lightness = options.lightness;
} else {
throw is.invalidParameterError('lightness', 'number', options.lightness);
}
}
return this;
}
/**
* Decorate the Sharp prototype with operation-related functions.
* @private
*/
module.exports = function (Sharp) {
Object.assign(Sharp.prototype, {
rotate,
flip,
flop,
affine,
sharpen,
median,
blur,
flatten,
unflatten,
gamma,
negate,
normalise,
normalize,
clahe,
convolve,
threshold,
boolean,
linear,
recomb,
modulate
});
};
+1413
View File
File diff suppressed because it is too large Load Diff
+30
View File
@@ -0,0 +1,30 @@
// Copyright 2013 Lovell Fuller and others.
// SPDX-License-Identifier: Apache-2.0
'use strict';
const detectLibc = require('detect-libc');
const env = process.env;
module.exports = function () {
const arch = env.npm_config_arch || process.arch;
const platform = env.npm_config_platform || process.platform;
const libc = process.env.npm_config_libc ||
/* istanbul ignore next */
(detectLibc.isNonGlibcLinuxSync() ? detectLibc.familySync() : '');
const libcId = platform !== 'linux' || libc === detectLibc.GLIBC ? '' : libc;
const platformId = [`${platform}${libcId}`];
if (arch === 'arm') {
const fallback = process.versions.electron ? '7' : '6';
platformId.push(`armv${env.npm_config_arm_version || process.config.variables.arm_version || fallback}`);
} else if (arch === 'arm64') {
platformId.push(`arm64v${env.npm_config_arm_version || '8'}`);
} else {
platformId.push(arch);
}
return platformId.join('-');
};
+582
View File
@@ -0,0 +1,582 @@
// Copyright 2013 Lovell Fuller and others.
// SPDX-License-Identifier: Apache-2.0
'use strict';
const is = require('./is');
/**
* Weighting to apply when using contain/cover fit.
* @member
* @private
*/
const gravity = {
center: 0,
centre: 0,
north: 1,
east: 2,
south: 3,
west: 4,
northeast: 5,
southeast: 6,
southwest: 7,
northwest: 8
};
/**
* Position to apply when using contain/cover fit.
* @member
* @private
*/
const position = {
top: 1,
right: 2,
bottom: 3,
left: 4,
'right top': 5,
'right bottom': 6,
'left bottom': 7,
'left top': 8
};
/**
* How to extend the image.
* @member
* @private
*/
const extendWith = {
background: 'background',
copy: 'copy',
repeat: 'repeat',
mirror: 'mirror'
};
/**
* Strategies for automagic cover behaviour.
* @member
* @private
*/
const strategy = {
entropy: 16,
attention: 17
};
/**
* Reduction kernels.
* @member
* @private
*/
const kernel = {
nearest: 'nearest',
cubic: 'cubic',
mitchell: 'mitchell',
lanczos2: 'lanczos2',
lanczos3: 'lanczos3'
};
/**
* Methods by which an image can be resized to fit the provided dimensions.
* @member
* @private
*/
const fit = {
contain: 'contain',
cover: 'cover',
fill: 'fill',
inside: 'inside',
outside: 'outside'
};
/**
* Map external fit property to internal canvas property.
* @member
* @private
*/
const mapFitToCanvas = {
contain: 'embed',
cover: 'crop',
fill: 'ignore_aspect',
inside: 'max',
outside: 'min'
};
/**
* @private
*/
function isRotationExpected (options) {
return (options.angle % 360) !== 0 || options.useExifOrientation === true || options.rotationAngle !== 0;
}
/**
* @private
*/
function isResizeExpected (options) {
return options.width !== -1 || options.height !== -1;
}
/**
* Resize image to `width`, `height` or `width x height`.
*
* When both a `width` and `height` are provided, the possible methods by which the image should **fit** these are:
* - `cover`: (default) Preserving aspect ratio, attempt to ensure the image covers both provided dimensions by cropping/clipping to fit.
* - `contain`: Preserving aspect ratio, contain within both provided dimensions using "letterboxing" where necessary.
* - `fill`: Ignore the aspect ratio of the input and stretch to both provided dimensions.
* - `inside`: Preserving aspect ratio, resize the image to be as large as possible while ensuring its dimensions are less than or equal to both those specified.
* - `outside`: Preserving aspect ratio, resize the image to be as small as possible while ensuring its dimensions are greater than or equal to both those specified.
*
* Some of these values are based on the [object-fit](https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit) CSS property.
*
* <img alt="Examples of various values for the fit property when resizing" width="100%" style="aspect-ratio: 998/243" src="https://cdn.jsdelivr.net/gh/lovell/sharp@main/docs/image/api-resize-fit.svg">
*
* When using a **fit** of `cover` or `contain`, the default **position** is `centre`. Other options are:
* - `sharp.position`: `top`, `right top`, `right`, `right bottom`, `bottom`, `left bottom`, `left`, `left top`.
* - `sharp.gravity`: `north`, `northeast`, `east`, `southeast`, `south`, `southwest`, `west`, `northwest`, `center` or `centre`.
* - `sharp.strategy`: `cover` only, dynamically crop using either the `entropy` or `attention` strategy.
*
* Some of these values are based on the [object-position](https://developer.mozilla.org/en-US/docs/Web/CSS/object-position) CSS property.
*
* The experimental strategy-based approach resizes so one dimension is at its target length
* then repeatedly ranks edge regions, discarding the edge with the lowest score based on the selected strategy.
* - `entropy`: focus on the region with the highest [Shannon entropy](https://en.wikipedia.org/wiki/Entropy_%28information_theory%29).
* - `attention`: focus on the region with the highest luminance frequency, colour saturation and presence of skin tones.
*
* Possible interpolation kernels are:
* - `nearest`: Use [nearest neighbour interpolation](http://en.wikipedia.org/wiki/Nearest-neighbor_interpolation).
* - `cubic`: Use a [Catmull-Rom spline](https://en.wikipedia.org/wiki/Centripetal_Catmull%E2%80%93Rom_spline).
* - `mitchell`: Use a [Mitchell-Netravali spline](https://www.cs.utexas.edu/~fussell/courses/cs384g-fall2013/lectures/mitchell/Mitchell.pdf).
* - `lanczos2`: Use a [Lanczos kernel](https://en.wikipedia.org/wiki/Lanczos_resampling#Lanczos_kernel) with `a=2`.
* - `lanczos3`: Use a Lanczos kernel with `a=3` (the default).
*
* Only one resize can occur per pipeline.
* Previous calls to `resize` in the same pipeline will be ignored.
*
* @example
* sharp(input)
* .resize({ width: 100 })
* .toBuffer()
* .then(data => {
* // 100 pixels wide, auto-scaled height
* });
*
* @example
* sharp(input)
* .resize({ height: 100 })
* .toBuffer()
* .then(data => {
* // 100 pixels high, auto-scaled width
* });
*
* @example
* sharp(input)
* .resize(200, 300, {
* kernel: sharp.kernel.nearest,
* fit: 'contain',
* position: 'right top',
* background: { r: 255, g: 255, b: 255, alpha: 0.5 }
* })
* .toFile('output.png')
* .then(() => {
* // output.png is a 200 pixels wide and 300 pixels high image
* // containing a nearest-neighbour scaled version
* // contained within the north-east corner of a semi-transparent white canvas
* });
*
* @example
* const transformer = sharp()
* .resize({
* width: 200,
* height: 200,
* fit: sharp.fit.cover,
* position: sharp.strategy.entropy
* });
* // Read image data from readableStream
* // Write 200px square auto-cropped image data to writableStream
* readableStream
* .pipe(transformer)
* .pipe(writableStream);
*
* @example
* sharp(input)
* .resize(200, 200, {
* fit: sharp.fit.inside,
* withoutEnlargement: true
* })
* .toFormat('jpeg')
* .toBuffer()
* .then(function(outputBuffer) {
* // outputBuffer contains JPEG image data
* // no wider and no higher than 200 pixels
* // and no larger than the input image
* });
*
* @example
* sharp(input)
* .resize(200, 200, {
* fit: sharp.fit.outside,
* withoutReduction: true
* })
* .toFormat('jpeg')
* .toBuffer()
* .then(function(outputBuffer) {
* // outputBuffer contains JPEG image data
* // of at least 200 pixels wide and 200 pixels high while maintaining aspect ratio
* // and no smaller than the input image
* });
*
* @example
* const scaleByHalf = await sharp(input)
* .metadata()
* .then(({ width }) => sharp(input)
* .resize(Math.round(width * 0.5))
* .toBuffer()
* );
*
* @param {number} [width] - How many pixels wide the resultant image should be. Use `null` or `undefined` to auto-scale the width to match the height.
* @param {number} [height] - How many pixels high the resultant image should be. Use `null` or `undefined` to auto-scale the height to match the width.
* @param {Object} [options]
* @param {number} [options.width] - An alternative means of specifying `width`. If both are present this takes priority.
* @param {number} [options.height] - An alternative means of specifying `height`. If both are present this takes priority.
* @param {String} [options.fit='cover'] - How the image should be resized/cropped to fit the target dimension(s), one of `cover`, `contain`, `fill`, `inside` or `outside`.
* @param {String} [options.position='centre'] - A position, gravity or strategy to use when `fit` is `cover` or `contain`.
* @param {String|Object} [options.background={r: 0, g: 0, b: 0, alpha: 1}] - background colour when `fit` is `contain`, parsed by the [color](https://www.npmjs.org/package/color) module, defaults to black without transparency.
* @param {String} [options.kernel='lanczos3'] - The kernel to use for image reduction. Use the `fastShrinkOnLoad` option to control kernel vs shrink-on-load.
* @param {Boolean} [options.withoutEnlargement=false] - Do not scale up if the width *or* height are already less than the target dimensions, equivalent to GraphicsMagick's `>` geometry option. This may result in output dimensions smaller than the target dimensions.
* @param {Boolean} [options.withoutReduction=false] - Do not scale down if the width *or* height are already greater than the target dimensions, equivalent to GraphicsMagick's `<` geometry option. This may still result in a crop to reach the target dimensions.
* @param {Boolean} [options.fastShrinkOnLoad=true] - Take greater advantage of the JPEG and WebP shrink-on-load feature, which can lead to a slight moiré pattern or round-down of an auto-scaled dimension.
* @returns {Sharp}
* @throws {Error} Invalid parameters
*/
function resize (widthOrOptions, height, options) {
if (isResizeExpected(this.options)) {
this.options.debuglog('ignoring previous resize options');
}
if (is.defined(widthOrOptions)) {
if (is.object(widthOrOptions) && !is.defined(options)) {
options = widthOrOptions;
} else if (is.integer(widthOrOptions) && widthOrOptions > 0) {
this.options.width = widthOrOptions;
} else {
throw is.invalidParameterError('width', 'positive integer', widthOrOptions);
}
} else {
this.options.width = -1;
}
if (is.defined(height)) {
if (is.integer(height) && height > 0) {
this.options.height = height;
} else {
throw is.invalidParameterError('height', 'positive integer', height);
}
} else {
this.options.height = -1;
}
if (is.object(options)) {
// Width
if (is.defined(options.width)) {
if (is.integer(options.width) && options.width > 0) {
this.options.width = options.width;
} else {
throw is.invalidParameterError('width', 'positive integer', options.width);
}
}
// Height
if (is.defined(options.height)) {
if (is.integer(options.height) && options.height > 0) {
this.options.height = options.height;
} else {
throw is.invalidParameterError('height', 'positive integer', options.height);
}
}
// Fit
if (is.defined(options.fit)) {
const canvas = mapFitToCanvas[options.fit];
if (is.string(canvas)) {
this.options.canvas = canvas;
} else {
throw is.invalidParameterError('fit', 'valid fit', options.fit);
}
}
// Position
if (is.defined(options.position)) {
const pos = is.integer(options.position)
? options.position
: strategy[options.position] || position[options.position] || gravity[options.position];
if (is.integer(pos) && (is.inRange(pos, 0, 8) || is.inRange(pos, 16, 17))) {
this.options.position = pos;
} else {
throw is.invalidParameterError('position', 'valid position/gravity/strategy', options.position);
}
}
// Background
this._setBackgroundColourOption('resizeBackground', options.background);
// Kernel
if (is.defined(options.kernel)) {
if (is.string(kernel[options.kernel])) {
this.options.kernel = kernel[options.kernel];
} else {
throw is.invalidParameterError('kernel', 'valid kernel name', options.kernel);
}
}
// Without enlargement
if (is.defined(options.withoutEnlargement)) {
this._setBooleanOption('withoutEnlargement', options.withoutEnlargement);
}
// Without reduction
if (is.defined(options.withoutReduction)) {
this._setBooleanOption('withoutReduction', options.withoutReduction);
}
// Shrink on load
if (is.defined(options.fastShrinkOnLoad)) {
this._setBooleanOption('fastShrinkOnLoad', options.fastShrinkOnLoad);
}
}
if (isRotationExpected(this.options) && isResizeExpected(this.options)) {
this.options.rotateBeforePreExtract = true;
}
return this;
}
/**
* Extend / pad / extrude one or more edges of the image with either
* the provided background colour or pixels derived from the image.
* This operation will always occur after resizing and extraction, if any.
*
* @example
* // Resize to 140 pixels wide, then add 10 transparent pixels
* // to the top, left and right edges and 20 to the bottom edge
* sharp(input)
* .resize(140)
* .extend({
* top: 10,
* bottom: 20,
* left: 10,
* right: 10,
* background: { r: 0, g: 0, b: 0, alpha: 0 }
* })
* ...
*
* @example
* // Add a row of 10 red pixels to the bottom
* sharp(input)
* .extend({
* bottom: 10,
* background: 'red'
* })
* ...
*
* @example
* // Extrude image by 8 pixels to the right, mirroring existing right hand edge
* sharp(input)
* .extend({
* right: 8,
* background: 'mirror'
* })
* ...
*
* @param {(number|Object)} extend - single pixel count to add to all edges or an Object with per-edge counts
* @param {number} [extend.top=0]
* @param {number} [extend.left=0]
* @param {number} [extend.bottom=0]
* @param {number} [extend.right=0]
* @param {String} [extend.extendWith='background'] - populate new pixels using this method, one of: background, copy, repeat, mirror.
* @param {String|Object} [extend.background={r: 0, g: 0, b: 0, alpha: 1}] - background colour, parsed by the [color](https://www.npmjs.org/package/color) module, defaults to black without transparency.
* @returns {Sharp}
* @throws {Error} Invalid parameters
*/
function extend (extend) {
if (is.integer(extend) && extend > 0) {
this.options.extendTop = extend;
this.options.extendBottom = extend;
this.options.extendLeft = extend;
this.options.extendRight = extend;
} else if (is.object(extend)) {
if (is.defined(extend.top)) {
if (is.integer(extend.top) && extend.top >= 0) {
this.options.extendTop = extend.top;
} else {
throw is.invalidParameterError('top', 'positive integer', extend.top);
}
}
if (is.defined(extend.bottom)) {
if (is.integer(extend.bottom) && extend.bottom >= 0) {
this.options.extendBottom = extend.bottom;
} else {
throw is.invalidParameterError('bottom', 'positive integer', extend.bottom);
}
}
if (is.defined(extend.left)) {
if (is.integer(extend.left) && extend.left >= 0) {
this.options.extendLeft = extend.left;
} else {
throw is.invalidParameterError('left', 'positive integer', extend.left);
}
}
if (is.defined(extend.right)) {
if (is.integer(extend.right) && extend.right >= 0) {
this.options.extendRight = extend.right;
} else {
throw is.invalidParameterError('right', 'positive integer', extend.right);
}
}
this._setBackgroundColourOption('extendBackground', extend.background);
if (is.defined(extend.extendWith)) {
if (is.string(extendWith[extend.extendWith])) {
this.options.extendWith = extendWith[extend.extendWith];
} else {
throw is.invalidParameterError('extendWith', 'one of: background, copy, repeat, mirror', extend.extendWith);
}
}
} else {
throw is.invalidParameterError('extend', 'integer or object', extend);
}
return this;
}
/**
* Extract/crop a region of the image.
*
* - Use `extract` before `resize` for pre-resize extraction.
* - Use `extract` after `resize` for post-resize extraction.
* - Use `extract` before and after for both.
*
* @example
* sharp(input)
* .extract({ left: left, top: top, width: width, height: height })
* .toFile(output, function(err) {
* // Extract a region of the input image, saving in the same format.
* });
* @example
* sharp(input)
* .extract({ left: leftOffsetPre, top: topOffsetPre, width: widthPre, height: heightPre })
* .resize(width, height)
* .extract({ left: leftOffsetPost, top: topOffsetPost, width: widthPost, height: heightPost })
* .toFile(output, function(err) {
* // Extract a region, resize, then extract from the resized image
* });
*
* @param {Object} options - describes the region to extract using integral pixel values
* @param {number} options.left - zero-indexed offset from left edge
* @param {number} options.top - zero-indexed offset from top edge
* @param {number} options.width - width of region to extract
* @param {number} options.height - height of region to extract
* @returns {Sharp}
* @throws {Error} Invalid parameters
*/
function extract (options) {
const suffix = isResizeExpected(this.options) || this.options.widthPre !== -1 ? 'Post' : 'Pre';
if (this.options[`width${suffix}`] !== -1) {
this.options.debuglog('ignoring previous extract options');
}
['left', 'top', 'width', 'height'].forEach(function (name) {
const value = options[name];
if (is.integer(value) && value >= 0) {
this.options[name + (name === 'left' || name === 'top' ? 'Offset' : '') + suffix] = value;
} else {
throw is.invalidParameterError(name, 'integer', value);
}
}, this);
// Ensure existing rotation occurs before pre-resize extraction
if (isRotationExpected(this.options) && !isResizeExpected(this.options)) {
if (this.options.widthPre === -1 || this.options.widthPost === -1) {
this.options.rotateBeforePreExtract = true;
}
}
return this;
}
/**
* Trim pixels from all edges that contain values similar to the given background colour, which defaults to that of the top-left pixel.
*
* Images with an alpha channel will use the combined bounding box of alpha and non-alpha channels.
*
* If the result of this operation would trim an image to nothing then no change is made.
*
* The `info` response Object, obtained from callback of `.toFile()` or `.toBuffer()`,
* will contain `trimOffsetLeft` and `trimOffsetTop` properties.
*
* @example
* // Trim pixels with a colour similar to that of the top-left pixel.
* sharp(input)
* .trim()
* .toFile(output, function(err, info) {
* ...
* });
* @example
* // Trim pixels with the exact same colour as that of the top-left pixel.
* sharp(input)
* .trim(0)
* .toFile(output, function(err, info) {
* ...
* });
* @example
* // Trim only pixels with a similar colour to red.
* sharp(input)
* .trim("#FF0000")
* .toFile(output, function(err, info) {
* ...
* });
* @example
* // Trim all "yellow-ish" pixels, being more lenient with the higher threshold.
* sharp(input)
* .trim({
* background: "yellow",
* threshold: 42,
* })
* .toFile(output, function(err, info) {
* ...
* });
*
* @param {string|number|Object} trim - the specific background colour to trim, the threshold for doing so or an Object with both.
* @param {string|Object} [trim.background='top-left pixel'] - background colour, parsed by the [color](https://www.npmjs.org/package/color) module, defaults to that of the top-left pixel.
* @param {number} [trim.threshold=10] - the allowed difference from the above colour, a positive number.
* @returns {Sharp}
* @throws {Error} Invalid parameters
*/
function trim (trim) {
if (!is.defined(trim)) {
this.options.trimThreshold = 10;
} else if (is.string(trim)) {
this._setBackgroundColourOption('trimBackground', trim);
this.options.trimThreshold = 10;
} else if (is.number(trim)) {
if (trim >= 0) {
this.options.trimThreshold = trim;
} else {
throw is.invalidParameterError('threshold', 'positive number', trim);
}
} else if (is.object(trim)) {
this._setBackgroundColourOption('trimBackground', trim.background);
if (!is.defined(trim.threshold)) {
this.options.trimThreshold = 10;
} else if (is.number(trim.threshold) && trim.threshold >= 0) {
this.options.trimThreshold = trim.threshold;
} else {
throw is.invalidParameterError('threshold', 'positive number', trim);
}
} else {
throw is.invalidParameterError('trim', 'string, number or object', trim);
}
if (isRotationExpected(this.options)) {
this.options.rotateBeforePreExtract = true;
}
return this;
}
/**
* Decorate the Sharp prototype with resize-related functions.
* @private
*/
module.exports = function (Sharp) {
Object.assign(Sharp.prototype, {
resize,
extend,
extract,
trim
});
// Class attributes
Sharp.gravity = gravity;
Sharp.strategy = strategy;
Sharp.kernel = kernel;
Sharp.fit = fit;
Sharp.position = position;
};
+38
View File
@@ -0,0 +1,38 @@
// Copyright 2013 Lovell Fuller and others.
// SPDX-License-Identifier: Apache-2.0
'use strict';
const platformAndArch = require('./platform')();
/* istanbul ignore next */
try {
module.exports = require(`../build/Release/sharp-${platformAndArch}.node`);
} catch (err) {
// Bail early if bindings aren't available
const help = ['', 'Something went wrong installing the "sharp" module', '', err.message, '', 'Possible solutions:'];
if (/dylib/.test(err.message) && /Incompatible library version/.test(err.message)) {
help.push('- Update Homebrew: "brew update && brew upgrade vips"');
} else {
const [platform, arch] = platformAndArch.split('-');
if (platform === 'linux' && /Module did not self-register/.test(err.message)) {
help.push('- Using worker threads? See https://sharp.pixelplumbing.com/install#worker-threads');
}
help.push(
'- Install with verbose logging and look for errors: "npm install --ignore-scripts=false --foreground-scripts --verbose sharp"',
`- Install for the current ${platformAndArch} runtime: "npm install --platform=${platform} --arch=${arch} sharp"`
);
}
help.push(
'- Consult the installation documentation: https://sharp.pixelplumbing.com/install'
);
// Check loaded
if (process.platform === 'win32' || /symbol/.test(err.message)) {
const loadedModule = Object.keys(require.cache).find((i) => /[\\/]build[\\/]Release[\\/]sharp(.*)\.node$/.test(i));
if (loadedModule) {
const [, loadedPackage] = loadedModule.match(/node_modules[\\/]([^\\/]+)[\\/]/);
help.push(`- Ensure the version of sharp aligns with the ${loadedPackage} package: "npm ls sharp"`);
}
}
throw new Error(help.join('\n'));
}
+287
View File
@@ -0,0 +1,287 @@
// Copyright 2013 Lovell Fuller and others.
// SPDX-License-Identifier: Apache-2.0
'use strict';
const fs = require('fs');
const path = require('path');
const events = require('events');
const detectLibc = require('detect-libc');
const is = require('./is');
const platformAndArch = require('./platform')();
const sharp = require('./sharp');
/**
* An Object containing nested boolean values representing the available input and output formats/methods.
* @member
* @example
* console.log(sharp.format);
* @returns {Object}
*/
const format = sharp.format();
format.heif.output.alias = ['avif', 'heic'];
format.jpeg.output.alias = ['jpe', 'jpg'];
format.tiff.output.alias = ['tif'];
format.jp2k.output.alias = ['j2c', 'j2k', 'jp2', 'jpx'];
/**
* An Object containing the available interpolators and their proper values
* @readonly
* @enum {string}
*/
const interpolators = {
/** [Nearest neighbour interpolation](http://en.wikipedia.org/wiki/Nearest-neighbor_interpolation). Suitable for image enlargement only. */
nearest: 'nearest',
/** [Bilinear interpolation](http://en.wikipedia.org/wiki/Bilinear_interpolation). Faster than bicubic but with less smooth results. */
bilinear: 'bilinear',
/** [Bicubic interpolation](http://en.wikipedia.org/wiki/Bicubic_interpolation) (the default). */
bicubic: 'bicubic',
/** [LBB interpolation](https://github.com/libvips/libvips/blob/master/libvips/resample/lbb.cpp#L100). Prevents some "[acutance](http://en.wikipedia.org/wiki/Acutance)" but typically reduces performance by a factor of 2. */
locallyBoundedBicubic: 'lbb',
/** [Nohalo interpolation](http://eprints.soton.ac.uk/268086/). Prevents acutance but typically reduces performance by a factor of 3. */
nohalo: 'nohalo',
/** [VSQBS interpolation](https://github.com/libvips/libvips/blob/master/libvips/resample/vsqbs.cpp#L48). Prevents "staircasing" when enlarging. */
vertexSplitQuadraticBasisSpline: 'vsqbs'
};
/**
* An Object containing the version numbers of sharp, libvips and its dependencies.
* @member
* @example
* console.log(sharp.versions);
*/
let versions = {
vips: sharp.libvipsVersion()
};
try {
versions = require(`../vendor/${versions.vips}/${platformAndArch}/versions.json`);
} catch (_err) { /* ignore */ }
versions.sharp = require('../package.json').version;
/**
* An Object containing the platform and architecture
* of the current and installed vendored binaries.
* @member
* @example
* console.log(sharp.vendor);
*/
const vendor = {
current: platformAndArch,
installed: []
};
try {
vendor.installed = fs.readdirSync(path.join(__dirname, `../vendor/${versions.vips}`));
} catch (_err) { /* ignore */ }
/**
* Gets or, when options are provided, sets the limits of _libvips'_ operation cache.
* Existing entries in the cache will be trimmed after any change in limits.
* This method always returns cache statistics,
* useful for determining how much working memory is required for a particular task.
*
* @example
* const stats = sharp.cache();
* @example
* sharp.cache( { items: 200 } );
* sharp.cache( { files: 0 } );
* sharp.cache(false);
*
* @param {Object|boolean} [options=true] - Object with the following attributes, or boolean where true uses default cache settings and false removes all caching
* @param {number} [options.memory=50] - is the maximum memory in MB to use for this cache
* @param {number} [options.files=20] - is the maximum number of files to hold open
* @param {number} [options.items=100] - is the maximum number of operations to cache
* @returns {Object}
*/
function cache (options) {
if (is.bool(options)) {
if (options) {
// Default cache settings of 50MB, 20 files, 100 items
return sharp.cache(50, 20, 100);
} else {
return sharp.cache(0, 0, 0);
}
} else if (is.object(options)) {
return sharp.cache(options.memory, options.files, options.items);
} else {
return sharp.cache();
}
}
cache(true);
/**
* Gets or, when a concurrency is provided, sets
* the maximum number of threads _libvips_ should use to process _each image_.
* These are from a thread pool managed by glib,
* which helps avoid the overhead of creating new threads.
*
* This method always returns the current concurrency.
*
* The default value is the number of CPU cores,
* except when using glibc-based Linux without jemalloc,
* where the default is `1` to help reduce memory fragmentation.
*
* A value of `0` will reset this to the number of CPU cores.
*
* Some image format libraries spawn additional threads,
* e.g. libaom manages its own 4 threads when encoding AVIF images,
* and these are independent of the value set here.
*
* The maximum number of images that sharp can process in parallel
* is controlled by libuv's `UV_THREADPOOL_SIZE` environment variable,
* which defaults to 4.
*
* https://nodejs.org/api/cli.html#uv_threadpool_sizesize
*
* For example, by default, a machine with 8 CPU cores will process
* 4 images in parallel and use up to 8 threads per image,
* so there will be up to 32 concurrent threads.
*
* @example
* const threads = sharp.concurrency(); // 4
* sharp.concurrency(2); // 2
* sharp.concurrency(0); // 4
*
* @param {number} [concurrency]
* @returns {number} concurrency
*/
function concurrency (concurrency) {
return sharp.concurrency(is.integer(concurrency) ? concurrency : null);
}
/* istanbul ignore next */
if (detectLibc.familySync() === detectLibc.GLIBC && !sharp._isUsingJemalloc()) {
// Reduce default concurrency to 1 when using glibc memory allocator
sharp.concurrency(1);
}
/**
* An EventEmitter that emits a `change` event when a task is either:
* - queued, waiting for _libuv_ to provide a worker thread
* - complete
* @member
* @example
* sharp.queue.on('change', function(queueLength) {
* console.log('Queue contains ' + queueLength + ' task(s)');
* });
*/
const queue = new events.EventEmitter();
/**
* Provides access to internal task counters.
* - queue is the number of tasks this module has queued waiting for _libuv_ to provide a worker thread from its pool.
* - process is the number of resize tasks currently being processed.
*
* @example
* const counters = sharp.counters(); // { queue: 2, process: 4 }
*
* @returns {Object}
*/
function counters () {
return sharp.counters();
}
/**
* Get and set use of SIMD vector unit instructions.
* Requires libvips to have been compiled with liborc support.
*
* Improves the performance of `resize`, `blur` and `sharpen` operations
* by taking advantage of the SIMD vector unit of the CPU, e.g. Intel SSE and ARM NEON.
*
* @example
* const simd = sharp.simd();
* // simd is `true` if the runtime use of liborc is currently enabled
* @example
* const simd = sharp.simd(false);
* // prevent libvips from using liborc at runtime
*
* @param {boolean} [simd=true]
* @returns {boolean}
*/
function simd (simd) {
return sharp.simd(is.bool(simd) ? simd : null);
}
simd(true);
/**
* Block libvips operations at runtime.
*
* This is in addition to the `VIPS_BLOCK_UNTRUSTED` environment variable,
* which when set will block all "untrusted" operations.
*
* @since 0.32.4
*
* @example <caption>Block all TIFF input.</caption>
* sharp.block({
* operation: ['VipsForeignLoadTiff']
* });
*
* @param {Object} options
* @param {Array<string>} options.operation - List of libvips low-level operation names to block.
*/
function block (options) {
if (is.object(options)) {
if (Array.isArray(options.operation) && options.operation.every(is.string)) {
sharp.block(options.operation, true);
} else {
throw is.invalidParameterError('operation', 'Array<string>', options.operation);
}
} else {
throw is.invalidParameterError('options', 'object', options);
}
}
/**
* Unblock libvips operations at runtime.
*
* This is useful for defining a list of allowed operations.
*
* @since 0.32.4
*
* @example <caption>Block all input except WebP from the filesystem.</caption>
* sharp.block({
* operation: ['VipsForeignLoad']
* });
* sharp.unblock({
* operation: ['VipsForeignLoadWebpFile']
* });
*
* @example <caption>Block all input except JPEG and PNG from a Buffer or Stream.</caption>
* sharp.block({
* operation: ['VipsForeignLoad']
* });
* sharp.unblock({
* operation: ['VipsForeignLoadJpegBuffer', 'VipsForeignLoadPngBuffer']
* });
*
* @param {Object} options
* @param {Array<string>} options.operation - List of libvips low-level operation names to unblock.
*/
function unblock (options) {
if (is.object(options)) {
if (Array.isArray(options.operation) && options.operation.every(is.string)) {
sharp.block(options.operation, false);
} else {
throw is.invalidParameterError('operation', 'Array<string>', options.operation);
}
} else {
throw is.invalidParameterError('options', 'object', options);
}
}
/**
* Decorate the Sharp class with utility-related functions.
* @private
*/
module.exports = function (Sharp) {
Sharp.cache = cache;
Sharp.concurrency = concurrency;
Sharp.counters = counters;
Sharp.simd = simd;
Sharp.format = format;
Sharp.interpolators = interpolators;
Sharp.versions = versions;
Sharp.vendor = vendor;
Sharp.queue = queue;
Sharp.block = block;
Sharp.unblock = unblock;
};
+204
View File
@@ -0,0 +1,204 @@
{
"name": "sharp",
"description": "High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP, GIF, AVIF and TIFF images",
"version": "0.32.6",
"author": "Lovell Fuller <npm@lovell.info>",
"homepage": "https://github.com/lovell/sharp",
"contributors": [
"Pierre Inglebert <pierre.inglebert@gmail.com>",
"Jonathan Ong <jonathanrichardong@gmail.com>",
"Chanon Sajjamanochai <chanon.s@gmail.com>",
"Juliano Julio <julianojulio@gmail.com>",
"Daniel Gasienica <daniel@gasienica.ch>",
"Julian Walker <julian@fiftythree.com>",
"Amit Pitaru <pitaru.amit@gmail.com>",
"Brandon Aaron <hello.brandon@aaron.sh>",
"Andreas Lind <andreas@one.com>",
"Maurus Cuelenaere <mcuelenaere@gmail.com>",
"Linus Unnebäck <linus@folkdatorn.se>",
"Victor Mateevitsi <mvictoras@gmail.com>",
"Alaric Holloway <alaric.holloway@gmail.com>",
"Bernhard K. Weisshuhn <bkw@codingforce.com>",
"Chris Riley <criley@primedia.com>",
"David Carley <dacarley@gmail.com>",
"John Tobin <john@limelightmobileinc.com>",
"Kenton Gray <kentongray@gmail.com>",
"Felix Bünemann <Felix.Buenemann@gmail.com>",
"Samy Al Zahrani <samyalzahrany@gmail.com>",
"Chintan Thakkar <lemnisk8@gmail.com>",
"F. Orlando Galashan <frulo@gmx.de>",
"Kleis Auke Wolthuizen <info@kleisauke.nl>",
"Matt Hirsch <mhirsch@media.mit.edu>",
"Matthias Thoemmes <thoemmes@gmail.com>",
"Patrick Paskaris <patrick@paskaris.gr>",
"Jérémy Lal <kapouer@melix.org>",
"Rahul Nanwani <r.nanwani@gmail.com>",
"Alice Monday <alice0meta@gmail.com>",
"Kristo Jorgenson <kristo.jorgenson@gmail.com>",
"YvesBos <yves_bos@outlook.com>",
"Guy Maliar <guy@tailorbrands.com>",
"Nicolas Coden <nicolas@ncoden.fr>",
"Matt Parrish <matt.r.parrish@gmail.com>",
"Marcel Bretschneider <marcel.bretschneider@gmail.com>",
"Matthew McEachen <matthew+github@mceachen.org>",
"Jarda Kotěšovec <jarda.kotesovec@gmail.com>",
"Kenric D'Souza <kenric.dsouza@gmail.com>",
"Oleh Aleinyk <oleg.aleynik@gmail.com>",
"Marcel Bretschneider <marcel.bretschneider@gmail.com>",
"Andrea Bianco <andrea.bianco@unibas.ch>",
"Rik Heywood <rik@rik.org>",
"Thomas Parisot <hi@oncletom.io>",
"Nathan Graves <nathanrgraves+github@gmail.com>",
"Tom Lokhorst <tom@lokhorst.eu>",
"Espen Hovlandsdal <espen@hovlandsdal.com>",
"Sylvain Dumont <sylvain.dumont35@gmail.com>",
"Alun Davies <alun.owain.davies@googlemail.com>",
"Aidan Hoolachan <ajhoolachan21@gmail.com>",
"Axel Eirola <axel.eirola@iki.fi>",
"Freezy <freezy@xbmc.org>",
"Daiz <taneli.vatanen@gmail.com>",
"Julian Aubourg <j@ubourg.net>",
"Keith Belovay <keith@picthrive.com>",
"Michael B. Klein <mbklein@gmail.com>",
"Jordan Prudhomme <jordan@raboland.fr>",
"Ilya Ovdin <iovdin@gmail.com>",
"Andargor <andargor@yahoo.com>",
"Paul Neave <paul.neave@gmail.com>",
"Brendan Kennedy <brenwken@gmail.com>",
"Brychan Bennett-Odlum <git@brychan.io>",
"Edward Silverton <e.silverton@gmail.com>",
"Roman Malieiev <aromaleev@gmail.com>",
"Tomas Szabo <tomas.szabo@deftomat.com>",
"Robert O'Rourke <robert@o-rourke.org>",
"Guillermo Alfonso Varela Chouciño <guillevch@gmail.com>",
"Christian Flintrup <chr@gigahost.dk>",
"Manan Jadhav <manan@motionden.com>",
"Leon Radley <leon@radley.se>",
"alza54 <alza54@thiocod.in>",
"Jacob Smith <jacob@frende.me>",
"Michael Nutt <michael@nutt.im>",
"Brad Parham <baparham@gmail.com>",
"Taneli Vatanen <taneli.vatanen@gmail.com>",
"Joris Dugué <zaruike10@gmail.com>",
"Chris Banks <christopher.bradley.banks@gmail.com>",
"Ompal Singh <ompal.hitm09@gmail.com>",
"Brodan <christopher.hranj@gmail.com",
"Ankur Parihar <ankur.github@gmail.com>",
"Brahim Ait elhaj <brahima@gmail.com>",
"Mart Jansink <m.jansink@gmail.com>",
"Lachlan Newman <lachnewman007@gmail.com>"
],
"scripts": {
"install": "(node install/libvips && node install/dll-copy && prebuild-install) || (node install/can-compile && node-gyp rebuild && node install/dll-copy)",
"clean": "rm -rf node_modules/ build/ vendor/ .nyc_output/ coverage/ test/fixtures/output.*",
"test": "npm run test-lint && npm run test-unit && npm run test-licensing && npm run test-types",
"test-lint": "semistandard && cpplint",
"test-unit": "nyc --reporter=lcov --reporter=text --check-coverage --branches=100 mocha",
"test-licensing": "license-checker --production --summary --onlyAllow=\"Apache-2.0;BSD;ISC;MIT\"",
"test-leak": "./test/leak/leak.sh",
"test-types": "tsd",
"docs-build": "node docs/build && node docs/search-index/build",
"docs-serve": "cd docs && npx serve",
"docs-publish": "cd docs && npx firebase-tools deploy --project pixelplumbing --only hosting:pixelplumbing-sharp"
},
"main": "lib/index.js",
"types": "lib/index.d.ts",
"files": [
"binding.gyp",
"install/**",
"lib/**",
"src/**"
],
"repository": {
"type": "git",
"url": "git://github.com/lovell/sharp"
},
"keywords": [
"jpeg",
"png",
"webp",
"avif",
"tiff",
"gif",
"svg",
"jp2",
"dzi",
"image",
"resize",
"thumbnail",
"crop",
"embed",
"libvips",
"vips"
],
"dependencies": {
"color": "^4.2.3",
"detect-libc": "^2.0.2",
"node-addon-api": "^6.1.0",
"prebuild-install": "^7.1.1",
"semver": "^7.5.4",
"simple-get": "^4.0.1",
"tar-fs": "^3.0.4",
"tunnel-agent": "^0.6.0"
},
"devDependencies": {
"@types/node": "*",
"async": "^3.2.4",
"cc": "^3.0.1",
"exif-reader": "^1.2.0",
"extract-zip": "^2.0.1",
"icc": "^3.0.0",
"jsdoc-to-markdown": "^8.0.0",
"license-checker": "^25.0.1",
"mocha": "^10.2.0",
"mock-fs": "^5.2.0",
"nyc": "^15.1.0",
"prebuild": "^12.0.0",
"semistandard": "^16.0.1",
"tsd": "^0.29.0"
},
"license": "Apache-2.0",
"config": {
"libvips": "8.14.5",
"integrity": {
"darwin-arm64v8": "sha512-1QZzICfCJd4wAO0P6qmYI5e5VFMt9iCE4QgefI8VMMbdSzjIXA9L/ARN6pkMQPZ3h20Y9RtJ2W1skgCsvCIccw==",
"darwin-x64": "sha512-sMIKMYXsdU9FlIfztj6Kt/SfHlhlDpP0Ups7ftVFqwjaszmYmpI9y/d/q3mLb4jrzuSiSUEislSWCwBnW7MPTw==",
"linux-arm64v8": "sha512-CD8owELzkDumaom+O3jJ8fKamILAQdj+//KK/VNcHK3sngUcFpdjx36C8okwbux9sml/T7GTB/gzpvReDrAejQ==",
"linux-armv6": "sha512-wk6IPHatDFVWKJy7lI1TJezHGHPQut1wF2bwx256KlZwXUQU3fcVcMpV1zxXjgLFewHq2+uhyMkoSGBPahWzlA==",
"linux-armv7": "sha512-HEZC9KYtkmBK5rUR2MqBhrVarnQVZ/TwLUeLkKq0XuoM2pc/eXI6N0Fh5NGEFwdXI2XE8g1ySf+OYS6DDi+xCQ==",
"linux-x64": "sha512-SlFWrITSW5XVUkaFPQOySAaSGXnhkGJCj8X2wGYYta9hk5piZldQyMp4zwy0z6UeRu1qKTKtZvmq28W3Gnh9xA==",
"linuxmusl-arm64v8": "sha512-ga9iX7WUva3sG/VsKkOD318InLlCfPIztvzCZKZ2/+izQXRbQi8VoXWMHgEN4KHACv45FTl7mJ/8CRqUzhS8wQ==",
"linuxmusl-x64": "sha512-yeaHnpfee1hrZLok2l4eFceHzlfq8gN3QOu0R4Mh8iMK5O5vAUu97bdtxeZZeJJvHw8tfh2/msGi0qysxKN8bw==",
"win32-arm64v8": "sha512-kR91hy9w1+GEXK56hLh51+hBCBo7T+ijM4Slkmvb/2PsYZySq5H7s61n99iDYl6kTJP2y9sW5Xcvm3uuXDaDgg==",
"win32-ia32": "sha512-HrnofEbzHNpHJ0vVnjsTj5yfgVdcqdWshXuwFO2zc8xlEjA83BvXZ0lVj9MxPxkxJ2ta+/UlLr+CFzc5bOceMw==",
"win32-x64": "sha512-BwKckinJZ0Fu/EcunqiLPwOLEBWp4xf8GV7nvmVuKKz5f6B+GxoA2k9aa2wueqv4r4RJVgV/aWXZWFKOIjre/Q=="
},
"runtime": "napi",
"target": 7
},
"engines": {
"node": ">=14.15.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"binary": {
"napi_versions": [
7
]
},
"semistandard": {
"env": [
"mocha"
]
},
"cc": {
"linelength": "120",
"filter": [
"build/include"
]
},
"tsd": {
"directory": "test/types/"
}
}
+1042
View File
File diff suppressed because it is too large Load Diff
+377
View File
@@ -0,0 +1,377 @@
// Copyright 2013 Lovell Fuller and others.
// SPDX-License-Identifier: Apache-2.0
#ifndef SRC_COMMON_H_
#define SRC_COMMON_H_
#include <string>
#include <tuple>
#include <vector>
#include <napi.h>
#include <vips/vips8>
// Verify platform and compiler compatibility
#if (VIPS_MAJOR_VERSION < 8) || \
(VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION < 14) || \
(VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION == 14 && VIPS_MICRO_VERSION < 5)
#error "libvips version 8.14.5+ is required - please see https://sharp.pixelplumbing.com/install"
#endif
#if ((!defined(__clang__)) && defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 6)))
#error "GCC version 4.6+ is required for C++11 features - please see https://sharp.pixelplumbing.com/install"
#endif
#if (defined(__clang__) && defined(__has_feature))
#if (!__has_feature(cxx_range_for))
#error "clang version 3.0+ is required for C++11 features - please see https://sharp.pixelplumbing.com/install"
#endif
#endif
using vips::VImage;
namespace sharp {
struct InputDescriptor { // NOLINT(runtime/indentation_namespace)
std::string name;
std::string file;
char *buffer;
VipsFailOn failOn;
uint64_t limitInputPixels;
bool unlimited;
VipsAccess access;
size_t bufferLength;
bool isBuffer;
double density;
bool ignoreIcc;
VipsBandFormat rawDepth;
int rawChannels;
int rawWidth;
int rawHeight;
bool rawPremultiplied;
int pages;
int page;
int level;
int subifd;
int createChannels;
int createWidth;
int createHeight;
std::vector<double> createBackground;
std::string createNoiseType;
double createNoiseMean;
double createNoiseSigma;
std::string textValue;
std::string textFont;
std::string textFontfile;
int textWidth;
int textHeight;
VipsAlign textAlign;
bool textJustify;
int textDpi;
bool textRgba;
int textSpacing;
VipsTextWrap textWrap;
int textAutofitDpi;
InputDescriptor():
buffer(nullptr),
failOn(VIPS_FAIL_ON_WARNING),
limitInputPixels(0x3FFF * 0x3FFF),
unlimited(FALSE),
access(VIPS_ACCESS_RANDOM),
bufferLength(0),
isBuffer(FALSE),
density(72.0),
ignoreIcc(FALSE),
rawDepth(VIPS_FORMAT_UCHAR),
rawChannels(0),
rawWidth(0),
rawHeight(0),
rawPremultiplied(false),
pages(1),
page(0),
level(0),
subifd(-1),
createChannels(0),
createWidth(0),
createHeight(0),
createBackground{ 0.0, 0.0, 0.0, 255.0 },
createNoiseMean(0.0),
createNoiseSigma(0.0),
textWidth(0),
textHeight(0),
textAlign(VIPS_ALIGN_LOW),
textJustify(FALSE),
textDpi(72),
textRgba(FALSE),
textSpacing(0),
textWrap(VIPS_TEXT_WRAP_WORD),
textAutofitDpi(0) {}
};
// Convenience methods to access the attributes of a Napi::Object
bool HasAttr(Napi::Object obj, std::string attr);
std::string AttrAsStr(Napi::Object obj, std::string attr);
std::string AttrAsStr(Napi::Object obj, unsigned int const attr);
uint32_t AttrAsUint32(Napi::Object obj, std::string attr);
int32_t AttrAsInt32(Napi::Object obj, std::string attr);
int32_t AttrAsInt32(Napi::Object obj, unsigned int const attr);
double AttrAsDouble(Napi::Object obj, std::string attr);
double AttrAsDouble(Napi::Object obj, unsigned int const attr);
bool AttrAsBool(Napi::Object obj, std::string attr);
std::vector<double> AttrAsVectorOfDouble(Napi::Object obj, std::string attr);
std::vector<int32_t> AttrAsInt32Vector(Napi::Object obj, std::string attr);
template <class T> T AttrAsEnum(Napi::Object obj, std::string attr, GType type) {
return static_cast<T>(
vips_enum_from_nick(nullptr, type, AttrAsStr(obj, attr).data()));
}
// Create an InputDescriptor instance from a Napi::Object describing an input image
InputDescriptor* CreateInputDescriptor(Napi::Object input);
enum class ImageType {
JPEG,
PNG,
WEBP,
JP2,
TIFF,
GIF,
SVG,
HEIF,
PDF,
MAGICK,
OPENSLIDE,
PPM,
FITS,
EXR,
JXL,
VIPS,
RAW,
UNKNOWN,
MISSING
};
enum class Canvas {
CROP,
EMBED,
MAX,
MIN,
IGNORE_ASPECT
};
// How many tasks are in the queue?
extern volatile int counterQueue;
// How many tasks are being processed?
extern volatile int counterProcess;
// Filename extension checkers
bool IsJpeg(std::string const &str);
bool IsPng(std::string const &str);
bool IsWebp(std::string const &str);
bool IsJp2(std::string const &str);
bool IsGif(std::string const &str);
bool IsTiff(std::string const &str);
bool IsHeic(std::string const &str);
bool IsHeif(std::string const &str);
bool IsAvif(std::string const &str);
bool IsJxl(std::string const &str);
bool IsDz(std::string const &str);
bool IsDzZip(std::string const &str);
bool IsV(std::string const &str);
/*
Trim space from end of string.
*/
std::string TrimEnd(std::string const &str);
/*
Provide a string identifier for the given image type.
*/
std::string ImageTypeId(ImageType const imageType);
/*
Determine image format of a buffer.
*/
ImageType DetermineImageType(void *buffer, size_t const length);
/*
Determine image format of a file.
*/
ImageType DetermineImageType(char const *file);
/*
Does this image type support multiple pages?
*/
bool ImageTypeSupportsPage(ImageType imageType);
/*
Does this image type support removal of safety limits?
*/
bool ImageTypeSupportsUnlimited(ImageType imageType);
/*
Open an image from the given InputDescriptor (filesystem, compressed buffer, raw pixel data)
*/
std::tuple<VImage, ImageType> OpenInput(InputDescriptor *descriptor);
/*
Does this image have an embedded profile?
*/
bool HasProfile(VImage image);
/*
Does this image have an alpha channel?
Uses colour space interpretation with number of channels to guess this.
*/
bool HasAlpha(VImage image);
/*
Get EXIF Orientation of image, if any.
*/
int ExifOrientation(VImage image);
/*
Set EXIF Orientation of image.
*/
VImage SetExifOrientation(VImage image, int const orientation);
/*
Remove EXIF Orientation from image.
*/
VImage RemoveExifOrientation(VImage image);
/*
Set animation properties if necessary.
*/
VImage SetAnimationProperties(VImage image, int nPages, int pageHeight, std::vector<int> delay, int loop);
/*
Remove animation properties from image.
*/
VImage RemoveAnimationProperties(VImage image);
/*
Remove GIF palette from image.
*/
VImage RemoveGifPalette(VImage image);
/*
Does this image have a non-default density?
*/
bool HasDensity(VImage image);
/*
Get pixels/mm resolution as pixels/inch density.
*/
int GetDensity(VImage image);
/*
Set pixels/mm resolution based on a pixels/inch density.
*/
VImage SetDensity(VImage image, const double density);
/*
Multi-page images can have a page height. Fetch it, and sanity check it.
If page-height is not set, it defaults to the image height
*/
int GetPageHeight(VImage image);
/*
Check the proposed format supports the current dimensions.
*/
void AssertImageTypeDimensions(VImage image, ImageType const imageType);
/*
Called when a Buffer undergoes GC, required to support mixed runtime libraries in Windows
*/
extern std::function<void(void*, char*)> FreeCallback;
/*
Called with warnings from the glib-registered "VIPS" domain
*/
void VipsWarningCallback(char const* log_domain, GLogLevelFlags log_level, char const* message, void* ignore);
/*
Pop the oldest warning message from the queue
*/
std::string VipsWarningPop();
/*
Attach an event listener for progress updates, used to detect timeout
*/
void SetTimeout(VImage image, int const timeoutSeconds);
/*
Event listener for progress updates, used to detect timeout
*/
void VipsProgressCallBack(VipsImage *image, VipsProgress *progress, int *timeoutSeconds);
/*
Calculate the (left, top) coordinates of the output image
within the input image, applying the given gravity during an embed.
*/
std::tuple<int, int> CalculateEmbedPosition(int const inWidth, int const inHeight,
int const outWidth, int const outHeight, int const gravity);
/*
Calculate the (left, top) coordinates of the output image
within the input image, applying the given gravity.
*/
std::tuple<int, int> CalculateCrop(int const inWidth, int const inHeight,
int const outWidth, int const outHeight, int const gravity);
/*
Calculate the (left, top) coordinates of the output image
within the input image, applying the given x and y offsets of the output image.
*/
std::tuple<int, int> CalculateCrop(int const inWidth, int const inHeight,
int const outWidth, int const outHeight, int const x, int const y);
/*
Are pixel values in this image 16-bit integer?
*/
bool Is16Bit(VipsInterpretation const interpretation);
/*
Return the image alpha maximum. Useful for combining alpha bands. scRGB
images are 0 - 1 for image data, but the alpha is 0 - 255.
*/
double MaximumImageAlpha(VipsInterpretation const interpretation);
/*
Convert RGBA value to another colourspace
*/
std::vector<double> GetRgbaAsColourspace(std::vector<double> const rgba,
VipsInterpretation const interpretation, bool premultiply);
/*
Apply the alpha channel to a given colour
*/
std::tuple<VImage, std::vector<double>> ApplyAlpha(VImage image, std::vector<double> colour, bool premultiply);
/*
Removes alpha channel, if any.
*/
VImage RemoveAlpha(VImage image);
/*
Ensures alpha channel, if missing.
*/
VImage EnsureAlpha(VImage image, double const value);
/*
Calculate the horizontal and vertical shrink factors, taking the canvas mode into account.
*/
std::pair<double, double> ResolveShrink(int width, int height, int targetWidth, int targetHeight,
Canvas canvas, bool withoutEnlargement, bool withoutReduction);
/*
Ensure decoding remains sequential.
*/
VImage StaySequential(VImage image, VipsAccess access, bool condition = TRUE);
} // namespace sharp
#endif // SRC_COMMON_H_
+151
View File
@@ -0,0 +1,151 @@
/* Object part of the VSource and VTarget class
*/
/*
Copyright (C) 1991-2001 The National Gallery
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
/*
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif /*HAVE_CONFIG_H*/
#include <vips/vips8>
#include <vips/debug.h>
/*
#define VIPS_DEBUG
#define VIPS_DEBUG_VERBOSE
*/
VIPS_NAMESPACE_START
VSource
VSource::new_from_descriptor( int descriptor )
{
VipsSource *input;
if( !(input = vips_source_new_from_descriptor( descriptor )) )
throw VError();
VSource out( input );
return( out );
}
VSource
VSource::new_from_file( const char *filename )
{
VipsSource *input;
if( !(input = vips_source_new_from_file( filename )) )
throw VError();
VSource out( input );
return( out );
}
VSource
VSource::new_from_blob( VipsBlob *blob )
{
VipsSource *input;
if( !(input = vips_source_new_from_blob( blob )) )
throw VError();
VSource out( input );
return( out );
}
VSource
VSource::new_from_memory( const void *data,
size_t size )
{
VipsSource *input;
if( !(input = vips_source_new_from_memory( data, size )) )
throw VError();
VSource out( input );
return( out );
}
VSource
VSource::new_from_options( const char *options )
{
VipsSource *input;
if( !(input = vips_source_new_from_options( options )) )
throw VError();
VSource out( input );
return( out );
}
VTarget
VTarget::new_to_descriptor( int descriptor )
{
VipsTarget *output;
if( !(output = vips_target_new_to_descriptor( descriptor )) )
throw VError();
VTarget out( output );
return( out );
}
VTarget
VTarget::new_to_file( const char *filename )
{
VipsTarget *output;
if( !(output = vips_target_new_to_file( filename )) )
throw VError();
VTarget out( output );
return( out );
}
VTarget
VTarget::new_to_memory()
{
VipsTarget *output;
if( !(output = vips_target_new_to_memory()) )
throw VError();
VTarget out( output );
return( out );
}
VIPS_NAMESPACE_END
+49
View File
@@ -0,0 +1,49 @@
// Code for error type
/*
Copyright (C) 1991-2001 The National Gallery
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
/*
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif /*HAVE_CONFIG_H*/
#include <vips/vips8>
VIPS_NAMESPACE_START
std::ostream &operator<<( std::ostream &file, const VError &err )
{
err.ostream_print( file );
return( file );
}
void VError::ostream_print( std::ostream &file ) const
{
file << _what;
}
VIPS_NAMESPACE_END
File diff suppressed because it is too large Load Diff
+62
View File
@@ -0,0 +1,62 @@
/* Object part of VInterpolate class
*/
/*
Copyright (C) 1991-2001 The National Gallery
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
/*
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif /*HAVE_CONFIG_H*/
#include <vips/vips8>
#include <vips/debug.h>
/*
#define VIPS_DEBUG
#define VIPS_DEBUG_VERBOSE
*/
VIPS_NAMESPACE_START
VInterpolate
VInterpolate::new_from_name( const char *name, VOption *options )
{
VipsInterpolate *interp;
if( !(interp = vips_interpolate_new( name )) ) {
delete options;
throw VError();
}
delete options;
VInterpolate out( interp );
return( out );
}
VIPS_NAMESPACE_END
+27
View File
@@ -0,0 +1,27 @@
// Object part of VRegion class
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif /*HAVE_CONFIG_H*/
#include <vips/vips8>
#include <vips/debug.h>
VIPS_NAMESPACE_START
VRegion
VRegion::new_from_image( VImage image )
{
VipsRegion *region;
if( !(region = vips_region_new( image.get_image() )) ) {
throw VError();
}
VRegion out( region );
return( out );
}
VIPS_NAMESPACE_END
File diff suppressed because it is too large Load Diff
+287
View File
@@ -0,0 +1,287 @@
// Copyright 2013 Lovell Fuller and others.
// SPDX-License-Identifier: Apache-2.0
#include <numeric>
#include <vector>
#include <napi.h>
#include <vips/vips8>
#include "common.h"
#include "metadata.h"
class MetadataWorker : public Napi::AsyncWorker {
public:
MetadataWorker(Napi::Function callback, MetadataBaton *baton, Napi::Function debuglog) :
Napi::AsyncWorker(callback), baton(baton), debuglog(Napi::Persistent(debuglog)) {}
~MetadataWorker() {}
void Execute() {
// Decrement queued task counter
g_atomic_int_dec_and_test(&sharp::counterQueue);
vips::VImage image;
sharp::ImageType imageType = sharp::ImageType::UNKNOWN;
try {
std::tie(image, imageType) = OpenInput(baton->input);
} catch (vips::VError const &err) {
(baton->err).append(err.what());
}
if (imageType != sharp::ImageType::UNKNOWN) {
// Image type
baton->format = sharp::ImageTypeId(imageType);
// VipsImage attributes
baton->width = image.width();
baton->height = image.height();
baton->space = vips_enum_nick(VIPS_TYPE_INTERPRETATION, image.interpretation());
baton->channels = image.bands();
baton->depth = vips_enum_nick(VIPS_TYPE_BAND_FORMAT, image.format());
if (sharp::HasDensity(image)) {
baton->density = sharp::GetDensity(image);
}
if (image.get_typeof("jpeg-chroma-subsample") == VIPS_TYPE_REF_STRING) {
baton->chromaSubsampling = image.get_string("jpeg-chroma-subsample");
}
if (image.get_typeof("interlaced") == G_TYPE_INT) {
baton->isProgressive = image.get_int("interlaced") == 1;
}
if (image.get_typeof("palette-bit-depth") == G_TYPE_INT) {
baton->paletteBitDepth = image.get_int("palette-bit-depth");
}
if (image.get_typeof(VIPS_META_N_PAGES) == G_TYPE_INT) {
baton->pages = image.get_int(VIPS_META_N_PAGES);
}
if (image.get_typeof(VIPS_META_PAGE_HEIGHT) == G_TYPE_INT) {
baton->pageHeight = image.get_int(VIPS_META_PAGE_HEIGHT);
}
if (image.get_typeof("loop") == G_TYPE_INT) {
baton->loop = image.get_int("loop");
}
if (image.get_typeof("delay") == VIPS_TYPE_ARRAY_INT) {
baton->delay = image.get_array_int("delay");
}
if (image.get_typeof("heif-primary") == G_TYPE_INT) {
baton->pagePrimary = image.get_int("heif-primary");
}
if (image.get_typeof("heif-compression") == VIPS_TYPE_REF_STRING) {
baton->compression = image.get_string("heif-compression");
}
if (image.get_typeof(VIPS_META_RESOLUTION_UNIT) == VIPS_TYPE_REF_STRING) {
baton->resolutionUnit = image.get_string(VIPS_META_RESOLUTION_UNIT);
}
if (image.get_typeof("magick-format") == VIPS_TYPE_REF_STRING) {
baton->formatMagick = image.get_string("magick-format");
}
if (image.get_typeof("openslide.level-count") == VIPS_TYPE_REF_STRING) {
int const levels = std::stoi(image.get_string("openslide.level-count"));
for (int l = 0; l < levels; l++) {
std::string prefix = "openslide.level[" + std::to_string(l) + "].";
int const width = std::stoi(image.get_string((prefix + "width").data()));
int const height = std::stoi(image.get_string((prefix + "height").data()));
baton->levels.push_back(std::pair<int, int>(width, height));
}
}
if (image.get_typeof(VIPS_META_N_SUBIFDS) == G_TYPE_INT) {
baton->subifds = image.get_int(VIPS_META_N_SUBIFDS);
}
baton->hasProfile = sharp::HasProfile(image);
if (image.get_typeof("background") == VIPS_TYPE_ARRAY_DOUBLE) {
baton->background = image.get_array_double("background");
}
// Derived attributes
baton->hasAlpha = sharp::HasAlpha(image);
baton->orientation = sharp::ExifOrientation(image);
// EXIF
if (image.get_typeof(VIPS_META_EXIF_NAME) == VIPS_TYPE_BLOB) {
size_t exifLength;
void const *exif = image.get_blob(VIPS_META_EXIF_NAME, &exifLength);
baton->exif = static_cast<char*>(g_malloc(exifLength));
memcpy(baton->exif, exif, exifLength);
baton->exifLength = exifLength;
}
// ICC profile
if (image.get_typeof(VIPS_META_ICC_NAME) == VIPS_TYPE_BLOB) {
size_t iccLength;
void const *icc = image.get_blob(VIPS_META_ICC_NAME, &iccLength);
baton->icc = static_cast<char*>(g_malloc(iccLength));
memcpy(baton->icc, icc, iccLength);
baton->iccLength = iccLength;
}
// IPTC
if (image.get_typeof(VIPS_META_IPTC_NAME) == VIPS_TYPE_BLOB) {
size_t iptcLength;
void const *iptc = image.get_blob(VIPS_META_IPTC_NAME, &iptcLength);
baton->iptc = static_cast<char *>(g_malloc(iptcLength));
memcpy(baton->iptc, iptc, iptcLength);
baton->iptcLength = iptcLength;
}
// XMP
if (image.get_typeof(VIPS_META_XMP_NAME) == VIPS_TYPE_BLOB) {
size_t xmpLength;
void const *xmp = image.get_blob(VIPS_META_XMP_NAME, &xmpLength);
baton->xmp = static_cast<char *>(g_malloc(xmpLength));
memcpy(baton->xmp, xmp, xmpLength);
baton->xmpLength = xmpLength;
}
// TIFFTAG_PHOTOSHOP
if (image.get_typeof(VIPS_META_PHOTOSHOP_NAME) == VIPS_TYPE_BLOB) {
size_t tifftagPhotoshopLength;
void const *tifftagPhotoshop = image.get_blob(VIPS_META_PHOTOSHOP_NAME, &tifftagPhotoshopLength);
baton->tifftagPhotoshop = static_cast<char *>(g_malloc(tifftagPhotoshopLength));
memcpy(baton->tifftagPhotoshop, tifftagPhotoshop, tifftagPhotoshopLength);
baton->tifftagPhotoshopLength = tifftagPhotoshopLength;
}
}
// Clean up
vips_error_clear();
vips_thread_shutdown();
}
void OnOK() {
Napi::Env env = Env();
Napi::HandleScope scope(env);
// Handle warnings
std::string warning = sharp::VipsWarningPop();
while (!warning.empty()) {
debuglog.MakeCallback(Receiver().Value(), { Napi::String::New(env, warning) });
warning = sharp::VipsWarningPop();
}
if (baton->err.empty()) {
Napi::Object info = Napi::Object::New(env);
info.Set("format", baton->format);
if (baton->input->bufferLength > 0) {
info.Set("size", baton->input->bufferLength);
}
info.Set("width", baton->width);
info.Set("height", baton->height);
info.Set("space", baton->space);
info.Set("channels", baton->channels);
info.Set("depth", baton->depth);
if (baton->density > 0) {
info.Set("density", baton->density);
}
if (!baton->chromaSubsampling.empty()) {
info.Set("chromaSubsampling", baton->chromaSubsampling);
}
info.Set("isProgressive", baton->isProgressive);
if (baton->paletteBitDepth > 0) {
info.Set("paletteBitDepth", baton->paletteBitDepth);
}
if (baton->pages > 0) {
info.Set("pages", baton->pages);
}
if (baton->pageHeight > 0) {
info.Set("pageHeight", baton->pageHeight);
}
if (baton->loop >= 0) {
info.Set("loop", baton->loop);
}
if (!baton->delay.empty()) {
int i = 0;
Napi::Array delay = Napi::Array::New(env, static_cast<size_t>(baton->delay.size()));
for (int const d : baton->delay) {
delay.Set(i++, d);
}
info.Set("delay", delay);
}
if (baton->pagePrimary > -1) {
info.Set("pagePrimary", baton->pagePrimary);
}
if (!baton->compression.empty()) {
info.Set("compression", baton->compression);
}
if (!baton->resolutionUnit.empty()) {
info.Set("resolutionUnit", baton->resolutionUnit == "in" ? "inch" : baton->resolutionUnit);
}
if (!baton->formatMagick.empty()) {
info.Set("formatMagick", baton->formatMagick);
}
if (!baton->levels.empty()) {
int i = 0;
Napi::Array levels = Napi::Array::New(env, static_cast<size_t>(baton->levels.size()));
for (std::pair<int, int> const &l : baton->levels) {
Napi::Object level = Napi::Object::New(env);
level.Set("width", l.first);
level.Set("height", l.second);
levels.Set(i++, level);
}
info.Set("levels", levels);
}
if (baton->subifds > 0) {
info.Set("subifds", baton->subifds);
}
if (!baton->background.empty()) {
if (baton->background.size() == 3) {
Napi::Object background = Napi::Object::New(env);
background.Set("r", baton->background[0]);
background.Set("g", baton->background[1]);
background.Set("b", baton->background[2]);
info.Set("background", background);
} else {
info.Set("background", baton->background[0]);
}
}
info.Set("hasProfile", baton->hasProfile);
info.Set("hasAlpha", baton->hasAlpha);
if (baton->orientation > 0) {
info.Set("orientation", baton->orientation);
}
if (baton->exifLength > 0) {
info.Set("exif", Napi::Buffer<char>::NewOrCopy(env, baton->exif, baton->exifLength, sharp::FreeCallback));
}
if (baton->iccLength > 0) {
info.Set("icc", Napi::Buffer<char>::NewOrCopy(env, baton->icc, baton->iccLength, sharp::FreeCallback));
}
if (baton->iptcLength > 0) {
info.Set("iptc", Napi::Buffer<char>::NewOrCopy(env, baton->iptc, baton->iptcLength, sharp::FreeCallback));
}
if (baton->xmpLength > 0) {
info.Set("xmp", Napi::Buffer<char>::NewOrCopy(env, baton->xmp, baton->xmpLength, sharp::FreeCallback));
}
if (baton->tifftagPhotoshopLength > 0) {
info.Set("tifftagPhotoshop",
Napi::Buffer<char>::NewOrCopy(env, baton->tifftagPhotoshop,
baton->tifftagPhotoshopLength, sharp::FreeCallback));
}
Callback().MakeCallback(Receiver().Value(), { env.Null(), info });
} else {
Callback().MakeCallback(Receiver().Value(), { Napi::Error::New(env, sharp::TrimEnd(baton->err)).Value() });
}
delete baton->input;
delete baton;
}
private:
MetadataBaton* baton;
Napi::FunctionReference debuglog;
};
/*
metadata(options, callback)
*/
Napi::Value metadata(const Napi::CallbackInfo& info) {
// V8 objects are converted to non-V8 types held in the baton struct
MetadataBaton *baton = new MetadataBaton;
Napi::Object options = info[size_t(0)].As<Napi::Object>();
// Input
baton->input = sharp::CreateInputDescriptor(options.Get("input").As<Napi::Object>());
// Function to notify of libvips warnings
Napi::Function debuglog = options.Get("debuglog").As<Napi::Function>();
// Join queue for worker thread
Napi::Function callback = info[size_t(1)].As<Napi::Function>();
MetadataWorker *worker = new MetadataWorker(callback, baton, debuglog);
worker->Receiver().Set("options", options);
worker->Queue();
// Increment queued task counter
g_atomic_int_inc(&sharp::counterQueue);
return info.Env().Undefined();
}
+82
View File
@@ -0,0 +1,82 @@
// Copyright 2013 Lovell Fuller and others.
// SPDX-License-Identifier: Apache-2.0
#ifndef SRC_METADATA_H_
#define SRC_METADATA_H_
#include <string>
#include <napi.h>
#include "./common.h"
struct MetadataBaton {
// Input
sharp::InputDescriptor *input;
// Output
std::string format;
int width;
int height;
std::string space;
int channels;
std::string depth;
int density;
std::string chromaSubsampling;
bool isProgressive;
int paletteBitDepth;
int pages;
int pageHeight;
int loop;
std::vector<int> delay;
int pagePrimary;
std::string compression;
std::string resolutionUnit;
std::string formatMagick;
std::vector<std::pair<int, int>> levels;
int subifds;
std::vector<double> background;
bool hasProfile;
bool hasAlpha;
int orientation;
char *exif;
size_t exifLength;
char *icc;
size_t iccLength;
char *iptc;
size_t iptcLength;
char *xmp;
size_t xmpLength;
char *tifftagPhotoshop;
size_t tifftagPhotoshopLength;
std::string err;
MetadataBaton():
input(nullptr),
width(0),
height(0),
channels(0),
density(0),
isProgressive(false),
paletteBitDepth(0),
pages(0),
pageHeight(0),
loop(-1),
pagePrimary(-1),
subifds(0),
hasProfile(false),
hasAlpha(false),
orientation(0),
exif(nullptr),
exifLength(0),
icc(nullptr),
iccLength(0),
iptc(nullptr),
iptcLength(0),
xmp(nullptr),
xmpLength(0),
tifftagPhotoshop(nullptr),
tifftagPhotoshopLength(0) {}
};
Napi::Value metadata(const Napi::CallbackInfo& info);
#endif // SRC_METADATA_H_
+454
View File
@@ -0,0 +1,454 @@
// Copyright 2013 Lovell Fuller and others.
// SPDX-License-Identifier: Apache-2.0
#include <algorithm>
#include <functional>
#include <memory>
#include <tuple>
#include <vector>
#include <vips/vips8>
#include "common.h"
#include "operations.h"
using vips::VImage;
using vips::VError;
namespace sharp {
/*
* Tint an image using the specified chroma, preserving the original image luminance
*/
VImage Tint(VImage image, double const a, double const b) {
// Get original colourspace
VipsInterpretation typeBeforeTint = image.interpretation();
if (typeBeforeTint == VIPS_INTERPRETATION_RGB) {
typeBeforeTint = VIPS_INTERPRETATION_sRGB;
}
// Extract luminance
VImage luminance = image.colourspace(VIPS_INTERPRETATION_LAB)[0];
// Create the tinted version by combining the L from the original and the chroma from the tint
std::vector<double> chroma {a, b};
VImage tinted = luminance
.bandjoin(chroma)
.copy(VImage::option()->set("interpretation", VIPS_INTERPRETATION_LAB))
.colourspace(typeBeforeTint);
// Attach original alpha channel, if any
if (HasAlpha(image)) {
// Extract original alpha channel
VImage alpha = image[image.bands() - 1];
// Join alpha channel to normalised image
tinted = tinted.bandjoin(alpha);
}
return tinted;
}
/*
* Stretch luminance to cover full dynamic range.
*/
VImage Normalise(VImage image, int const lower, int const upper) {
// Get original colourspace
VipsInterpretation typeBeforeNormalize = image.interpretation();
if (typeBeforeNormalize == VIPS_INTERPRETATION_RGB) {
typeBeforeNormalize = VIPS_INTERPRETATION_sRGB;
}
// Convert to LAB colourspace
VImage lab = image.colourspace(VIPS_INTERPRETATION_LAB);
// Extract luminance
VImage luminance = lab[0];
// Find luminance range
int const min = lower == 0 ? luminance.min() : luminance.percent(lower);
int const max = upper == 100 ? luminance.max() : luminance.percent(upper);
if (std::abs(max - min) > 1) {
// Extract chroma
VImage chroma = lab.extract_band(1, VImage::option()->set("n", 2));
// Calculate multiplication factor and addition
double f = 100.0 / (max - min);
double a = -(min * f);
// Scale luminance, join to chroma, convert back to original colourspace
VImage normalized = luminance.linear(f, a).bandjoin(chroma).colourspace(typeBeforeNormalize);
// Attach original alpha channel, if any
if (HasAlpha(image)) {
// Extract original alpha channel
VImage alpha = image[image.bands() - 1];
// Join alpha channel to normalised image
return normalized.bandjoin(alpha);
} else {
return normalized;
}
}
return image;
}
/*
* Contrast limiting adapative histogram equalization (CLAHE)
*/
VImage Clahe(VImage image, int const width, int const height, int const maxSlope) {
return image.hist_local(width, height, VImage::option()->set("max_slope", maxSlope));
}
/*
* Gamma encoding/decoding
*/
VImage Gamma(VImage image, double const exponent) {
if (HasAlpha(image)) {
// Separate alpha channel
VImage alpha = image[image.bands() - 1];
return RemoveAlpha(image).gamma(VImage::option()->set("exponent", exponent)).bandjoin(alpha);
} else {
return image.gamma(VImage::option()->set("exponent", exponent));
}
}
/*
* Flatten image to remove alpha channel
*/
VImage Flatten(VImage image, std::vector<double> flattenBackground) {
double const multiplier = sharp::Is16Bit(image.interpretation()) ? 256.0 : 1.0;
std::vector<double> background {
flattenBackground[0] * multiplier,
flattenBackground[1] * multiplier,
flattenBackground[2] * multiplier
};
return image.flatten(VImage::option()->set("background", background));
}
/**
* Produce the "negative" of the image.
*/
VImage Negate(VImage image, bool const negateAlpha) {
if (HasAlpha(image) && !negateAlpha) {
// Separate alpha channel
VImage alpha = image[image.bands() - 1];
return RemoveAlpha(image).invert().bandjoin(alpha);
} else {
return image.invert();
}
}
/*
* Gaussian blur. Use sigma of -1.0 for fast blur.
*/
VImage Blur(VImage image, double const sigma) {
if (sigma == -1.0) {
// Fast, mild blur - averages neighbouring pixels
VImage blur = VImage::new_matrixv(3, 3,
1.0, 1.0, 1.0,
1.0, 1.0, 1.0,
1.0, 1.0, 1.0);
blur.set("scale", 9.0);
return image.conv(blur);
} else {
// Slower, accurate Gaussian blur
return image.gaussblur(sigma);
}
}
/*
* Convolution with a kernel.
*/
VImage Convolve(VImage image, int const width, int const height,
double const scale, double const offset,
std::unique_ptr<double[]> const &kernel_v
) {
VImage kernel = VImage::new_from_memory(
kernel_v.get(),
width * height * sizeof(double),
width,
height,
1,
VIPS_FORMAT_DOUBLE);
kernel.set("scale", scale);
kernel.set("offset", offset);
return image.conv(kernel);
}
/*
* Recomb with a Matrix of the given bands/channel size.
* Eg. RGB will be a 3x3 matrix.
*/
VImage Recomb(VImage image, std::unique_ptr<double[]> const &matrix) {
double *m = matrix.get();
image = image.colourspace(VIPS_INTERPRETATION_sRGB);
return image
.recomb(image.bands() == 3
? VImage::new_from_memory(
m, 9 * sizeof(double), 3, 3, 1, VIPS_FORMAT_DOUBLE
)
: VImage::new_matrixv(4, 4,
m[0], m[1], m[2], 0.0,
m[3], m[4], m[5], 0.0,
m[6], m[7], m[8], 0.0,
0.0, 0.0, 0.0, 1.0));
}
VImage Modulate(VImage image, double const brightness, double const saturation,
int const hue, double const lightness) {
VipsInterpretation colourspaceBeforeModulate = image.interpretation();
if (HasAlpha(image)) {
// Separate alpha channel
VImage alpha = image[image.bands() - 1];
return RemoveAlpha(image)
.colourspace(VIPS_INTERPRETATION_LCH)
.linear(
{ brightness, saturation, 1},
{ lightness, 0.0, static_cast<double>(hue) }
)
.colourspace(colourspaceBeforeModulate)
.bandjoin(alpha);
} else {
return image
.colourspace(VIPS_INTERPRETATION_LCH)
.linear(
{ brightness, saturation, 1 },
{ lightness, 0.0, static_cast<double>(hue) }
)
.colourspace(colourspaceBeforeModulate);
}
}
/*
* Sharpen flat and jagged areas. Use sigma of -1.0 for fast sharpen.
*/
VImage Sharpen(VImage image, double const sigma, double const m1, double const m2,
double const x1, double const y2, double const y3) {
if (sigma == -1.0) {
// Fast, mild sharpen
VImage sharpen = VImage::new_matrixv(3, 3,
-1.0, -1.0, -1.0,
-1.0, 32.0, -1.0,
-1.0, -1.0, -1.0);
sharpen.set("scale", 24.0);
return image.conv(sharpen);
} else {
// Slow, accurate sharpen in LAB colour space, with control over flat vs jagged areas
VipsInterpretation colourspaceBeforeSharpen = image.interpretation();
if (colourspaceBeforeSharpen == VIPS_INTERPRETATION_RGB) {
colourspaceBeforeSharpen = VIPS_INTERPRETATION_sRGB;
}
return image
.sharpen(VImage::option()
->set("sigma", sigma)
->set("m1", m1)
->set("m2", m2)
->set("x1", x1)
->set("y2", y2)
->set("y3", y3))
.colourspace(colourspaceBeforeSharpen);
}
}
VImage Threshold(VImage image, double const threshold, bool const thresholdGrayscale) {
if (!thresholdGrayscale) {
return image >= threshold;
}
return image.colourspace(VIPS_INTERPRETATION_B_W) >= threshold;
}
/*
Perform boolean/bitwise operation on image color channels - results in one channel image
*/
VImage Bandbool(VImage image, VipsOperationBoolean const boolean) {
image = image.bandbool(boolean);
return image.copy(VImage::option()->set("interpretation", VIPS_INTERPRETATION_B_W));
}
/*
Perform bitwise boolean operation between images
*/
VImage Boolean(VImage image, VImage imageR, VipsOperationBoolean const boolean) {
return image.boolean(imageR, boolean);
}
/*
Trim an image
*/
VImage Trim(VImage image, std::vector<double> background, double threshold) {
if (image.width() < 3 && image.height() < 3) {
throw VError("Image to trim must be at least 3x3 pixels");
}
if (background.size() == 0) {
// Top-left pixel provides the default background colour if none is given
background = image.extract_area(0, 0, 1, 1)(0, 0);
} else if (sharp::Is16Bit(image.interpretation())) {
for (size_t i = 0; i < background.size(); i++) {
background[i] *= 256.0;
}
threshold *= 256.0;
}
std::vector<double> backgroundAlpha({ background.back() });
if (HasAlpha(image)) {
background.pop_back();
} else {
background.resize(image.bands());
}
int left, top, width, height;
left = image.find_trim(&top, &width, &height, VImage::option()
->set("background", background)
->set("threshold", threshold));
if (HasAlpha(image)) {
// Search alpha channel (A)
int leftA, topA, widthA, heightA;
VImage alpha = image[image.bands() - 1];
leftA = alpha.find_trim(&topA, &widthA, &heightA, VImage::option()
->set("background", backgroundAlpha)
->set("threshold", threshold));
if (widthA > 0 && heightA > 0) {
if (width > 0 && height > 0) {
// Combined bounding box (B)
int const leftB = std::min(left, leftA);
int const topB = std::min(top, topA);
int const widthB = std::max(left + width, leftA + widthA) - leftB;
int const heightB = std::max(top + height, topA + heightA) - topB;
return image.extract_area(leftB, topB, widthB, heightB);
} else {
// Use alpha only
return image.extract_area(leftA, topA, widthA, heightA);
}
}
}
if (width > 0 && height > 0) {
return image.extract_area(left, top, width, height);
}
return image;
}
/*
* Calculate (a * in + b)
*/
VImage Linear(VImage image, std::vector<double> const a, std::vector<double> const b) {
size_t const bands = static_cast<size_t>(image.bands());
if (a.size() > bands) {
throw VError("Band expansion using linear is unsupported");
}
bool const uchar = !Is16Bit(image.interpretation());
if (HasAlpha(image) && a.size() != bands && (a.size() == 1 || a.size() == bands - 1 || bands - 1 == 1)) {
// Separate alpha channel
VImage alpha = image[bands - 1];
return RemoveAlpha(image).linear(a, b, VImage::option()->set("uchar", uchar)).bandjoin(alpha);
} else {
return image.linear(a, b, VImage::option()->set("uchar", uchar));
}
}
/*
* Unflatten
*/
VImage Unflatten(VImage image) {
if (HasAlpha(image)) {
VImage alpha = image[image.bands() - 1];
VImage noAlpha = RemoveAlpha(image);
return noAlpha.bandjoin(alpha & (noAlpha.colourspace(VIPS_INTERPRETATION_B_W) < 255));
} else {
return image.bandjoin(image.colourspace(VIPS_INTERPRETATION_B_W) < 255);
}
}
/*
* Ensure the image is in a given colourspace
*/
VImage EnsureColourspace(VImage image, VipsInterpretation colourspace) {
if (colourspace != VIPS_INTERPRETATION_LAST && image.interpretation() != colourspace) {
image = image.colourspace(colourspace,
VImage::option()->set("source_space", image.interpretation()));
}
return image;
}
/*
* Split and crop each frame, reassemble, and update pageHeight.
*/
VImage CropMultiPage(VImage image, int left, int top, int width, int height,
int nPages, int *pageHeight) {
if (top == 0 && height == *pageHeight) {
// Fast path; no need to adjust the height of the multi-page image
return image.extract_area(left, 0, width, image.height());
} else {
std::vector<VImage> pages;
pages.reserve(nPages);
// Split the image into cropped frames
for (int i = 0; i < nPages; i++) {
pages.push_back(
image.extract_area(left, *pageHeight * i + top, width, height));
}
// Reassemble the frames into a tall, thin image
VImage assembled = VImage::arrayjoin(pages,
VImage::option()->set("across", 1));
// Update the page height
*pageHeight = height;
return assembled;
}
}
/*
* Split into frames, embed each frame, reassemble, and update pageHeight.
*/
VImage EmbedMultiPage(VImage image, int left, int top, int width, int height,
VipsExtend extendWith, std::vector<double> background, int nPages, int *pageHeight) {
if (top == 0 && height == *pageHeight) {
// Fast path; no need to adjust the height of the multi-page image
return image.embed(left, 0, width, image.height(), VImage::option()
->set("extend", extendWith)
->set("background", background));
} else if (left == 0 && width == image.width()) {
// Fast path; no need to adjust the width of the multi-page image
std::vector<VImage> pages;
pages.reserve(nPages);
// Rearrange the tall image into a vertical grid
image = image.grid(*pageHeight, nPages, 1);
// Do the embed on the wide image
image = image.embed(0, top, image.width(), height, VImage::option()
->set("extend", extendWith)
->set("background", background));
// Split the wide image into frames
for (int i = 0; i < nPages; i++) {
pages.push_back(
image.extract_area(width * i, 0, width, height));
}
// Reassemble the frames into a tall, thin image
VImage assembled = VImage::arrayjoin(pages,
VImage::option()->set("across", 1));
// Update the page height
*pageHeight = height;
return assembled;
} else {
std::vector<VImage> pages;
pages.reserve(nPages);
// Split the image into frames
for (int i = 0; i < nPages; i++) {
pages.push_back(
image.extract_area(0, *pageHeight * i, image.width(), *pageHeight));
}
// Embed each frame in the target size
for (int i = 0; i < nPages; i++) {
pages[i] = pages[i].embed(left, top, width, height, VImage::option()
->set("extend", extendWith)
->set("background", background));
}
// Reassemble the frames into a tall, thin image
VImage assembled = VImage::arrayjoin(pages,
VImage::option()->set("across", 1));
// Update the page height
*pageHeight = height;
return assembled;
}
}
} // namespace sharp
+125
View File
@@ -0,0 +1,125 @@
// Copyright 2013 Lovell Fuller and others.
// SPDX-License-Identifier: Apache-2.0
#ifndef SRC_OPERATIONS_H_
#define SRC_OPERATIONS_H_
#include <algorithm>
#include <functional>
#include <memory>
#include <tuple>
#include <vips/vips8>
using vips::VImage;
namespace sharp {
/*
* Tint an image using the specified chroma, preserving the original image luminance
*/
VImage Tint(VImage image, double const a, double const b);
/*
* Stretch luminance to cover full dynamic range.
*/
VImage Normalise(VImage image, int const lower, int const upper);
/*
* Contrast limiting adapative histogram equalization (CLAHE)
*/
VImage Clahe(VImage image, int const width, int const height, int const maxSlope);
/*
* Gamma encoding/decoding
*/
VImage Gamma(VImage image, double const exponent);
/*
* Flatten image to remove alpha channel
*/
VImage Flatten(VImage image, std::vector<double> flattenBackground);
/*
* Produce the "negative" of the image.
*/
VImage Negate(VImage image, bool const negateAlpha);
/*
* Gaussian blur. Use sigma of -1.0 for fast blur.
*/
VImage Blur(VImage image, double const sigma);
/*
* Convolution with a kernel.
*/
VImage Convolve(VImage image, int const width, int const height,
double const scale, double const offset, std::unique_ptr<double[]> const &kernel_v);
/*
* Sharpen flat and jagged areas. Use sigma of -1.0 for fast sharpen.
*/
VImage Sharpen(VImage image, double const sigma, double const m1, double const m2,
double const x1, double const y2, double const y3);
/*
Threshold an image
*/
VImage Threshold(VImage image, double const threshold, bool const thresholdColor);
/*
Perform boolean/bitwise operation on image color channels - results in one channel image
*/
VImage Bandbool(VImage image, VipsOperationBoolean const boolean);
/*
Perform bitwise boolean operation between images
*/
VImage Boolean(VImage image, VImage imageR, VipsOperationBoolean const boolean);
/*
Trim an image
*/
VImage Trim(VImage image, std::vector<double> background, double const threshold);
/*
* Linear adjustment (a * in + b)
*/
VImage Linear(VImage image, std::vector<double> const a, std::vector<double> const b);
/*
* Unflatten
*/
VImage Unflatten(VImage image);
/*
* Recomb with a Matrix of the given bands/channel size.
* Eg. RGB will be a 3x3 matrix.
*/
VImage Recomb(VImage image, std::unique_ptr<double[]> const &matrix);
/*
* Modulate brightness, saturation, hue and lightness
*/
VImage Modulate(VImage image, double const brightness, double const saturation,
int const hue, double const lightness);
/*
* Ensure the image is in a given colourspace
*/
VImage EnsureColourspace(VImage image, VipsInterpretation colourspace);
/*
* Split and crop each frame, reassemble, and update pageHeight.
*/
VImage CropMultiPage(VImage image, int left, int top, int width, int height,
int nPages, int *pageHeight);
/*
* Split into frames, embed each frame, reassemble, and update pageHeight.
*/
VImage EmbedMultiPage(VImage image, int left, int top, int width, int height,
VipsExtend extendWith, std::vector<double> background, int nPages, int *pageHeight);
} // namespace sharp
#endif // SRC_OPERATIONS_H_
+1715
View File
File diff suppressed because it is too large Load Diff
+381
View File
@@ -0,0 +1,381 @@
// Copyright 2013 Lovell Fuller and others.
// SPDX-License-Identifier: Apache-2.0
#ifndef SRC_PIPELINE_H_
#define SRC_PIPELINE_H_
#include <memory>
#include <string>
#include <vector>
#include <unordered_map>
#include <napi.h>
#include <vips/vips8>
#include "./common.h"
Napi::Value pipeline(const Napi::CallbackInfo& info);
struct Composite {
sharp::InputDescriptor *input;
VipsBlendMode mode;
int gravity;
int left;
int top;
bool hasOffset;
bool tile;
bool premultiplied;
Composite():
input(nullptr),
mode(VIPS_BLEND_MODE_OVER),
gravity(0),
left(0),
top(0),
hasOffset(false),
tile(false),
premultiplied(false) {}
};
struct PipelineBaton {
sharp::InputDescriptor *input;
std::string formatOut;
std::string fileOut;
void *bufferOut;
size_t bufferOutLength;
std::vector<Composite *> composite;
std::vector<sharp::InputDescriptor *> joinChannelIn;
int topOffsetPre;
int leftOffsetPre;
int widthPre;
int heightPre;
int topOffsetPost;
int leftOffsetPost;
int widthPost;
int heightPost;
int width;
int height;
int channels;
VipsKernel kernel;
sharp::Canvas canvas;
int position;
std::vector<double> resizeBackground;
bool hasCropOffset;
int cropOffsetLeft;
int cropOffsetTop;
bool hasAttentionCenter;
int attentionX;
int attentionY;
bool premultiplied;
bool tileCentre;
bool fastShrinkOnLoad;
double tintA;
double tintB;
bool flatten;
std::vector<double> flattenBackground;
bool unflatten;
bool negate;
bool negateAlpha;
double blurSigma;
double brightness;
double saturation;
int hue;
double lightness;
int medianSize;
double sharpenSigma;
double sharpenM1;
double sharpenM2;
double sharpenX1;
double sharpenY2;
double sharpenY3;
int threshold;
bool thresholdGrayscale;
std::vector<double> trimBackground;
double trimThreshold;
int trimOffsetLeft;
int trimOffsetTop;
std::vector<double> linearA;
std::vector<double> linearB;
double gamma;
double gammaOut;
bool greyscale;
bool normalise;
int normaliseLower;
int normaliseUpper;
int claheWidth;
int claheHeight;
int claheMaxSlope;
bool useExifOrientation;
int angle;
double rotationAngle;
std::vector<double> rotationBackground;
bool rotateBeforePreExtract;
bool flip;
bool flop;
int extendTop;
int extendBottom;
int extendLeft;
int extendRight;
std::vector<double> extendBackground;
VipsExtend extendWith;
bool withoutEnlargement;
bool withoutReduction;
std::vector<double> affineMatrix;
std::vector<double> affineBackground;
double affineIdx;
double affineIdy;
double affineOdx;
double affineOdy;
std::string affineInterpolator;
int jpegQuality;
bool jpegProgressive;
std::string jpegChromaSubsampling;
bool jpegTrellisQuantisation;
int jpegQuantisationTable;
bool jpegOvershootDeringing;
bool jpegOptimiseScans;
bool jpegOptimiseCoding;
bool pngProgressive;
int pngCompressionLevel;
bool pngAdaptiveFiltering;
bool pngPalette;
int pngQuality;
int pngEffort;
int pngBitdepth;
double pngDither;
int jp2Quality;
bool jp2Lossless;
int jp2TileHeight;
int jp2TileWidth;
std::string jp2ChromaSubsampling;
int webpQuality;
int webpAlphaQuality;
bool webpNearLossless;
bool webpLossless;
bool webpSmartSubsample;
VipsForeignWebpPreset webpPreset;
int webpEffort;
bool webpMinSize;
bool webpMixed;
int gifBitdepth;
int gifEffort;
double gifDither;
double gifInterFrameMaxError;
double gifInterPaletteMaxError;
bool gifReuse;
bool gifProgressive;
int tiffQuality;
VipsForeignTiffCompression tiffCompression;
VipsForeignTiffPredictor tiffPredictor;
bool tiffPyramid;
int tiffBitdepth;
bool tiffTile;
int tiffTileHeight;
int tiffTileWidth;
double tiffXres;
double tiffYres;
VipsForeignTiffResunit tiffResolutionUnit;
int heifQuality;
VipsForeignHeifCompression heifCompression;
int heifEffort;
std::string heifChromaSubsampling;
bool heifLossless;
double jxlDistance;
int jxlDecodingTier;
int jxlEffort;
bool jxlLossless;
VipsBandFormat rawDepth;
std::string err;
bool withMetadata;
int withMetadataOrientation;
double withMetadataDensity;
std::string withMetadataIcc;
std::unordered_map<std::string, std::string> withMetadataStrs;
int timeoutSeconds;
std::unique_ptr<double[]> convKernel;
int convKernelWidth;
int convKernelHeight;
double convKernelScale;
double convKernelOffset;
sharp::InputDescriptor *boolean;
VipsOperationBoolean booleanOp;
VipsOperationBoolean bandBoolOp;
int extractChannel;
bool removeAlpha;
double ensureAlpha;
VipsInterpretation colourspaceInput;
VipsInterpretation colourspace;
std::vector<int> delay;
int loop;
int tileSize;
int tileOverlap;
VipsForeignDzContainer tileContainer;
VipsForeignDzLayout tileLayout;
std::string tileFormat;
int tileAngle;
std::vector<double> tileBackground;
int tileSkipBlanks;
VipsForeignDzDepth tileDepth;
std::string tileId;
std::string tileBasename;
std::unique_ptr<double[]> recombMatrix;
PipelineBaton():
input(nullptr),
bufferOutLength(0),
topOffsetPre(-1),
topOffsetPost(-1),
channels(0),
kernel(VIPS_KERNEL_LANCZOS3),
canvas(sharp::Canvas::CROP),
position(0),
resizeBackground{ 0.0, 0.0, 0.0, 255.0 },
hasCropOffset(false),
cropOffsetLeft(0),
cropOffsetTop(0),
hasAttentionCenter(false),
attentionX(0),
attentionY(0),
premultiplied(false),
tintA(128.0),
tintB(128.0),
flatten(false),
flattenBackground{ 0.0, 0.0, 0.0 },
unflatten(false),
negate(false),
negateAlpha(true),
blurSigma(0.0),
brightness(1.0),
saturation(1.0),
hue(0),
lightness(0),
medianSize(0),
sharpenSigma(0.0),
sharpenM1(1.0),
sharpenM2(2.0),
sharpenX1(2.0),
sharpenY2(10.0),
sharpenY3(20.0),
threshold(0),
thresholdGrayscale(true),
trimBackground{},
trimThreshold(0.0),
trimOffsetLeft(0),
trimOffsetTop(0),
linearA{},
linearB{},
gamma(0.0),
greyscale(false),
normalise(false),
normaliseLower(1),
normaliseUpper(99),
claheWidth(0),
claheHeight(0),
claheMaxSlope(3),
useExifOrientation(false),
angle(0),
rotationAngle(0.0),
rotationBackground{ 0.0, 0.0, 0.0, 255.0 },
flip(false),
flop(false),
extendTop(0),
extendBottom(0),
extendLeft(0),
extendRight(0),
extendBackground{ 0.0, 0.0, 0.0, 255.0 },
extendWith(VIPS_EXTEND_BACKGROUND),
withoutEnlargement(false),
withoutReduction(false),
affineMatrix{ 1.0, 0.0, 0.0, 1.0 },
affineBackground{ 0.0, 0.0, 0.0, 255.0 },
affineIdx(0),
affineIdy(0),
affineOdx(0),
affineOdy(0),
affineInterpolator("bicubic"),
jpegQuality(80),
jpegProgressive(false),
jpegChromaSubsampling("4:2:0"),
jpegTrellisQuantisation(false),
jpegQuantisationTable(0),
jpegOvershootDeringing(false),
jpegOptimiseScans(false),
jpegOptimiseCoding(true),
pngProgressive(false),
pngCompressionLevel(6),
pngAdaptiveFiltering(false),
pngPalette(false),
pngQuality(100),
pngEffort(7),
pngBitdepth(8),
pngDither(1.0),
jp2Quality(80),
jp2Lossless(false),
jp2TileHeight(512),
jp2TileWidth(512),
jp2ChromaSubsampling("4:4:4"),
webpQuality(80),
webpAlphaQuality(100),
webpNearLossless(false),
webpLossless(false),
webpSmartSubsample(false),
webpPreset(VIPS_FOREIGN_WEBP_PRESET_DEFAULT),
webpEffort(4),
webpMinSize(false),
webpMixed(false),
gifBitdepth(8),
gifEffort(7),
gifDither(1.0),
gifInterFrameMaxError(0.0),
gifInterPaletteMaxError(3.0),
gifReuse(true),
gifProgressive(false),
tiffQuality(80),
tiffCompression(VIPS_FOREIGN_TIFF_COMPRESSION_JPEG),
tiffPredictor(VIPS_FOREIGN_TIFF_PREDICTOR_HORIZONTAL),
tiffPyramid(false),
tiffBitdepth(8),
tiffTile(false),
tiffTileHeight(256),
tiffTileWidth(256),
tiffXres(1.0),
tiffYres(1.0),
tiffResolutionUnit(VIPS_FOREIGN_TIFF_RESUNIT_INCH),
heifQuality(50),
heifCompression(VIPS_FOREIGN_HEIF_COMPRESSION_AV1),
heifEffort(4),
heifChromaSubsampling("4:4:4"),
heifLossless(false),
jxlDistance(1.0),
jxlDecodingTier(0),
jxlEffort(7),
jxlLossless(false),
rawDepth(VIPS_FORMAT_UCHAR),
withMetadata(false),
withMetadataOrientation(-1),
withMetadataDensity(0.0),
timeoutSeconds(0),
convKernelWidth(0),
convKernelHeight(0),
convKernelScale(0.0),
convKernelOffset(0.0),
boolean(nullptr),
booleanOp(VIPS_OPERATION_BOOLEAN_LAST),
bandBoolOp(VIPS_OPERATION_BOOLEAN_LAST),
extractChannel(-1),
removeAlpha(false),
ensureAlpha(-1.0),
colourspaceInput(VIPS_INTERPRETATION_LAST),
colourspace(VIPS_INTERPRETATION_LAST),
loop(-1),
tileSize(256),
tileOverlap(0),
tileContainer(VIPS_FOREIGN_DZ_CONTAINER_FS),
tileLayout(VIPS_FOREIGN_DZ_LAYOUT_DZ),
tileAngle(0),
tileBackground{ 255.0, 255.0, 255.0, 255.0 },
tileSkipBlanks(-1),
tileDepth(VIPS_FOREIGN_DZ_DEPTH_LAST) {}
};
#endif // SRC_PIPELINE_H_
+41
View File
@@ -0,0 +1,41 @@
// Copyright 2013 Lovell Fuller and others.
// SPDX-License-Identifier: Apache-2.0
#include <napi.h>
#include <vips/vips8>
#include "common.h"
#include "metadata.h"
#include "pipeline.h"
#include "utilities.h"
#include "stats.h"
static void* sharp_vips_init(void*) {
vips_init("sharp");
return nullptr;
}
Napi::Object init(Napi::Env env, Napi::Object exports) {
static GOnce sharp_vips_init_once = G_ONCE_INIT;
g_once(&sharp_vips_init_once, static_cast<GThreadFunc>(sharp_vips_init), nullptr);
g_log_set_handler("VIPS", static_cast<GLogLevelFlags>(G_LOG_LEVEL_WARNING),
static_cast<GLogFunc>(sharp::VipsWarningCallback), nullptr);
// Methods available to JavaScript
exports.Set("metadata", Napi::Function::New(env, metadata));
exports.Set("pipeline", Napi::Function::New(env, pipeline));
exports.Set("cache", Napi::Function::New(env, cache));
exports.Set("concurrency", Napi::Function::New(env, concurrency));
exports.Set("counters", Napi::Function::New(env, counters));
exports.Set("simd", Napi::Function::New(env, simd));
exports.Set("libvipsVersion", Napi::Function::New(env, libvipsVersion));
exports.Set("format", Napi::Function::New(env, format));
exports.Set("block", Napi::Function::New(env, block));
exports.Set("_maxColourDistance", Napi::Function::New(env, _maxColourDistance));
exports.Set("_isUsingJemalloc", Napi::Function::New(env, _isUsingJemalloc));
exports.Set("stats", Napi::Function::New(env, stats));
return exports;
}
NODE_API_MODULE(sharp, init)
+183
View File
@@ -0,0 +1,183 @@
// Copyright 2013 Lovell Fuller and others.
// SPDX-License-Identifier: Apache-2.0
#include <numeric>
#include <vector>
#include <iostream>
#include <napi.h>
#include <vips/vips8>
#include "common.h"
#include "stats.h"
class StatsWorker : public Napi::AsyncWorker {
public:
StatsWorker(Napi::Function callback, StatsBaton *baton, Napi::Function debuglog) :
Napi::AsyncWorker(callback), baton(baton), debuglog(Napi::Persistent(debuglog)) {}
~StatsWorker() {}
const int STAT_MIN_INDEX = 0;
const int STAT_MAX_INDEX = 1;
const int STAT_SUM_INDEX = 2;
const int STAT_SQ_SUM_INDEX = 3;
const int STAT_MEAN_INDEX = 4;
const int STAT_STDEV_INDEX = 5;
const int STAT_MINX_INDEX = 6;
const int STAT_MINY_INDEX = 7;
const int STAT_MAXX_INDEX = 8;
const int STAT_MAXY_INDEX = 9;
void Execute() {
// Decrement queued task counter
g_atomic_int_dec_and_test(&sharp::counterQueue);
vips::VImage image;
sharp::ImageType imageType = sharp::ImageType::UNKNOWN;
try {
std::tie(image, imageType) = OpenInput(baton->input);
} catch (vips::VError const &err) {
(baton->err).append(err.what());
}
if (imageType != sharp::ImageType::UNKNOWN) {
try {
vips::VImage stats = image.stats();
int const bands = image.bands();
for (int b = 1; b <= bands; b++) {
ChannelStats cStats(
static_cast<int>(stats.getpoint(STAT_MIN_INDEX, b).front()),
static_cast<int>(stats.getpoint(STAT_MAX_INDEX, b).front()),
stats.getpoint(STAT_SUM_INDEX, b).front(),
stats.getpoint(STAT_SQ_SUM_INDEX, b).front(),
stats.getpoint(STAT_MEAN_INDEX, b).front(),
stats.getpoint(STAT_STDEV_INDEX, b).front(),
static_cast<int>(stats.getpoint(STAT_MINX_INDEX, b).front()),
static_cast<int>(stats.getpoint(STAT_MINY_INDEX, b).front()),
static_cast<int>(stats.getpoint(STAT_MAXX_INDEX, b).front()),
static_cast<int>(stats.getpoint(STAT_MAXY_INDEX, b).front()));
baton->channelStats.push_back(cStats);
}
// Image is not opaque when alpha layer is present and contains a non-mamixa value
if (sharp::HasAlpha(image)) {
double const minAlpha = static_cast<double>(stats.getpoint(STAT_MIN_INDEX, bands).front());
if (minAlpha != sharp::MaximumImageAlpha(image.interpretation())) {
baton->isOpaque = false;
}
}
// Convert to greyscale
vips::VImage greyscale = image.colourspace(VIPS_INTERPRETATION_B_W)[0];
// Estimate entropy via histogram of greyscale value frequency
baton->entropy = std::abs(greyscale.hist_find().hist_entropy());
// Estimate sharpness via standard deviation of greyscale laplacian
if (image.width() > 1 || image.height() > 1) {
VImage laplacian = VImage::new_matrixv(3, 3,
0.0, 1.0, 0.0,
1.0, -4.0, 1.0,
0.0, 1.0, 0.0);
laplacian.set("scale", 9.0);
baton->sharpness = greyscale.conv(laplacian).deviate();
}
// Most dominant sRGB colour via 4096-bin 3D histogram
vips::VImage hist = sharp::RemoveAlpha(image)
.colourspace(VIPS_INTERPRETATION_sRGB)
.hist_find_ndim(VImage::option()->set("bins", 16));
std::complex<double> maxpos = hist.maxpos();
int const dx = static_cast<int>(std::real(maxpos));
int const dy = static_cast<int>(std::imag(maxpos));
std::vector<double> pel = hist(dx, dy);
int const dz = std::distance(pel.begin(), std::find(pel.begin(), pel.end(), hist.max()));
baton->dominantRed = dx * 16 + 8;
baton->dominantGreen = dy * 16 + 8;
baton->dominantBlue = dz * 16 + 8;
} catch (vips::VError const &err) {
(baton->err).append(err.what());
}
}
// Clean up
vips_error_clear();
vips_thread_shutdown();
}
void OnOK() {
Napi::Env env = Env();
Napi::HandleScope scope(env);
// Handle warnings
std::string warning = sharp::VipsWarningPop();
while (!warning.empty()) {
debuglog.MakeCallback(Receiver().Value(), { Napi::String::New(env, warning) });
warning = sharp::VipsWarningPop();
}
if (baton->err.empty()) {
// Stats Object
Napi::Object info = Napi::Object::New(env);
Napi::Array channels = Napi::Array::New(env);
std::vector<ChannelStats>::iterator it;
int i = 0;
for (it = baton->channelStats.begin(); it < baton->channelStats.end(); it++, i++) {
Napi::Object channelStat = Napi::Object::New(env);
channelStat.Set("min", it->min);
channelStat.Set("max", it->max);
channelStat.Set("sum", it->sum);
channelStat.Set("squaresSum", it->squaresSum);
channelStat.Set("mean", it->mean);
channelStat.Set("stdev", it->stdev);
channelStat.Set("minX", it->minX);
channelStat.Set("minY", it->minY);
channelStat.Set("maxX", it->maxX);
channelStat.Set("maxY", it->maxY);
channels.Set(i, channelStat);
}
info.Set("channels", channels);
info.Set("isOpaque", baton->isOpaque);
info.Set("entropy", baton->entropy);
info.Set("sharpness", baton->sharpness);
Napi::Object dominant = Napi::Object::New(env);
dominant.Set("r", baton->dominantRed);
dominant.Set("g", baton->dominantGreen);
dominant.Set("b", baton->dominantBlue);
info.Set("dominant", dominant);
Callback().MakeCallback(Receiver().Value(), { env.Null(), info });
} else {
Callback().MakeCallback(Receiver().Value(), { Napi::Error::New(env, sharp::TrimEnd(baton->err)).Value() });
}
delete baton->input;
delete baton;
}
private:
StatsBaton* baton;
Napi::FunctionReference debuglog;
};
/*
stats(options, callback)
*/
Napi::Value stats(const Napi::CallbackInfo& info) {
// V8 objects are converted to non-V8 types held in the baton struct
StatsBaton *baton = new StatsBaton;
Napi::Object options = info[size_t(0)].As<Napi::Object>();
// Input
baton->input = sharp::CreateInputDescriptor(options.Get("input").As<Napi::Object>());
baton->input->access = VIPS_ACCESS_RANDOM;
// Function to notify of libvips warnings
Napi::Function debuglog = options.Get("debuglog").As<Napi::Function>();
// Join queue for worker thread
Napi::Function callback = info[size_t(1)].As<Napi::Function>();
StatsWorker *worker = new StatsWorker(callback, baton, debuglog);
worker->Receiver().Set("options", options);
worker->Queue();
// Increment queued task counter
g_atomic_int_inc(&sharp::counterQueue);
return info.Env().Undefined();
}
+59
View File
@@ -0,0 +1,59 @@
// Copyright 2013 Lovell Fuller and others.
// SPDX-License-Identifier: Apache-2.0
#ifndef SRC_STATS_H_
#define SRC_STATS_H_
#include <string>
#include <napi.h>
#include "./common.h"
struct ChannelStats {
// stats per channel
int min;
int max;
double sum;
double squaresSum;
double mean;
double stdev;
int minX;
int minY;
int maxX;
int maxY;
ChannelStats(int minVal, int maxVal, double sumVal, double squaresSumVal,
double meanVal, double stdevVal, int minXVal, int minYVal, int maxXVal, int maxYVal):
min(minVal), max(maxVal), sum(sumVal), squaresSum(squaresSumVal),
mean(meanVal), stdev(stdevVal), minX(minXVal), minY(minYVal), maxX(maxXVal), maxY(maxYVal) {}
};
struct StatsBaton {
// Input
sharp::InputDescriptor *input;
// Output
std::vector<ChannelStats> channelStats;
bool isOpaque;
double entropy;
double sharpness;
int dominantRed;
int dominantGreen;
int dominantBlue;
std::string err;
StatsBaton():
input(nullptr),
isOpaque(true),
entropy(0.0),
sharpness(0.0),
dominantRed(0),
dominantGreen(0),
dominantBlue(0)
{}
};
Napi::Value stats(const Napi::CallbackInfo& info);
#endif // SRC_STATS_H_
+254
View File
@@ -0,0 +1,254 @@
// Copyright 2013 Lovell Fuller and others.
// SPDX-License-Identifier: Apache-2.0
#include <cmath>
#include <string>
#include <napi.h>
#include <vips/vips8>
#include <vips/vector.h>
#include "common.h"
#include "operations.h"
#include "utilities.h"
/*
Get and set cache limits
*/
Napi::Value cache(const Napi::CallbackInfo& info) {
Napi::Env env = info.Env();
// Set memory limit
if (info[size_t(0)].IsNumber()) {
vips_cache_set_max_mem(info[size_t(0)].As<Napi::Number>().Int32Value() * 1048576);
}
// Set file limit
if (info[size_t(1)].IsNumber()) {
vips_cache_set_max_files(info[size_t(1)].As<Napi::Number>().Int32Value());
}
// Set items limit
if (info[size_t(2)].IsNumber()) {
vips_cache_set_max(info[size_t(2)].As<Napi::Number>().Int32Value());
}
// Get memory stats
Napi::Object memory = Napi::Object::New(env);
memory.Set("current", round(vips_tracked_get_mem() / 1048576));
memory.Set("high", round(vips_tracked_get_mem_highwater() / 1048576));
memory.Set("max", round(vips_cache_get_max_mem() / 1048576));
// Get file stats
Napi::Object files = Napi::Object::New(env);
files.Set("current", vips_tracked_get_files());
files.Set("max", vips_cache_get_max_files());
// Get item stats
Napi::Object items = Napi::Object::New(env);
items.Set("current", vips_cache_get_size());
items.Set("max", vips_cache_get_max());
Napi::Object cache = Napi::Object::New(env);
cache.Set("memory", memory);
cache.Set("files", files);
cache.Set("items", items);
return cache;
}
/*
Get and set size of thread pool
*/
Napi::Value concurrency(const Napi::CallbackInfo& info) {
// Set concurrency
if (info[size_t(0)].IsNumber()) {
vips_concurrency_set(info[size_t(0)].As<Napi::Number>().Int32Value());
}
// Get concurrency
return Napi::Number::New(info.Env(), vips_concurrency_get());
}
/*
Get internal counters (queued tasks, processing tasks)
*/
Napi::Value counters(const Napi::CallbackInfo& info) {
Napi::Object counters = Napi::Object::New(info.Env());
counters.Set("queue", sharp::counterQueue);
counters.Set("process", sharp::counterProcess);
return counters;
}
/*
Get and set use of SIMD vector unit instructions
*/
Napi::Value simd(const Napi::CallbackInfo& info) {
// Set state
if (info[size_t(0)].IsBoolean()) {
vips_vector_set_enabled(info[size_t(0)].As<Napi::Boolean>().Value());
}
// Get state
return Napi::Boolean::New(info.Env(), vips_vector_isenabled());
}
/*
Get libvips version
*/
Napi::Value libvipsVersion(const Napi::CallbackInfo& info) {
char version[9];
g_snprintf(version, sizeof(version), "%d.%d.%d", vips_version(0), vips_version(1), vips_version(2));
return Napi::String::New(info.Env(), version);
}
/*
Get available input/output file/buffer/stream formats
*/
Napi::Value format(const Napi::CallbackInfo& info) {
Napi::Env env = info.Env();
Napi::Object format = Napi::Object::New(env);
for (std::string const f : {
"jpeg", "png", "webp", "tiff", "magick", "openslide", "dz",
"ppm", "fits", "gif", "svg", "heif", "pdf", "vips", "jp2k", "jxl"
}) {
// Input
const VipsObjectClass *oc = vips_class_find("VipsOperation", (f + "load").c_str());
Napi::Boolean hasInputFile = Napi::Boolean::New(env, oc);
Napi::Boolean hasInputBuffer =
Napi::Boolean::New(env, vips_type_find("VipsOperation", (f + "load_buffer").c_str()));
Napi::Object input = Napi::Object::New(env);
input.Set("file", hasInputFile);
input.Set("buffer", hasInputBuffer);
input.Set("stream", hasInputBuffer);
if (hasInputFile) {
const VipsForeignClass *fc = VIPS_FOREIGN_CLASS(oc);
if (fc->suffs) {
Napi::Array fileSuffix = Napi::Array::New(env);
const char **suffix = fc->suffs;
for (int i = 0; *suffix; i++, suffix++) {
fileSuffix.Set(i, Napi::String::New(env, *suffix));
}
input.Set("fileSuffix", fileSuffix);
}
}
// Output
Napi::Boolean hasOutputFile =
Napi::Boolean::New(env, vips_type_find("VipsOperation", (f + "save").c_str()));
Napi::Boolean hasOutputBuffer =
Napi::Boolean::New(env, vips_type_find("VipsOperation", (f + "save_buffer").c_str()));
Napi::Object output = Napi::Object::New(env);
output.Set("file", hasOutputFile);
output.Set("buffer", hasOutputBuffer);
output.Set("stream", hasOutputBuffer);
// Other attributes
Napi::Object container = Napi::Object::New(env);
container.Set("id", f);
container.Set("input", input);
container.Set("output", output);
// Add to set of formats
format.Set(f, container);
}
// Raw, uncompressed data
Napi::Boolean supported = Napi::Boolean::New(env, true);
Napi::Boolean unsupported = Napi::Boolean::New(env, false);
Napi::Object rawInput = Napi::Object::New(env);
rawInput.Set("file", unsupported);
rawInput.Set("buffer", supported);
rawInput.Set("stream", supported);
Napi::Object rawOutput = Napi::Object::New(env);
rawOutput.Set("file", unsupported);
rawOutput.Set("buffer", supported);
rawOutput.Set("stream", supported);
Napi::Object raw = Napi::Object::New(env);
raw.Set("id", "raw");
raw.Set("input", rawInput);
raw.Set("output", rawOutput);
format.Set("raw", raw);
return format;
}
/*
(Un)block libvips operations at runtime.
*/
void block(const Napi::CallbackInfo& info) {
Napi::Array ops = info[size_t(0)].As<Napi::Array>();
bool const state = info[size_t(1)].As<Napi::Boolean>().Value();
for (unsigned int i = 0; i < ops.Length(); i++) {
vips_operation_block_set(ops.Get(i).As<Napi::String>().Utf8Value().c_str(), state);
}
}
/*
Synchronous, internal-only method used by some of the functional tests.
Calculates the maximum colour distance using the DE2000 algorithm
between two images of the same dimensions and number of channels.
*/
Napi::Value _maxColourDistance(const Napi::CallbackInfo& info) {
Napi::Env env = info.Env();
// Open input files
VImage image1;
sharp::ImageType imageType1 = sharp::DetermineImageType(info[size_t(0)].As<Napi::String>().Utf8Value().data());
if (imageType1 != sharp::ImageType::UNKNOWN) {
try {
image1 = VImage::new_from_file(info[size_t(0)].As<Napi::String>().Utf8Value().c_str());
} catch (...) {
throw Napi::Error::New(env, "Input file 1 has corrupt header");
}
} else {
throw Napi::Error::New(env, "Input file 1 is of an unsupported image format");
}
VImage image2;
sharp::ImageType imageType2 = sharp::DetermineImageType(info[size_t(1)].As<Napi::String>().Utf8Value().data());
if (imageType2 != sharp::ImageType::UNKNOWN) {
try {
image2 = VImage::new_from_file(info[size_t(1)].As<Napi::String>().Utf8Value().c_str());
} catch (...) {
throw Napi::Error::New(env, "Input file 2 has corrupt header");
}
} else {
throw Napi::Error::New(env, "Input file 2 is of an unsupported image format");
}
// Ensure same number of channels
if (image1.bands() != image2.bands()) {
throw Napi::Error::New(env, "mismatchedBands");
}
// Ensure same dimensions
if (image1.width() != image2.width() || image1.height() != image2.height()) {
throw Napi::Error::New(env, "mismatchedDimensions");
}
double maxColourDistance;
try {
// Premultiply and remove alpha
if (sharp::HasAlpha(image1)) {
image1 = image1.premultiply().extract_band(1, VImage::option()->set("n", image1.bands() - 1));
}
if (sharp::HasAlpha(image2)) {
image2 = image2.premultiply().extract_band(1, VImage::option()->set("n", image2.bands() - 1));
}
// Calculate colour distance
maxColourDistance = image1.dE00(image2).max();
} catch (vips::VError const &err) {
throw Napi::Error::New(env, err.what());
}
// Clean up libvips' per-request data and threads
vips_error_clear();
vips_thread_shutdown();
return Napi::Number::New(env, maxColourDistance);
}
#if defined(__GNUC__)
// mallctl will be resolved by the runtime linker when jemalloc is being used
extern "C" {
int mallctl(const char *name, void *oldp, size_t *oldlenp, void *newp, size_t newlen) __attribute__((weak));
}
Napi::Value _isUsingJemalloc(const Napi::CallbackInfo& info) {
Napi::Env env = info.Env();
return Napi::Boolean::New(env, mallctl != nullptr);
}
#else
Napi::Value _isUsingJemalloc(const Napi::CallbackInfo& info) {
Napi::Env env = info.Env();
return Napi::Boolean::New(env, false);
}
#endif
+19
View File
@@ -0,0 +1,19 @@
// Copyright 2013 Lovell Fuller and others.
// SPDX-License-Identifier: Apache-2.0
#ifndef SRC_UTILITIES_H_
#define SRC_UTILITIES_H_
#include <napi.h>
Napi::Value cache(const Napi::CallbackInfo& info);
Napi::Value concurrency(const Napi::CallbackInfo& info);
Napi::Value counters(const Napi::CallbackInfo& info);
Napi::Value simd(const Napi::CallbackInfo& info);
Napi::Value libvipsVersion(const Napi::CallbackInfo& info);
Napi::Value format(const Napi::CallbackInfo& info);
void block(const Napi::CallbackInfo& info);
Napi::Value _maxColourDistance(const Napi::CallbackInfo& info);
Napi::Value _isUsingJemalloc(const Napi::CallbackInfo& info);
#endif // SRC_UTILITIES_H_
@@ -0,0 +1,43 @@
# Third-party notices
This software contains third-party libraries
used under the terms of the following licences:
| Library | Used under the terms of |
|---------------|-----------------------------------------------------------------------------------------------------------|
| aom | BSD 2-Clause + [Alliance for Open Media Patent License 1.0](https://aomedia.org/license/patent-license/) |
| cairo | Mozilla Public License 2.0 |
| cgif | MIT Licence |
| expat | MIT Licence |
| fontconfig | [fontconfig Licence](https://gitlab.freedesktop.org/fontconfig/fontconfig/blob/main/COPYING) (BSD-like) |
| freetype | [freetype Licence](https://git.savannah.gnu.org/cgit/freetype/freetype2.git/tree/docs/FTL.TXT) (BSD-like) |
| fribidi | LGPLv3 |
| gdk-pixbuf | LGPLv3 |
| glib | LGPLv3 |
| harfbuzz | MIT Licence |
| lcms | MIT Licence |
| libarchive | BSD 2-Clause |
| libexif | LGPLv3 |
| libffi | MIT Licence |
| libheif | LGPLv3 |
| libimagequant | [BSD 2-Clause](https://github.com/lovell/libimagequant/blob/main/COPYRIGHT) |
| mozjpeg | [zlib License, IJG License, BSD-3-Clause](https://github.com/mozilla/mozjpeg/blob/master/LICENSE.md) |
| libnsgif | MIT Licence |
| libpng | [libpng License](https://github.com/glennrp/libpng/blob/master/LICENSE) |
| librsvg | LGPLv3 |
| libspng | [BSD 2-Clause, libpng License](https://github.com/randy408/libspng/blob/master/LICENSE) |
| libtiff | [libtiff License](https://libtiff.gitlab.io/libtiff/misc.html) (BSD-like) |
| libvips | LGPLv3 |
| libwebp | New BSD License |
| libxml2 | MIT Licence |
| orc | [orc License](https://gitlab.freedesktop.org/gstreamer/orc/blob/master/COPYING) (BSD-like) |
| pango | LGPLv3 |
| pixman | MIT Licence |
| proxy-libintl | LGPLv3 |
| zlib-ng | [zlib Licence](https://github.com/zlib-ng/zlib-ng/blob/develop/LICENSE.md) |
Use of libraries under the terms of the LGPLv3 is via the
"any later version" clause of the LGPLv2 or LGPLv2.1.
Please report any errors or omissions via
https://github.com/lovell/sharp-libvips/issues/new
+127
View File
@@ -0,0 +1,127 @@
/*
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
*
* This source code is subject to the terms of the BSD 2 Clause License and
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
* was not distributed with this source code in the LICENSE file, you can
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
* Media Patent License 1.0 was not distributed with this source code in the
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
/*!\defgroup aom AOM
* \ingroup codecs
* AOM is aom's newest video compression algorithm that uses motion
* compensated prediction, Discrete Cosine Transform (DCT) coding of the
* prediction error signal and context dependent entropy coding techniques
* based on arithmetic principles. It features:
* - YUV 4:2:0 image format
* - Macro-block based coding (16x16 luma plus two 8x8 chroma)
* - 1/4 (1/8) pixel accuracy motion compensated prediction
* - 4x4 DCT transform
* - 128 level linear quantizer
* - In loop deblocking filter
* - Context-based entropy coding
*
* @{
*/
/*!\file
* \brief Provides controls common to both the AOM encoder and decoder.
*/
#ifndef AOM_AOM_AOM_H_
#define AOM_AOM_AOM_H_
#include "aom/aom_codec.h"
#include "aom/aom_image.h"
#ifdef __cplusplus
extern "C" {
#endif
/*!\brief Control functions
*
* The set of macros define the control functions of AOM interface
* The range for common control IDs is 230-255(max).
*/
enum aom_com_control_id {
/*!\brief Codec control function to get a pointer to a reference frame
*
* av1_ref_frame_t* parameter
*/
AV1_GET_REFERENCE = 230,
/*!\brief Codec control function to write a frame into a reference buffer
*
* av1_ref_frame_t* parameter
*/
AV1_SET_REFERENCE = 231,
/*!\brief Codec control function to get a copy of reference frame from the
* decoder
*
* av1_ref_frame_t* parameter
*/
AV1_COPY_REFERENCE = 232,
/*!\brief Codec control function to get a pointer to the new frame
*
* aom_image_t* parameter
*/
AV1_GET_NEW_FRAME_IMAGE = 233,
/*!\brief Codec control function to copy the new frame to an external buffer
*
* aom_image_t* parameter
*/
AV1_COPY_NEW_FRAME_IMAGE = 234,
/*!\brief Start point of control IDs for aom_dec_control_id.
* Any new common control IDs should be added above.
*/
AOM_DECODER_CTRL_ID_START = 256
// No common control IDs should be added after AOM_DECODER_CTRL_ID_START.
};
/*!\brief AV1 specific reference frame data struct
*
* Define the data struct to access av1 reference frames.
*/
typedef struct av1_ref_frame {
int idx; /**< frame index to get (input) */
int use_external_ref; /**< Directly use external ref buffer(decoder only) */
aom_image_t img; /**< img structure to populate (output) */
} av1_ref_frame_t;
/*!\cond */
/*!\brief aom decoder control function parameter type
*
* Defines the data type for each of AOM decoder control function requires.
*
* \note For each control ID "X", a macro-define of
* AOM_CTRL_X is provided. It is used at compile time to determine
* if the control ID is supported by the libaom library available,
* when the libaom version cannot be controlled.
*/
AOM_CTRL_USE_TYPE(AV1_GET_REFERENCE, av1_ref_frame_t *)
#define AOM_CTRL_AV1_GET_REFERENCE
AOM_CTRL_USE_TYPE(AV1_SET_REFERENCE, av1_ref_frame_t *)
#define AOM_CTRL_AV1_SET_REFERENCE
AOM_CTRL_USE_TYPE(AV1_COPY_REFERENCE, av1_ref_frame_t *)
#define AOM_CTRL_AV1_COPY_REFERENCE
AOM_CTRL_USE_TYPE(AV1_GET_NEW_FRAME_IMAGE, aom_image_t *)
#define AOM_CTRL_AV1_GET_NEW_FRAME_IMAGE
AOM_CTRL_USE_TYPE(AV1_COPY_NEW_FRAME_IMAGE, aom_image_t *)
#define AOM_CTRL_AV1_COPY_NEW_FRAME_IMAGE
/*!\endcond */
/*! @} - end defgroup aom */
#ifdef __cplusplus
} // extern "C"
#endif
#endif // AOM_AOM_AOM_H_
@@ -0,0 +1,577 @@
/*
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
*
* This source code is subject to the terms of the BSD 2 Clause License and
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
* was not distributed with this source code in the LICENSE file, you can
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
* Media Patent License 1.0 was not distributed with this source code in the
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
///////////////////////////////////////////////////////////////////////////////
// Internal implementation details
///////////////////////////////////////////////////////////////////////////////
//
// There are two levels of interfaces used to access the AOM codec: the
// aom_codec_iface and the aom_codec_ctx.
//
// 1. aom_codec_iface_t
// (Related files: aom/aom_codec.h, aom/src/aom_codec.c,
// aom/internal/aom_codec_internal.h, av1/av1_cx_iface.c,
// av1/av1_dx_iface.c)
//
// Used to initialize the codec context, which contains the configuration for
// for modifying the encoder/decoder during run-time. See the other
// documentation in this header file for more details. For the most part,
// users will call helper functions, such as aom_codec_iface_name,
// aom_codec_get_caps, etc., to interact with it.
//
// The main purpose of the aom_codec_iface_t is to provide a way to generate
// a default codec config, find out what capabilities the implementation has,
// and create an aom_codec_ctx_t (which is actually used to interact with the
// codec).
//
// Note that the implementations for the AV1 algorithm are located in
// av1/av1_cx_iface.c and av1/av1_dx_iface.c
//
//
// 2. aom_codec_ctx_t
// (Related files: aom/aom_codec.h, av1/av1_cx_iface.c, av1/av1_dx_iface.c,
// aom/aomcx.h, aom/aomdx.h, aom/src/aom_encoder.c, aom/src/aom_decoder.c)
//
// The actual interface between user code and the codec. It stores the name
// of the codec, a pointer back to the aom_codec_iface_t that initialized it,
// initialization flags, a config for either encoder or the decoder, and a
// pointer to internal data.
//
// The codec is configured / queried through calls to aom_codec_control,
// which takes a control ID (listed in aomcx.h and aomdx.h) and a parameter.
// In the case of "getter" control IDs, the parameter is modified to have
// the requested value; in the case of "setter" control IDs, the codec's
// configuration is changed based on the parameter. Note that a aom_codec_err_t
// is returned, which indicates if the operation was successful or not.
//
// Note that for the encoder, the aom_codec_alg_priv_t points to the
// the aom_codec_alg_priv structure in av1/av1_cx_iface.c, and for the decoder,
// the struct in av1/av1_dx_iface.c. Variables such as AV1_COMP cpi are stored
// here and also used in the core algorithm.
//
// At the end, aom_codec_destroy should be called for each initialized
// aom_codec_ctx_t.
/*!\defgroup codec Common Algorithm Interface
* This abstraction allows applications to easily support multiple video
* formats with minimal code duplication. This section describes the interface
* common to all codecs (both encoders and decoders).
* @{
*/
/*!\file
* \brief Describes the codec algorithm interface to applications.
*
* This file describes the interface between an application and a
* video codec algorithm.
*
* An application instantiates a specific codec instance by using
* aom_codec_dec_init() or aom_codec_enc_init() and a pointer to the
* algorithm's interface structure:
* <pre>
* my_app.c:
* extern aom_codec_iface_t my_codec;
* {
* aom_codec_ctx_t algo;
* int threads = 4;
* aom_codec_dec_cfg_t cfg = { threads, 0, 0, 1 };
* res = aom_codec_dec_init(&algo, &my_codec, &cfg, 0);
* }
* </pre>
*
* Once initialized, the instance is managed using other functions from
* the aom_codec_* family.
*/
#ifndef AOM_AOM_AOM_CODEC_H_
#define AOM_AOM_AOM_CODEC_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "aom/aom_image.h"
#include "aom/aom_integer.h"
/*!\brief Decorator indicating a function is deprecated */
#ifndef AOM_DEPRECATED
#if defined(__GNUC__) && __GNUC__
#define AOM_DEPRECATED __attribute__((deprecated))
#elif defined(_MSC_VER)
#define AOM_DEPRECATED
#else
#define AOM_DEPRECATED
#endif
#endif /* AOM_DEPRECATED */
#ifndef AOM_DECLSPEC_DEPRECATED
#if defined(__GNUC__) && __GNUC__
#define AOM_DECLSPEC_DEPRECATED /**< \copydoc #AOM_DEPRECATED */
#elif defined(_MSC_VER)
/*!\brief \copydoc #AOM_DEPRECATED */
#define AOM_DECLSPEC_DEPRECATED __declspec(deprecated)
#else
#define AOM_DECLSPEC_DEPRECATED /**< \copydoc #AOM_DEPRECATED */
#endif
#endif /* AOM_DECLSPEC_DEPRECATED */
/*!\brief Decorator indicating a function is potentially unused */
#ifdef AOM_UNUSED
#elif defined(__GNUC__) || defined(__clang__)
#define AOM_UNUSED __attribute__((unused))
#else
#define AOM_UNUSED
#endif
/*!\brief Decorator indicating that given struct/union/enum is packed */
#ifndef ATTRIBUTE_PACKED
#if defined(__GNUC__) && __GNUC__
#define ATTRIBUTE_PACKED __attribute__((packed))
#elif defined(_MSC_VER)
#define ATTRIBUTE_PACKED
#else
#define ATTRIBUTE_PACKED
#endif
#endif /* ATTRIBUTE_PACKED */
/*!\brief Current ABI version number
*
* \internal
* If this file is altered in any way that changes the ABI, this value
* must be bumped. Examples include, but are not limited to, changing
* types, removing or reassigning enums, adding/removing/rearranging
* fields to structures
*/
#define AOM_CODEC_ABI_VERSION (7 + AOM_IMAGE_ABI_VERSION) /**<\hideinitializer*/
/*!\brief Algorithm return codes */
typedef enum {
/*!\brief Operation completed without error */
AOM_CODEC_OK,
/*!\brief Unspecified error */
AOM_CODEC_ERROR,
/*!\brief Memory operation failed */
AOM_CODEC_MEM_ERROR,
/*!\brief ABI version mismatch */
AOM_CODEC_ABI_MISMATCH,
/*!\brief Algorithm does not have required capability */
AOM_CODEC_INCAPABLE,
/*!\brief The given bitstream is not supported.
*
* The bitstream was unable to be parsed at the highest level. The decoder
* is unable to proceed. This error \ref SHOULD be treated as fatal to the
* stream. */
AOM_CODEC_UNSUP_BITSTREAM,
/*!\brief Encoded bitstream uses an unsupported feature
*
* The decoder does not implement a feature required by the encoder. This
* return code should only be used for features that prevent future
* pictures from being properly decoded. This error \ref MAY be treated as
* fatal to the stream or \ref MAY be treated as fatal to the current GOP.
*/
AOM_CODEC_UNSUP_FEATURE,
/*!\brief The coded data for this stream is corrupt or incomplete
*
* There was a problem decoding the current frame. This return code
* should only be used for failures that prevent future pictures from
* being properly decoded. This error \ref MAY be treated as fatal to the
* stream or \ref MAY be treated as fatal to the current GOP. If decoding
* is continued for the current GOP, artifacts may be present.
*/
AOM_CODEC_CORRUPT_FRAME,
/*!\brief An application-supplied parameter is not valid.
*
*/
AOM_CODEC_INVALID_PARAM,
/*!\brief An iterator reached the end of list.
*
*/
AOM_CODEC_LIST_END
} aom_codec_err_t;
/*! \brief Codec capabilities bitfield
*
* Each codec advertises the capabilities it supports as part of its
* ::aom_codec_iface_t interface structure. Capabilities are extra interfaces
* or functionality, and are not required to be supported.
*
* The available flags are specified by AOM_CODEC_CAP_* defines.
*/
typedef long aom_codec_caps_t;
#define AOM_CODEC_CAP_DECODER 0x1 /**< Is a decoder */
#define AOM_CODEC_CAP_ENCODER 0x2 /**< Is an encoder */
/*! \brief Initialization-time Feature Enabling
*
* Certain codec features must be known at initialization time, to allow for
* proper memory allocation.
*
* The available flags are specified by AOM_CODEC_USE_* defines.
*/
typedef long aom_codec_flags_t;
/*!\brief Time Stamp Type
*
* An integer, which when multiplied by the stream's time base, provides
* the absolute time of a sample.
*/
typedef int64_t aom_codec_pts_t;
/*!\brief Codec interface structure.
*
* Contains function pointers and other data private to the codec
* implementation. This structure is opaque to the application. Common
* functions used with this structure:
* - aom_codec_iface_name(aom_codec_iface_t *iface): get the
* name of the codec
* - aom_codec_get_caps(aom_codec_iface_t *iface): returns
* the capabilities of the codec
* - aom_codec_enc_config_default: generate the default config for
* initializing the encoder (see documentation in aom_encoder.h)
* - aom_codec_dec_init, aom_codec_enc_init: initialize the codec context
* structure (see documentation on aom_codec_ctx).
*
* To get access to the AV1 encoder and decoder, use aom_codec_av1_cx() and
* aom_codec_av1_dx().
*/
typedef const struct aom_codec_iface aom_codec_iface_t;
/*!\brief Codec private data structure.
*
* Contains data private to the codec implementation. This structure is opaque
* to the application.
*/
typedef struct aom_codec_priv aom_codec_priv_t;
/*!\brief Compressed Frame Flags
*
* This type represents a bitfield containing information about a compressed
* frame that may be useful to an application. The most significant 16 bits
* can be used by an algorithm to provide additional detail, for example to
* support frame types that are codec specific (MPEG-1 D-frames for example)
*/
typedef uint32_t aom_codec_frame_flags_t;
#define AOM_FRAME_IS_KEY 0x1u /**< frame is the start of a GOP */
/*!\brief frame can be dropped without affecting the stream (no future frame
* depends on this one) */
#define AOM_FRAME_IS_DROPPABLE 0x2u
/*!\brief this is an INTRA_ONLY frame */
#define AOM_FRAME_IS_INTRAONLY 0x10u
/*!\brief this is an S-frame */
#define AOM_FRAME_IS_SWITCH 0x20u
/*!\brief this is an error-resilient frame */
#define AOM_FRAME_IS_ERROR_RESILIENT 0x40u
/*!\brief this is a key-frame dependent recovery-point frame */
#define AOM_FRAME_IS_DELAYED_RANDOM_ACCESS_POINT 0x80u
/*!\brief Iterator
*
* Opaque storage used for iterating over lists.
*/
typedef const void *aom_codec_iter_t;
/*!\brief Codec context structure
*
* All codecs \ref MUST support this context structure fully. In general,
* this data should be considered private to the codec algorithm, and
* not be manipulated or examined by the calling application. Applications
* may reference the 'name' member to get a printable description of the
* algorithm.
*/
typedef struct aom_codec_ctx {
const char *name; /**< Printable interface name */
aom_codec_iface_t *iface; /**< Interface pointers */
aom_codec_err_t err; /**< Last returned error */
const char *err_detail; /**< Detailed info, if available */
aom_codec_flags_t init_flags; /**< Flags passed at init time */
union {
/**< Decoder Configuration Pointer */
const struct aom_codec_dec_cfg *dec;
/**< Encoder Configuration Pointer */
const struct aom_codec_enc_cfg *enc;
const void *raw;
} config; /**< Configuration pointer aliasing union */
aom_codec_priv_t *priv; /**< Algorithm private storage */
} aom_codec_ctx_t;
/*!\brief Bit depth for codec
* *
* This enumeration determines the bit depth of the codec.
*/
typedef enum aom_bit_depth {
AOM_BITS_8 = 8, /**< 8 bits */
AOM_BITS_10 = 10, /**< 10 bits */
AOM_BITS_12 = 12, /**< 12 bits */
} aom_bit_depth_t;
/*!\brief Superblock size selection.
*
* Defines the superblock size used for encoding. The superblock size can
* either be fixed at 64x64 or 128x128 pixels, or it can be dynamically
* selected by the encoder for each frame.
*/
typedef enum aom_superblock_size {
AOM_SUPERBLOCK_SIZE_64X64, /**< Always use 64x64 superblocks. */
AOM_SUPERBLOCK_SIZE_128X128, /**< Always use 128x128 superblocks. */
AOM_SUPERBLOCK_SIZE_DYNAMIC /**< Select superblock size dynamically. */
} aom_superblock_size_t;
/*
* Library Version Number Interface
*
* For example, see the following sample return values:
* aom_codec_version() (1<<16 | 2<<8 | 3)
* aom_codec_version_str() "v1.2.3-rc1-16-gec6a1ba"
* aom_codec_version_extra_str() "rc1-16-gec6a1ba"
*/
/*!\brief Return the version information (as an integer)
*
* Returns a packed encoding of the library version number. This will only
* include the major.minor.patch component of the version number. Note that this
* encoded value should be accessed through the macros provided, as the encoding
* may change in the future.
*
*/
int aom_codec_version(void);
/*!\brief Return the major version number */
#define aom_codec_version_major() ((aom_codec_version() >> 16) & 0xff)
/*!\brief Return the minor version number */
#define aom_codec_version_minor() ((aom_codec_version() >> 8) & 0xff)
/*!\brief Return the patch version number */
#define aom_codec_version_patch() ((aom_codec_version() >> 0) & 0xff)
/*!\brief Return the version information (as a string)
*
* Returns a printable string containing the full library version number. This
* may contain additional text following the three digit version number, as to
* indicate release candidates, pre-release versions, etc.
*
*/
const char *aom_codec_version_str(void);
/*!\brief Return the version information (as a string)
*
* Returns a printable "extra string". This is the component of the string
* returned by aom_codec_version_str() following the three digit version number.
*
*/
const char *aom_codec_version_extra_str(void);
/*!\brief Return the build configuration
*
* Returns a printable string containing an encoded version of the build
* configuration. This may be useful to aom support.
*
*/
const char *aom_codec_build_config(void);
/*!\brief Return the name for a given interface
*
* Returns a human readable string for name of the given codec interface.
*
* \param[in] iface Interface pointer
*
*/
const char *aom_codec_iface_name(aom_codec_iface_t *iface);
/*!\brief Convert error number to printable string
*
* Returns a human readable string for the last error returned by the
* algorithm. The returned error will be one line and will not contain
* any newline characters.
*
*
* \param[in] err Error number.
*
*/
const char *aom_codec_err_to_string(aom_codec_err_t err);
/*!\brief Retrieve error synopsis for codec context
*
* Returns a human readable string for the last error returned by the
* algorithm. The returned error will be one line and will not contain
* any newline characters.
*
*
* \param[in] ctx Pointer to this instance's context.
*
*/
const char *aom_codec_error(const aom_codec_ctx_t *ctx);
/*!\brief Retrieve detailed error information for codec context
*
* Returns a human readable string providing detailed information about
* the last error. The returned string is only valid until the next
* aom_codec_* function call (except aom_codec_error and
* aom_codec_error_detail) on the codec context.
*
* \param[in] ctx Pointer to this instance's context.
*
* \retval NULL
* No detailed information is available.
*/
const char *aom_codec_error_detail(const aom_codec_ctx_t *ctx);
/* REQUIRED FUNCTIONS
*
* The following functions are required to be implemented for all codecs.
* They represent the base case functionality expected of all codecs.
*/
/*!\brief Destroy a codec instance
*
* Destroys a codec context, freeing any associated memory buffers.
*
* \param[in] ctx Pointer to this instance's context
*
* \retval #AOM_CODEC_OK
* The codec instance has been destroyed.
* \retval #AOM_CODEC_INVALID_PARAM
* ctx is a null pointer.
* \retval #AOM_CODEC_ERROR
* Codec context not initialized.
*/
aom_codec_err_t aom_codec_destroy(aom_codec_ctx_t *ctx);
/*!\brief Get the capabilities of an algorithm.
*
* Retrieves the capabilities bitfield from the algorithm's interface.
*
* \param[in] iface Pointer to the algorithm interface
*
*/
aom_codec_caps_t aom_codec_get_caps(aom_codec_iface_t *iface);
/*!\name Codec Control
*
* The aom_codec_control function exchanges algorithm specific data with the
* codec instance. Additionally, the macro AOM_CODEC_CONTROL_TYPECHECKED is
* provided, which will type-check the parameter against the control ID before
* calling aom_codec_control - note that this macro requires the control ID
* to be directly encoded in it, e.g.,
* AOM_CODEC_CONTROL_TYPECHECKED(&ctx, AOME_SET_CPUUSED, 8).
*
* The codec control IDs can be found in aom.h, aomcx.h, and aomdx.h
* (defined as aom_com_control_id, aome_enc_control_id, and aom_dec_control_id).
* @{
*/
/*!\brief Algorithm Control
*
* aom_codec_control takes a context, a control ID, and a third parameter
* (with varying type). If the context is non-null and an error occurs,
* ctx->err will be set to the same value as the return value.
*
* \param[in] ctx Pointer to this instance's context
* \param[in] ctrl_id Algorithm specific control identifier.
* Must be nonzero.
*
* \retval #AOM_CODEC_OK
* The control request was processed.
* \retval #AOM_CODEC_ERROR
* The control request was not processed.
* \retval #AOM_CODEC_INVALID_PARAM
* The control ID was zero, or the data was not valid.
*/
aom_codec_err_t aom_codec_control(aom_codec_ctx_t *ctx, int ctrl_id, ...);
/*!\brief Key & Value API
*
* aom_codec_set_option() takes a context, a key (option name) and a value. If
* the context is non-null and an error occurs, ctx->err will be set to the same
* value as the return value.
*
* \param[in] ctx Pointer to this instance's context
* \param[in] name The name of the option (key)
* \param[in] value The value of the option
*
* \retval #AOM_CODEC_OK
* The value of the option was set.
* \retval #AOM_CODEC_INVALID_PARAM
* The data was not valid.
* \retval #AOM_CODEC_ERROR
* The option was not successfully set.
*/
aom_codec_err_t aom_codec_set_option(aom_codec_ctx_t *ctx, const char *name,
const char *value);
/*!\brief aom_codec_control wrapper macro (adds type-checking, less flexible)
*
* This macro allows for type safe conversions across the variadic parameter
* to aom_codec_control(). However, it requires the explicit control ID
* be passed in (it cannot be passed in via a variable) -- otherwise a compiler
* error will occur. After the type checking, it calls aom_codec_control.
*/
#define AOM_CODEC_CONTROL_TYPECHECKED(ctx, id, data) \
aom_codec_control_typechecked_##id(ctx, id, data) /**<\hideinitializer*/
/*!\brief Creates type checking mechanisms for aom_codec_control
*
* It defines a static function with the correctly typed arguments as a wrapper
* to the type-unsafe aom_codec_control function. It also creates a typedef
* for each type.
*/
#define AOM_CTRL_USE_TYPE(id, typ) \
static aom_codec_err_t aom_codec_control_typechecked_##id( \
aom_codec_ctx_t *, int, typ) AOM_UNUSED; \
static aom_codec_err_t aom_codec_control_typechecked_##id( \
aom_codec_ctx_t *ctx, int ctrl, typ data) { \
return aom_codec_control(ctx, ctrl, data); \
} /**<\hideinitializer*/ \
typedef typ aom_codec_control_type_##id;
/*!@} end Codec Control group */
/*!\brief OBU types. */
typedef enum ATTRIBUTE_PACKED {
OBU_SEQUENCE_HEADER = 1,
OBU_TEMPORAL_DELIMITER = 2,
OBU_FRAME_HEADER = 3,
OBU_TILE_GROUP = 4,
OBU_METADATA = 5,
OBU_FRAME = 6,
OBU_REDUNDANT_FRAME_HEADER = 7,
OBU_TILE_LIST = 8,
OBU_PADDING = 15,
} OBU_TYPE;
/*!\brief OBU metadata types. */
typedef enum {
OBU_METADATA_TYPE_AOM_RESERVED_0 = 0,
OBU_METADATA_TYPE_HDR_CLL = 1,
OBU_METADATA_TYPE_HDR_MDCV = 2,
OBU_METADATA_TYPE_SCALABILITY = 3,
OBU_METADATA_TYPE_ITUT_T35 = 4,
OBU_METADATA_TYPE_TIMECODE = 5,
} OBU_METADATA_TYPE;
/*!\brief Returns string representation of OBU_TYPE.
*
* \param[in] type The OBU_TYPE to convert to string.
*/
const char *aom_obu_type_to_string(OBU_TYPE type);
/*!@} - end defgroup codec*/
#ifdef __cplusplus
}
#endif
#endif // AOM_AOM_AOM_CODEC_H_
@@ -0,0 +1,257 @@
/*
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
*
* This source code is subject to the terms of the BSD 2 Clause License and
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
* was not distributed with this source code in the LICENSE file, you can
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
* Media Patent License 1.0 was not distributed with this source code in the
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
#ifndef AOM_AOM_AOM_DECODER_H_
#define AOM_AOM_AOM_DECODER_H_
/*!\defgroup decoder Decoder Algorithm Interface
* \ingroup codec
* This abstraction allows applications using this decoder to easily support
* multiple video formats with minimal code duplication. This section describes
* the interface common to all decoders.
* @{
*/
/*!\file
* \brief Describes the decoder algorithm interface to applications.
*
* This file describes the interface between an application and a
* video decoder algorithm.
*
*/
#ifdef __cplusplus
extern "C" {
#endif
#include "aom/aom_codec.h"
#include "aom/aom_frame_buffer.h"
/*!\brief Current ABI version number
*
* \internal
* If this file is altered in any way that changes the ABI, this value
* must be bumped. Examples include, but are not limited to, changing
* types, removing or reassigning enums, adding/removing/rearranging
* fields to structures
*/
#define AOM_DECODER_ABI_VERSION \
(6 + AOM_CODEC_ABI_VERSION) /**<\hideinitializer*/
/*! \brief Decoder capabilities bitfield
*
* Each decoder advertises the capabilities it supports as part of its
* ::aom_codec_iface_t interface structure. Capabilities are extra interfaces
* or functionality, and are not required to be supported by a decoder.
*
* The available flags are specified by AOM_CODEC_CAP_* defines.
*/
/*!brief Can support external frame buffers */
#define AOM_CODEC_CAP_EXTERNAL_FRAME_BUFFER 0x200000
/*! \brief Initialization-time Feature Enabling
*
* Certain codec features must be known at initialization time, to allow for
* proper memory allocation.
*
* The available flags are specified by AOM_CODEC_USE_* defines.
*/
/*!\brief Stream properties
*
* This structure is used to query or set properties of the decoded
* stream.
*/
typedef struct aom_codec_stream_info {
unsigned int w; /**< Width (or 0 for unknown/default) */
unsigned int h; /**< Height (or 0 for unknown/default) */
unsigned int is_kf; /**< Current frame is a keyframe */
unsigned int number_spatial_layers; /**< Number of spatial layers */
unsigned int number_temporal_layers; /**< Number of temporal layers */
unsigned int is_annexb; /**< Is Bitstream in Annex-B format */
} aom_codec_stream_info_t;
/* REQUIRED FUNCTIONS
*
* The following functions are required to be implemented for all decoders.
* They represent the base case functionality expected of all decoders.
*/
/*!\brief Initialization Configurations
*
* This structure is used to pass init time configuration options to the
* decoder.
*/
typedef struct aom_codec_dec_cfg {
unsigned int threads; /**< Maximum number of threads to use, default 1 */
unsigned int w; /**< Width */
unsigned int h; /**< Height */
unsigned int allow_lowbitdepth; /**< Allow use of low-bitdepth coding path */
} aom_codec_dec_cfg_t; /**< alias for struct aom_codec_dec_cfg */
/*!\brief Initialize a decoder instance
*
* Initializes a decoder context using the given interface. Applications
* should call the aom_codec_dec_init convenience macro instead of this
* function directly, to ensure that the ABI version number parameter
* is properly initialized.
*
* If the library was configured with cmake -DCONFIG_MULTITHREAD=0, this
* call is not thread safe and should be guarded with a lock if being used
* in a multithreaded context.
*
* \param[in] ctx Pointer to this instance's context.
* \param[in] iface Pointer to the algorithm interface to use.
* \param[in] cfg Configuration to use, if known. May be NULL.
* \param[in] flags Bitfield of AOM_CODEC_USE_* flags
* \param[in] ver ABI version number. Must be set to
* AOM_DECODER_ABI_VERSION
* \retval #AOM_CODEC_OK
* The decoder algorithm has been initialized.
* \retval #AOM_CODEC_MEM_ERROR
* Memory allocation failed.
*/
aom_codec_err_t aom_codec_dec_init_ver(aom_codec_ctx_t *ctx,
aom_codec_iface_t *iface,
const aom_codec_dec_cfg_t *cfg,
aom_codec_flags_t flags, int ver);
/*!\brief Convenience macro for aom_codec_dec_init_ver()
*
* Ensures the ABI version parameter is properly set.
*/
#define aom_codec_dec_init(ctx, iface, cfg, flags) \
aom_codec_dec_init_ver(ctx, iface, cfg, flags, AOM_DECODER_ABI_VERSION)
/*!\brief Parse stream info from a buffer
*
* Performs high level parsing of the bitstream. Construction of a decoder
* context is not necessary. Can be used to determine if the bitstream is
* of the proper format, and to extract information from the stream.
*
* \param[in] iface Pointer to the algorithm interface
* \param[in] data Pointer to a block of data to parse
* \param[in] data_sz Size of the data buffer
* \param[in,out] si Pointer to stream info to update. The is_annexb
* member \ref MUST be properly initialized. This
* function sets the rest of the members.
*
* \retval #AOM_CODEC_OK
* Bitstream is parsable and stream information updated.
* \retval #AOM_CODEC_INVALID_PARAM
* One of the arguments is invalid, for example a NULL pointer.
* \retval #AOM_CODEC_UNSUP_BITSTREAM
* The decoder didn't recognize the coded data, or the
* buffer was too short.
*/
aom_codec_err_t aom_codec_peek_stream_info(aom_codec_iface_t *iface,
const uint8_t *data, size_t data_sz,
aom_codec_stream_info_t *si);
/*!\brief Return information about the current stream.
*
* Returns information about the stream that has been parsed during decoding.
*
* \param[in] ctx Pointer to this instance's context
* \param[in,out] si Pointer to stream info to update.
*
* \retval #AOM_CODEC_OK
* Bitstream is parsable and stream information updated.
* \retval #AOM_CODEC_INVALID_PARAM
* One of the arguments is invalid, for example a NULL pointer.
* \retval #AOM_CODEC_UNSUP_BITSTREAM
* The decoder couldn't parse the submitted data.
*/
aom_codec_err_t aom_codec_get_stream_info(aom_codec_ctx_t *ctx,
aom_codec_stream_info_t *si);
/*!\brief Decode data
*
* Processes a buffer of coded data. Encoded data \ref MUST be passed in DTS
* (decode time stamp) order. Frames produced will always be in PTS
* (presentation time stamp) order.
*
* \param[in] ctx Pointer to this instance's context
* \param[in] data Pointer to this block of new coded data.
* \param[in] data_sz Size of the coded data, in bytes.
* \param[in] user_priv Application specific data to associate with
* this frame.
*
* \return Returns #AOM_CODEC_OK if the coded data was processed completely
* and future pictures can be decoded without error. Otherwise,
* see the descriptions of the other error codes in ::aom_codec_err_t
* for recoverability capabilities.
*/
aom_codec_err_t aom_codec_decode(aom_codec_ctx_t *ctx, const uint8_t *data,
size_t data_sz, void *user_priv);
/*!\brief Decoded frames iterator
*
* Iterates over a list of the frames available for display. The iterator
* storage should be initialized to NULL to start the iteration. Iteration is
* complete when this function returns NULL.
*
* The list of available frames becomes valid upon completion of the
* aom_codec_decode call, and remains valid until the next call to
* aom_codec_decode.
*
* \param[in] ctx Pointer to this instance's context
* \param[in,out] iter Iterator storage, initialized to NULL
*
* \return Returns a pointer to an image, if one is ready for display. Frames
* produced will always be in PTS (presentation time stamp) order.
*/
aom_image_t *aom_codec_get_frame(aom_codec_ctx_t *ctx, aom_codec_iter_t *iter);
/*!\defgroup cap_external_frame_buffer External Frame Buffer Functions
*
* The following function is required to be implemented for all decoders
* that advertise the AOM_CODEC_CAP_EXTERNAL_FRAME_BUFFER capability.
* Calling this function for codecs that don't advertise this capability
* will result in an error code being returned, usually AOM_CODEC_INCAPABLE.
* @{
*/
/*!\brief Pass in external frame buffers for the decoder to use.
*
* Registers functions to be called when libaom needs a frame buffer
* to decode the current frame and a function to be called when libaom does
* not internally reference the frame buffer. This set function must
* be called before the first call to decode or libaom will assume the
* default behavior of allocating frame buffers internally.
*
* \param[in] ctx Pointer to this instance's context
* \param[in] cb_get Pointer to the get callback function
* \param[in] cb_release Pointer to the release callback function
* \param[in] cb_priv Callback's private data
*
* \retval #AOM_CODEC_OK
* External frame buffers will be used by libaom.
* \retval #AOM_CODEC_INVALID_PARAM
* One or more of the callbacks were NULL.
* \retval #AOM_CODEC_ERROR
* Decoder context not initialized.
* \retval #AOM_CODEC_INCAPABLE
* Algorithm not capable of using external frame buffers.
*
* \note
* When decoding AV1, the application may be required to pass in at least
* #AOM_MAXIMUM_WORK_BUFFERS external frame buffers.
*/
aom_codec_err_t aom_codec_set_frame_buffer_functions(
aom_codec_ctx_t *ctx, aom_get_frame_buffer_cb_fn_t cb_get,
aom_release_frame_buffer_cb_fn_t cb_release, void *cb_priv);
/*!@} - end defgroup cap_external_frame_buffer */
/*!@} - end defgroup decoder*/
#ifdef __cplusplus
}
#endif
#endif // AOM_AOM_AOM_DECODER_H_
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,452 @@
/*
* Copyright (c) 2021, Alliance for Open Media. All rights reserved
*
* This source code is subject to the terms of the BSD 2 Clause License and
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
* was not distributed with this source code in the LICENSE file, you can
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
* Media Patent License 1.0 was not distributed with this source code in the
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
#ifndef AOM_AOM_AOM_EXTERNAL_PARTITION_H_
#define AOM_AOM_AOM_EXTERNAL_PARTITION_H_
/*!\defgroup aom_encoder AOMedia AOM/AV1 Encoder
* \ingroup aom
*
* @{
*/
#include <stdint.h>
/*!\file
* \brief Provides function pointer definitions for the external partition.
*
* \note The external partition API should be considered experimental. Until the
* external partition API is declared stable, breaking changes may be made to
* this API in a future libaom release.
*/
/*!\brief Current ABI version number
*
* \internal
* If this file is altered in any way that changes the ABI, this value
* must be bumped. Examples include, but are not limited to, changing
* types, removing or reassigning enums, adding/removing/rearranging
* fields to structures.
*/
#define AOM_EXT_PART_ABI_VERSION 8
#ifdef __cplusplus
extern "C" {
#endif
/*!\brief Abstract external partition model handler
*/
typedef void *aom_ext_part_model_t;
/*!\brief Number of features to determine whether to skip partition none and
* do partition split directly. The same as "FEATURE_SIZE_SMS_SPLIT".
*/
#define AOM_EXT_PART_SIZE_DIRECT_SPLIT 17
/*!\brief Number of features to use simple motion search to prune out
* rectangular partition in some direction. The same as
* "FEATURE_SIZE_SMS_PRUNE_PART".
*/
#define AOM_EXT_PART_SIZE_PRUNE_PART 25
/*!\brief Number of features to prune split and rectangular partition
* after PARTITION_NONE.
*/
#define AOM_EXT_PART_SIZE_PRUNE_NONE 4
/*!\brief Number of features to terminates partition after partition none using
* simple_motion_search features and the rate, distortion, and rdcost of
* PARTITION_NONE. The same as "FEATURE_SIZE_SMS_TERM_NONE".
*/
#define AOM_EXT_PART_SIZE_TERM_NONE 28
/*!\brief Number of features to terminates partition after partition split.
*/
#define AOM_EXT_PART_SIZE_TERM_SPLIT 31
/*!\brief Number of features to prune rectangular partition using stats
* collected after partition split.
*/
#define AOM_EXT_PART_SIZE_PRUNE_RECT 9
/*!\brief Number of features to prune AB partition using stats
* collected after rectangular partition..
*/
#define AOM_EXT_PART_SIZE_PRUNE_AB 10
/*!\brief Number of features to prune 4-way partition using stats
* collected after AB partition.
*/
#define AOM_EXT_PART_SIZE_PRUNE_4_WAY 18
/*!\brief Decision mode of the external partition model.
* AOM_EXT_PART_WHOLE_TREE: the external partition model should provide the
* whole partition tree for the superblock.
*
* AOM_EXT_PART_RECURSIVE: the external partition model provides the partition
* decision of the current block only. The decision process starts from
* the superblock size, down to the smallest block size (4x4) recursively.
*/
typedef enum aom_ext_part_decision_mode {
AOM_EXT_PART_WHOLE_TREE = 0,
AOM_EXT_PART_RECURSIVE = 1,
} aom_ext_part_decision_mode_t;
/*!\brief Config information sent to the external partition model.
*
* For example, the maximum superblock size determined by the sequence header.
*/
typedef struct aom_ext_part_config {
int superblock_size; ///< super block size (either 64x64 or 128x128)
} aom_ext_part_config_t;
/*!\brief Features pass to the external model to make partition decisions.
* Specifically, features collected before NONE partition.
* Features "f" are used to determine:
* partition_none_allowed, partition_horz_allowed, partition_vert_allowed,
* do_rectangular_split, do_square_split
* Features "f_part2" are used to determine:
* prune_horz, prune_vert.
*/
typedef struct aom_partition_features_before_none {
/*! features to determine whether skip partition none and do split directly */
float f[AOM_EXT_PART_SIZE_DIRECT_SPLIT];
/*! features to determine whether to prune rectangular partition */
float f_part2[AOM_EXT_PART_SIZE_PRUNE_PART];
} aom_partition_features_before_none_t;
/*!\brief Features pass to the external model to make partition decisions.
* Specifically, features collected after NONE partition.
*/
typedef struct aom_partition_features_none {
/*! features to prune split and rectangular partition */
float f[AOM_EXT_PART_SIZE_PRUNE_NONE];
/*! features to determine termination of partition */
float f_terminate[AOM_EXT_PART_SIZE_TERM_NONE];
} aom_partition_features_none_t;
/*!\brief Features pass to the external model to make partition decisions.
* Specifically, features collected after SPLIT partition.
*/
typedef struct aom_partition_features_split {
/*! features to determine termination of partition */
float f_terminate[AOM_EXT_PART_SIZE_TERM_SPLIT];
/*! features to determine pruning rect partition */
float f_prune_rect[AOM_EXT_PART_SIZE_PRUNE_RECT];
} aom_partition_features_split_t;
/*!\brief Features pass to the external model to make partition decisions.
* Specifically, features collected after RECTANGULAR partition.
*/
typedef struct aom_partition_features_rect {
/*! features to determine pruning AB partition */
float f[AOM_EXT_PART_SIZE_PRUNE_AB];
} aom_partition_features_rect_t;
/*!\brief Features pass to the external model to make partition decisions.
* Specifically, features collected after AB partition: HORZ_A, HORZ_B, VERT_A,
* VERT_B.
*/
typedef struct aom_partition_features_ab {
/*! features to determine pruning 4-way partition */
float f[AOM_EXT_PART_SIZE_PRUNE_4_WAY];
} aom_partition_features_ab_t;
/*!\brief Feature id to tell the external model the current stage in partition
* pruning and what features to use to make decisions accordingly.
*/
typedef enum {
AOM_EXT_PART_FEATURE_BEFORE_NONE,
AOM_EXT_PART_FEATURE_BEFORE_NONE_PART2,
AOM_EXT_PART_FEATURE_AFTER_NONE,
AOM_EXT_PART_FEATURE_AFTER_NONE_PART2,
AOM_EXT_PART_FEATURE_AFTER_SPLIT,
AOM_EXT_PART_FEATURE_AFTER_SPLIT_PART2,
AOM_EXT_PART_FEATURE_AFTER_RECT,
AOM_EXT_PART_FEATURE_AFTER_AB
} AOM_EXT_PART_FEATURE_ID;
/*!\brief Features collected from the tpl process.
*
* The tpl process collects information that help measure the inter-frame
* dependency.
* The tpl process is computed in the unit of tpl_bsize_1d (16x16).
* Therefore, the max number of units inside a superblock is
* 128x128 / (16x16) = 64. Change it if the tpl process changes.
*/
typedef struct aom_sb_tpl_features {
int available; ///< If tpl stats are available
int tpl_unit_length; ///< The block length of tpl process
int num_units; ///< The number of units inside the current superblock
int64_t intra_cost[64]; ///< The intra cost of each unit
int64_t inter_cost[64]; ///< The inter cost of each unit
int64_t mc_dep_cost[64]; ///< The motion compensated dependency cost
} aom_sb_tpl_features_t;
/*!\brief Features collected from the simple motion process.
*
* The simple motion process collects information by applying motion compensated
* prediction on each block.
* The block size is 16x16, which could be changed. If it is changed, update
* comments and the array size here.
*/
typedef struct aom_sb_simple_motion_features {
int unit_length; ///< The block length of the simple motion process
int num_units; ///< The number of units inside the current superblock
int block_sse[64]; ///< Sum of squared error of each unit
int block_var[64]; ///< Variance of each unit
} aom_sb_simple_motion_features_t;
/*!\brief Features of each super block.
*
* Features collected for each super block before partition search.
*/
typedef struct aom_sb_features {
/*! Features from motion search */
aom_sb_simple_motion_features_t motion_features;
/*! Features from tpl process */
aom_sb_tpl_features_t tpl_features;
} aom_sb_features_t;
/*!\brief Features pass to the external model to make partition decisions.
*
* The encoder sends these features to the external model through
* "func()" defined in .....
*
* NOTE: new member variables may be added to this structure in the future.
* Once new features are finalized, bump the major version of libaom.
*/
typedef struct aom_partition_features {
// Features for the current supervised multi-stage ML model.
/*! Feature ID to indicate active features */
AOM_EXT_PART_FEATURE_ID id;
/*! Features collected before NONE partition */
aom_partition_features_before_none_t before_part_none;
/*! Features collected after NONE partition */
aom_partition_features_none_t after_part_none;
/*! Features collected after SPLIT partition */
aom_partition_features_split_t after_part_split;
/*! Features collected after RECTANGULAR partition */
aom_partition_features_rect_t after_part_rect;
/*! Features collected after AB partition */
aom_partition_features_ab_t after_part_ab;
// Features for a new ML model.
aom_sb_features_t sb_features; ///< Features collected for the super block
int mi_row; ///< Mi_row position of the block
int mi_col; ///< Mi_col position of the block
int frame_width; ///< Frame width
int frame_height; ///< Frame height
int block_size; ///< As "BLOCK_SIZE" in av1/common/enums.h
/*!
* Valid partition types. A bitmask is used. "1" represents the
* corresponding type is valid. The bitmask follows the enum order for
* PARTITION_TYPE in "enums.h" to represent one partition type at a bit.
* For example, 0x01 stands for only PARTITION_NONE is valid,
* 0x09 (00...001001) stands for PARTITION_NONE and PARTITION_SPLIT are valid.
*/
int valid_partition_types;
int update_type; ///< Frame update type, defined in ratectrl.h
int qindex; ///< Quantization index, range: [0, 255]
int rdmult; ///< Rate-distortion multiplier
int pyramid_level; ///< The level of this frame in the hierarchical structure
int has_above_block; ///< Has above neighbor block
int above_block_width; ///< Width of the above block, -1 if not exist
int above_block_height; ///< Height of the above block, -1 if not exist
int has_left_block; ///< Has left neighbor block
int left_block_width; ///< Width of the left block, -1 if not exist
int left_block_height; ///< Height of the left block, -1 if not exist
/*!
* The following parameters are collected from applying simple motion search.
* Sum of squared error (SSE) and variance of motion compensated residual
* are good indicators of block partitioning.
* If a block is a square, we also apply motion search for its 4 sub blocks.
* If not a square, their values are -1.
* If a block is able to split horizontally, we apply motion search and get
* stats for horizontal blocks. If not, their values are -1.
* If a block is able to split vertically, we apply motion search and get
* stats for vertical blocks. If not, their values are -1.
*/
unsigned int block_sse; ///< SSE of motion compensated residual
unsigned int block_var; ///< Variance of motion compensated residual
unsigned int sub_block_sse[4]; ///< SSE of sub blocks.
unsigned int sub_block_var[4]; ///< Variance of sub blocks.
unsigned int horz_block_sse[2]; ///< SSE of horz sub blocks
unsigned int horz_block_var[2]; ///< Variance of horz sub blocks
unsigned int vert_block_sse[2]; ///< SSE of vert sub blocks
unsigned int vert_block_var[2]; ///< Variance of vert sub blocks
/*!
* The following parameters are calculated from tpl model.
* If tpl model is not available, their values are -1.
*/
int64_t tpl_intra_cost; ///< Intra cost, ref to "TplDepStats" in tpl_model.h
int64_t tpl_inter_cost; ///< Inter cost in tpl model
int64_t tpl_mc_dep_cost; ///< Motion compensated dependency cost in tpl model
} aom_partition_features_t;
/*!\brief Partition decisions received from the external model.
*
* The encoder receives partition decisions and encodes the superblock
* with the given partition type.
* The encoder receives it from "func()" define in ....
*
* NOTE: new member variables may be added to this structure in the future.
* Once new features are finalized, bump the major version of libaom.
*/
typedef struct aom_partition_decision {
// Decisions for directly set partition types
int is_final_decision; ///< The flag whether it's the final decision
int num_nodes; ///< The number of leaf nodes
int partition_decision[2048]; ///< Partition decisions
int current_decision; ///< Partition decision for the current block
// Decisions for partition type pruning
int terminate_partition_search; ///< Terminate further partition search
int partition_none_allowed; ///< Allow partition none type
int partition_rect_allowed[2]; ///< Allow rectangular partitions
int do_rectangular_split; ///< Try rectangular split partition
int do_square_split; ///< Try square split partition
int prune_rect_part[2]; ///< Prune rectangular partition
int horza_partition_allowed; ///< Allow HORZ_A partition
int horzb_partition_allowed; ///< Allow HORZ_B partition
int verta_partition_allowed; ///< Allow VERT_A partition
int vertb_partition_allowed; ///< Allow VERT_B partition
int partition_horz4_allowed; ///< Allow HORZ4 partition
int partition_vert4_allowed; ///< Allow VERT4 partition
} aom_partition_decision_t;
/*!\brief Encoding stats for the given partition decision.
*
* The encoding stats collected by encoding the superblock with the
* given partition types.
* The encoder sends the stats to the external model for training
* or inference through "func()" defined in ....
*/
typedef struct aom_partition_stats {
int rate; ///< Rate cost of the block
int64_t dist; ///< Distortion of the block
int64_t rdcost; ///< Rate-distortion cost of the block
} aom_partition_stats_t;
/*!\brief Enum for return status.
*/
typedef enum aom_ext_part_status {
AOM_EXT_PART_OK = 0, ///< Status of success
AOM_EXT_PART_ERROR = 1, ///< Status of failure
AOM_EXT_PART_TEST = 2, ///< Status used for tests
} aom_ext_part_status_t;
/*!\brief Callback of creating an external partition model.
*
* The callback is invoked by the encoder to create an external partition
* model.
*
* \param[in] priv Callback's private data
* \param[in] part_config Config information pointer for model creation
* \param[out] ext_part_model Pointer to the model
*/
typedef aom_ext_part_status_t (*aom_ext_part_create_model_fn_t)(
void *priv, const aom_ext_part_config_t *part_config,
aom_ext_part_model_t *ext_part_model);
/*!\brief Callback of sending features to the external partition model.
*
* The callback is invoked by the encoder to send features to the external
* partition model.
*
* \param[in] ext_part_model The external model
* \param[in] part_features Pointer to the features
*/
typedef aom_ext_part_status_t (*aom_ext_part_send_features_fn_t)(
aom_ext_part_model_t ext_part_model,
const aom_partition_features_t *part_features);
/*!\brief Callback of receiving partition decisions from the external
* partition model.
*
* The callback is invoked by the encoder to receive partition decisions from
* the external partition model.
*
* \param[in] ext_part_model The external model
* \param[in] ext_part_decision Pointer to the partition decisions
*/
typedef aom_ext_part_status_t (*aom_ext_part_get_decision_fn_t)(
aom_ext_part_model_t ext_part_model,
aom_partition_decision_t *ext_part_decision);
/*!\brief Callback of sending stats to the external partition model.
*
* The callback is invoked by the encoder to send encoding stats to
* the external partition model.
*
* \param[in] ext_part_model The external model
* \param[in] ext_part_stats Pointer to the encoding stats
*/
typedef aom_ext_part_status_t (*aom_ext_part_send_partition_stats_fn_t)(
aom_ext_part_model_t ext_part_model,
const aom_partition_stats_t *ext_part_stats);
/*!\brief Callback of deleting the external partition model.
*
* The callback is invoked by the encoder to delete the external partition
* model.
*
* \param[in] ext_part_model The external model
*/
typedef aom_ext_part_status_t (*aom_ext_part_delete_model_fn_t)(
aom_ext_part_model_t ext_part_model);
/*!\brief Callback function set for external partition model.
*
* Uses can enable external partition model by registering a set of
* callback functions with the flag: AV1E_SET_EXTERNAL_PARTITION_MODEL
*/
typedef struct aom_ext_part_funcs {
/*!
* Create an external partition model.
*/
aom_ext_part_create_model_fn_t create_model;
/*!
* Send features to the external partition model to make partition decisions.
*/
aom_ext_part_send_features_fn_t send_features;
/*!
* Get partition decisions from the external partition model.
*/
aom_ext_part_get_decision_fn_t get_partition_decision;
/*!
* Send stats of the current partition to the external model.
*/
aom_ext_part_send_partition_stats_fn_t send_partition_stats;
/*!
* Delete the external partition model.
*/
aom_ext_part_delete_model_fn_t delete_model;
/*!
* The decision mode of the model.
*/
aom_ext_part_decision_mode_t decision_mode;
/*!
* Private data for the external partition model.
*/
void *priv;
} aom_ext_part_funcs_t;
/*!@} - end defgroup aom_encoder*/
#ifdef __cplusplus
} // extern "C"
#endif
#endif // AOM_AOM_AOM_EXTERNAL_PARTITION_H_
@@ -0,0 +1,84 @@
/*
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
*
* This source code is subject to the terms of the BSD 2 Clause License and
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
* was not distributed with this source code in the LICENSE file, you can
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
* Media Patent License 1.0 was not distributed with this source code in the
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
#ifndef AOM_AOM_AOM_FRAME_BUFFER_H_
#define AOM_AOM_AOM_FRAME_BUFFER_H_
/*!\file
* \brief Describes the decoder external frame buffer interface.
*/
#ifdef __cplusplus
extern "C" {
#endif
#include "aom/aom_integer.h"
/*!\brief The maximum number of work buffers used by libaom.
* Support maximum 4 threads to decode video in parallel.
* Each thread will use one work buffer.
* TODO(hkuang): Add support to set number of worker threads dynamically.
*/
#define AOM_MAXIMUM_WORK_BUFFERS 8
/*!\brief The maximum number of reference buffers that a AV1 encoder may use.
*/
#define AOM_MAXIMUM_REF_BUFFERS 8
/*!\brief External frame buffer
*
* This structure holds allocated frame buffers used by the decoder.
*/
typedef struct aom_codec_frame_buffer {
uint8_t *data; /**< Pointer to the data buffer */
size_t size; /**< Size of data in bytes */
void *priv; /**< Frame's private data */
} aom_codec_frame_buffer_t;
/*!\brief get frame buffer callback prototype
*
* This callback is invoked by the decoder to retrieve data for the frame
* buffer in order for the decode call to complete. The callback must
* allocate at least min_size in bytes and assign it to fb->data. The callback
* must zero out all the data allocated. Then the callback must set fb->size
* to the allocated size. The application does not need to align the allocated
* data. The callback is triggered when the decoder needs a frame buffer to
* decode a compressed image into. This function may be called more than once
* for every call to aom_codec_decode. The application may set fb->priv to
* some data which will be passed back in the aom_image_t and the release
* function call. |fb| is guaranteed to not be NULL. On success the callback
* must return 0. Any failure the callback must return a value less than 0.
*
* \param[in] priv Callback's private data
* \param[in] min_size Size in bytes needed by the buffer
* \param[in,out] fb Pointer to aom_codec_frame_buffer_t
*/
typedef int (*aom_get_frame_buffer_cb_fn_t)(void *priv, size_t min_size,
aom_codec_frame_buffer_t *fb);
/*!\brief release frame buffer callback prototype
*
* This callback is invoked by the decoder when the frame buffer is not
* referenced by any other buffers. |fb| is guaranteed to not be NULL. On
* success the callback must return 0. Any failure the callback must return
* a value less than 0.
*
* \param[in] priv Callback's private data
* \param[in] fb Pointer to aom_codec_frame_buffer_t
*/
typedef int (*aom_release_frame_buffer_cb_fn_t)(void *priv,
aom_codec_frame_buffer_t *fb);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // AOM_AOM_AOM_FRAME_BUFFER_H_
@@ -0,0 +1,448 @@
/*
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
*
* This source code is subject to the terms of the BSD 2 Clause License and
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
* was not distributed with this source code in the LICENSE file, you can
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
* Media Patent License 1.0 was not distributed with this source code in the
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
/*!\file
* \brief Describes the aom image descriptor and associated operations
*
*/
#ifndef AOM_AOM_AOM_IMAGE_H_
#define AOM_AOM_AOM_IMAGE_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "aom/aom_integer.h"
/*!\brief Current ABI version number
*
* \internal
* If this file is altered in any way that changes the ABI, this value
* must be bumped. Examples include, but are not limited to, changing
* types, removing or reassigning enums, adding/removing/rearranging
* fields to structures
*/
#define AOM_IMAGE_ABI_VERSION (9) /**<\hideinitializer*/
#define AOM_IMG_FMT_PLANAR 0x100 /**< Image is a planar format. */
#define AOM_IMG_FMT_UV_FLIP 0x200 /**< V plane precedes U in memory. */
/** 0x400 used to signal alpha channel, skipping for backwards compatibility. */
#define AOM_IMG_FMT_HIGHBITDEPTH 0x800 /**< Image uses 16bit framebuffer. */
/*!\brief List of supported image formats */
typedef enum aom_img_fmt {
AOM_IMG_FMT_NONE,
AOM_IMG_FMT_YV12 =
AOM_IMG_FMT_PLANAR | AOM_IMG_FMT_UV_FLIP | 1, /**< planar YVU */
AOM_IMG_FMT_I420 = AOM_IMG_FMT_PLANAR | 2,
AOM_IMG_FMT_AOMYV12 = AOM_IMG_FMT_PLANAR | AOM_IMG_FMT_UV_FLIP |
3, /** < planar 4:2:0 format with aom color space */
AOM_IMG_FMT_AOMI420 = AOM_IMG_FMT_PLANAR | 4,
AOM_IMG_FMT_I422 = AOM_IMG_FMT_PLANAR | 5,
AOM_IMG_FMT_I444 = AOM_IMG_FMT_PLANAR | 6,
/*!\brief Allows detection of the presence of AOM_IMG_FMT_NV12 at compile time.
*/
#define AOM_HAVE_IMG_FMT_NV12 1
AOM_IMG_FMT_NV12 =
AOM_IMG_FMT_PLANAR | 7, /**< 4:2:0 with U and V interleaved */
AOM_IMG_FMT_I42016 = AOM_IMG_FMT_I420 | AOM_IMG_FMT_HIGHBITDEPTH,
AOM_IMG_FMT_YV1216 = AOM_IMG_FMT_YV12 | AOM_IMG_FMT_HIGHBITDEPTH,
AOM_IMG_FMT_I42216 = AOM_IMG_FMT_I422 | AOM_IMG_FMT_HIGHBITDEPTH,
AOM_IMG_FMT_I44416 = AOM_IMG_FMT_I444 | AOM_IMG_FMT_HIGHBITDEPTH,
} aom_img_fmt_t; /**< alias for enum aom_img_fmt */
/*!\brief List of supported color primaries */
typedef enum aom_color_primaries {
AOM_CICP_CP_RESERVED_0 = 0, /**< For future use */
AOM_CICP_CP_BT_709 = 1, /**< BT.709 */
AOM_CICP_CP_UNSPECIFIED = 2, /**< Unspecified */
AOM_CICP_CP_RESERVED_3 = 3, /**< For future use */
AOM_CICP_CP_BT_470_M = 4, /**< BT.470 System M (historical) */
AOM_CICP_CP_BT_470_B_G = 5, /**< BT.470 System B, G (historical) */
AOM_CICP_CP_BT_601 = 6, /**< BT.601 */
AOM_CICP_CP_SMPTE_240 = 7, /**< SMPTE 240 */
AOM_CICP_CP_GENERIC_FILM =
8, /**< Generic film (color filters using illuminant C) */
AOM_CICP_CP_BT_2020 = 9, /**< BT.2020, BT.2100 */
AOM_CICP_CP_XYZ = 10, /**< SMPTE 428 (CIE 1921 XYZ) */
AOM_CICP_CP_SMPTE_431 = 11, /**< SMPTE RP 431-2 */
AOM_CICP_CP_SMPTE_432 = 12, /**< SMPTE EG 432-1 */
AOM_CICP_CP_RESERVED_13 = 13, /**< For future use (values 13 - 21) */
AOM_CICP_CP_EBU_3213 = 22, /**< EBU Tech. 3213-E */
AOM_CICP_CP_RESERVED_23 = 23 /**< For future use (values 23 - 255) */
} aom_color_primaries_t; /**< alias for enum aom_color_primaries */
/*!\brief List of supported transfer functions */
typedef enum aom_transfer_characteristics {
AOM_CICP_TC_RESERVED_0 = 0, /**< For future use */
AOM_CICP_TC_BT_709 = 1, /**< BT.709 */
AOM_CICP_TC_UNSPECIFIED = 2, /**< Unspecified */
AOM_CICP_TC_RESERVED_3 = 3, /**< For future use */
AOM_CICP_TC_BT_470_M = 4, /**< BT.470 System M (historical) */
AOM_CICP_TC_BT_470_B_G = 5, /**< BT.470 System B, G (historical) */
AOM_CICP_TC_BT_601 = 6, /**< BT.601 */
AOM_CICP_TC_SMPTE_240 = 7, /**< SMPTE 240 M */
AOM_CICP_TC_LINEAR = 8, /**< Linear */
AOM_CICP_TC_LOG_100 = 9, /**< Logarithmic (100 : 1 range) */
AOM_CICP_TC_LOG_100_SQRT10 =
10, /**< Logarithmic (100 * Sqrt(10) : 1 range) */
AOM_CICP_TC_IEC_61966 = 11, /**< IEC 61966-2-4 */
AOM_CICP_TC_BT_1361 = 12, /**< BT.1361 */
AOM_CICP_TC_SRGB = 13, /**< sRGB or sYCC*/
AOM_CICP_TC_BT_2020_10_BIT = 14, /**< BT.2020 10-bit systems */
AOM_CICP_TC_BT_2020_12_BIT = 15, /**< BT.2020 12-bit systems */
AOM_CICP_TC_SMPTE_2084 = 16, /**< SMPTE ST 2084, ITU BT.2100 PQ */
AOM_CICP_TC_SMPTE_428 = 17, /**< SMPTE ST 428 */
AOM_CICP_TC_HLG = 18, /**< BT.2100 HLG, ARIB STD-B67 */
AOM_CICP_TC_RESERVED_19 = 19 /**< For future use (values 19-255) */
} aom_transfer_characteristics_t; /**< alias for enum aom_transfer_function */
/*!\brief List of supported matrix coefficients */
typedef enum aom_matrix_coefficients {
AOM_CICP_MC_IDENTITY = 0, /**< Identity matrix */
AOM_CICP_MC_BT_709 = 1, /**< BT.709 */
AOM_CICP_MC_UNSPECIFIED = 2, /**< Unspecified */
AOM_CICP_MC_RESERVED_3 = 3, /**< For future use */
AOM_CICP_MC_FCC = 4, /**< US FCC 73.628 */
AOM_CICP_MC_BT_470_B_G = 5, /**< BT.470 System B, G (historical) */
AOM_CICP_MC_BT_601 = 6, /**< BT.601 */
AOM_CICP_MC_SMPTE_240 = 7, /**< SMPTE 240 M */
AOM_CICP_MC_SMPTE_YCGCO = 8, /**< YCgCo */
AOM_CICP_MC_BT_2020_NCL =
9, /**< BT.2020 non-constant luminance, BT.2100 YCbCr */
AOM_CICP_MC_BT_2020_CL = 10, /**< BT.2020 constant luminance */
AOM_CICP_MC_SMPTE_2085 = 11, /**< SMPTE ST 2085 YDzDx */
AOM_CICP_MC_CHROMAT_NCL =
12, /**< Chromaticity-derived non-constant luminance */
AOM_CICP_MC_CHROMAT_CL = 13, /**< Chromaticity-derived constant luminance */
AOM_CICP_MC_ICTCP = 14, /**< BT.2100 ICtCp */
AOM_CICP_MC_RESERVED_15 = 15 /**< For future use (values 15-255) */
} aom_matrix_coefficients_t;
/*!\brief List of supported color range */
typedef enum aom_color_range {
AOM_CR_STUDIO_RANGE = 0, /**<- Y [16..235], UV [16..240] (bit depth 8) */
/**<- Y [64..940], UV [64..960] (bit depth 10) */
/**<- Y [256..3760], UV [256..3840] (bit depth 12) */
AOM_CR_FULL_RANGE = 1 /**<- YUV/RGB [0..255] (bit depth 8) */
/**<- YUV/RGB [0..1023] (bit depth 10) */
/**<- YUV/RGB [0..4095] (bit depth 12) */
} aom_color_range_t; /**< alias for enum aom_color_range */
/*!\brief List of chroma sample positions */
typedef enum aom_chroma_sample_position {
AOM_CSP_UNKNOWN = 0, /**< Unknown */
AOM_CSP_VERTICAL = 1, /**< Horizontally co-located with luma(0, 0)*/
/**< sample, between two vertical samples */
AOM_CSP_COLOCATED = 2, /**< Co-located with luma(0, 0) sample */
AOM_CSP_RESERVED = 3 /**< Reserved value */
} aom_chroma_sample_position_t; /**< alias for enum aom_transfer_function */
/*!\brief List of insert flags for Metadata
*
* These flags control how the library treats metadata during encode.
*
* While encoding, when metadata is added to an aom_image via
* aom_img_add_metadata(), the flag passed along with the metadata will
* determine where the metadata OBU will be placed in the encoded OBU stream.
* Metadata will be emitted into the output stream within the next temporal unit
* if it satisfies the specified insertion flag.
*
* During decoding, when the library encounters a metadata OBU, it is always
* flagged as AOM_MIF_ANY_FRAME and emitted with the next output aom_image.
*/
typedef enum aom_metadata_insert_flags {
AOM_MIF_NON_KEY_FRAME = 0, /**< Adds metadata if it's not keyframe */
AOM_MIF_KEY_FRAME = 1, /**< Adds metadata only if it's a keyframe */
AOM_MIF_ANY_FRAME = 2 /**< Adds metadata to any type of frame */
} aom_metadata_insert_flags_t;
/*!\brief Array of aom_metadata structs for an image. */
typedef struct aom_metadata_array aom_metadata_array_t;
/*!\brief Metadata payload. */
typedef struct aom_metadata {
uint32_t type; /**< Metadata type */
uint8_t *payload; /**< Metadata payload data */
size_t sz; /**< Metadata payload size */
aom_metadata_insert_flags_t insert_flag; /**< Metadata insertion flag */
} aom_metadata_t;
/**\brief Image Descriptor */
typedef struct aom_image {
aom_img_fmt_t fmt; /**< Image Format */
aom_color_primaries_t cp; /**< CICP Color Primaries */
aom_transfer_characteristics_t tc; /**< CICP Transfer Characteristics */
aom_matrix_coefficients_t mc; /**< CICP Matrix Coefficients */
int monochrome; /**< Whether image is monochrome */
aom_chroma_sample_position_t csp; /**< chroma sample position */
aom_color_range_t range; /**< Color Range */
/* Image storage dimensions */
unsigned int w; /**< Stored image width */
unsigned int h; /**< Stored image height */
unsigned int bit_depth; /**< Stored image bit-depth */
/* Image display dimensions */
unsigned int d_w; /**< Displayed image width */
unsigned int d_h; /**< Displayed image height */
/* Image intended rendering dimensions */
unsigned int r_w; /**< Intended rendering image width */
unsigned int r_h; /**< Intended rendering image height */
/* Chroma subsampling info */
unsigned int x_chroma_shift; /**< subsampling order, X */
unsigned int y_chroma_shift; /**< subsampling order, Y */
/* Image data pointers. */
#define AOM_PLANE_PACKED 0 /**< To be used for all packed formats */
#define AOM_PLANE_Y 0 /**< Y (Luminance) plane */
#define AOM_PLANE_U 1 /**< U (Chroma) plane */
#define AOM_PLANE_V 2 /**< V (Chroma) plane */
/* planes[AOM_PLANE_V] = NULL and stride[AOM_PLANE_V] = 0 when fmt ==
* AOM_IMG_FMT_NV12 */
unsigned char *planes[3]; /**< pointer to the top left pixel for each plane */
int stride[3]; /**< stride between rows for each plane */
size_t sz; /**< data size */
int bps; /**< bits per sample (for packed formats) */
int temporal_id; /**< Temporal layer Id of image */
int spatial_id; /**< Spatial layer Id of image */
/*!\brief The following member may be set by the application to associate
* data with this image.
*/
void *user_priv;
/* The following members should be treated as private. */
unsigned char *img_data; /**< private */
int img_data_owner; /**< private */
int self_allocd; /**< private */
aom_metadata_array_t
*metadata; /**< Metadata payloads associated with the image. */
void *fb_priv; /**< Frame buffer data associated with the image. */
} aom_image_t; /**< alias for struct aom_image */
/*!\brief Open a descriptor, allocating storage for the underlying image
*
* Returns a descriptor for storing an image of the given format. The
* storage for the image is allocated on the heap.
*
* \param[in] img Pointer to storage for descriptor. If this parameter
* is NULL, the storage for the descriptor will be
* allocated on the heap.
* \param[in] fmt Format for the image
* \param[in] d_w Width of the image
* \param[in] d_h Height of the image
* \param[in] align Alignment, in bytes, of the image buffer and
* each row in the image (stride).
*
* \return Returns a pointer to the initialized image descriptor. If the img
* parameter is non-null, the value of the img parameter will be
* returned.
*/
aom_image_t *aom_img_alloc(aom_image_t *img, aom_img_fmt_t fmt,
unsigned int d_w, unsigned int d_h,
unsigned int align);
/*!\brief Open a descriptor, using existing storage for the underlying image
*
* Returns a descriptor for storing an image of the given format. The
* storage for the image has been allocated elsewhere, and a descriptor is
* desired to "wrap" that storage.
*
* \param[in] img Pointer to storage for descriptor. If this parameter
* is NULL, the storage for the descriptor will be
* allocated on the heap.
* \param[in] fmt Format for the image
* \param[in] d_w Width of the image
* \param[in] d_h Height of the image
* \param[in] align Alignment, in bytes, of each row in the image
* (stride).
* \param[in] img_data Storage to use for the image
*
* \return Returns a pointer to the initialized image descriptor. If the img
* parameter is non-null, the value of the img parameter will be
* returned.
*/
aom_image_t *aom_img_wrap(aom_image_t *img, aom_img_fmt_t fmt, unsigned int d_w,
unsigned int d_h, unsigned int align,
unsigned char *img_data);
/*!\brief Open a descriptor, allocating storage for the underlying image with a
* border
*
* Returns a descriptor for storing an image of the given format and its
* borders. The storage for the image is allocated on the heap.
*
* \param[in] img Pointer to storage for descriptor. If this parameter
* is NULL, the storage for the descriptor will be
* allocated on the heap.
* \param[in] fmt Format for the image
* \param[in] d_w Width of the image
* \param[in] d_h Height of the image
* \param[in] align Alignment, in bytes, of the image buffer and
* each row in the image (stride).
* \param[in] size_align Alignment, in pixels, of the image width and height.
* \param[in] border A border that is padded on four sides of the image.
*
* \return Returns a pointer to the initialized image descriptor. If the img
* parameter is non-null, the value of the img parameter will be
* returned.
*/
aom_image_t *aom_img_alloc_with_border(aom_image_t *img, aom_img_fmt_t fmt,
unsigned int d_w, unsigned int d_h,
unsigned int align,
unsigned int size_align,
unsigned int border);
/*!\brief Set the rectangle identifying the displayed portion of the image
*
* Updates the displayed rectangle (aka viewport) on the image surface to
* match the specified coordinates and size. Specifically, sets img->d_w,
* img->d_h, and elements of the img->planes[] array.
*
* \param[in] img Image descriptor
* \param[in] x leftmost column
* \param[in] y topmost row
* \param[in] w width
* \param[in] h height
* \param[in] border A border that is padded on four sides of the image.
*
* \return 0 if the requested rectangle is valid, nonzero (-1) otherwise.
*/
int aom_img_set_rect(aom_image_t *img, unsigned int x, unsigned int y,
unsigned int w, unsigned int h, unsigned int border);
/*!\brief Flip the image vertically (top for bottom)
*
* Adjusts the image descriptor's pointers and strides to make the image
* be referenced upside-down.
*
* \param[in] img Image descriptor
*/
void aom_img_flip(aom_image_t *img);
/*!\brief Close an image descriptor
*
* Frees all allocated storage associated with an image descriptor.
*
* \param[in] img Image descriptor
*/
void aom_img_free(aom_image_t *img);
/*!\brief Get the width of a plane
*
* Get the width of a plane of an image
*
* \param[in] img Image descriptor
* \param[in] plane Plane index
*/
int aom_img_plane_width(const aom_image_t *img, int plane);
/*!\brief Get the height of a plane
*
* Get the height of a plane of an image
*
* \param[in] img Image descriptor
* \param[in] plane Plane index
*/
int aom_img_plane_height(const aom_image_t *img, int plane);
/*!\brief Add metadata to image.
*
* Adds metadata to aom_image_t.
* Function makes a copy of the provided data parameter.
* Metadata insertion point is controlled by insert_flag.
*
* \param[in] img Image descriptor
* \param[in] type Metadata type
* \param[in] data Metadata contents
* \param[in] sz Metadata contents size
* \param[in] insert_flag Metadata insert flag
*
* \return Returns 0 on success. If img or data is NULL, sz is 0, or memory
* allocation fails, it returns -1.
*/
int aom_img_add_metadata(aom_image_t *img, uint32_t type, const uint8_t *data,
size_t sz, aom_metadata_insert_flags_t insert_flag);
/*!\brief Return a metadata payload stored within the image metadata array.
*
* Gets the metadata (aom_metadata_t) at the indicated index in the image
* metadata array.
*
* \param[in] img Pointer to image descriptor to get metadata from
* \param[in] index Metadata index to get from metadata array
*
* \return Returns a const pointer to the selected metadata, if img and/or index
* is invalid, it returns NULL.
*/
const aom_metadata_t *aom_img_get_metadata(const aom_image_t *img,
size_t index);
/*!\brief Return the number of metadata blocks within the image.
*
* Gets the number of metadata blocks contained within the provided image
* metadata array.
*
* \param[in] img Pointer to image descriptor to get metadata number
* from.
*
* \return Returns the size of the metadata array. If img or metadata is NULL,
* it returns 0.
*/
size_t aom_img_num_metadata(const aom_image_t *img);
/*!\brief Remove metadata from image.
*
* Removes all metadata in image metadata list and sets metadata list pointer
* to NULL.
*
* \param[in] img Image descriptor
*/
void aom_img_remove_metadata(aom_image_t *img);
/*!\brief Allocate memory for aom_metadata struct.
*
* Allocates storage for the metadata payload, sets its type and copies the
* payload data into the aom_metadata struct. A metadata payload buffer of size
* sz is allocated and sz bytes are copied from data into the payload buffer.
*
* \param[in] type Metadata type
* \param[in] data Metadata data pointer
* \param[in] sz Metadata size
* \param[in] insert_flag Metadata insert flag
*
* \return Returns the newly allocated aom_metadata struct. If data is NULL,
* sz is 0, or memory allocation fails, it returns NULL.
*/
aom_metadata_t *aom_img_metadata_alloc(uint32_t type, const uint8_t *data,
size_t sz,
aom_metadata_insert_flags_t insert_flag);
/*!\brief Free metadata struct.
*
* Free metadata struct and its buffer.
*
* \param[in] metadata Metadata struct pointer
*/
void aom_img_metadata_free(aom_metadata_t *metadata);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // AOM_AOM_AOM_IMAGE_H_
@@ -0,0 +1,68 @@
/*
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
*
* This source code is subject to the terms of the BSD 2 Clause License and
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
* was not distributed with this source code in the LICENSE file, you can
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
* Media Patent License 1.0 was not distributed with this source code in the
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
#ifndef AOM_AOM_AOM_INTEGER_H_
#define AOM_AOM_AOM_INTEGER_H_
/* get ptrdiff_t, size_t, wchar_t, NULL */
#include <stddef.h>
#if defined(_MSC_VER)
#define AOM_FORCE_INLINE __forceinline
#define AOM_INLINE __inline
#else
#define AOM_FORCE_INLINE __inline__ __attribute__((always_inline))
#define AOM_INLINE inline
#endif
/* Assume platforms have the C99 standard integer types. */
#if defined(__cplusplus)
#if !defined(__STDC_FORMAT_MACROS)
#define __STDC_FORMAT_MACROS
#endif
#if !defined(__STDC_LIMIT_MACROS)
#define __STDC_LIMIT_MACROS
#endif
#endif // __cplusplus
#include <stdint.h>
#include <inttypes.h>
#if defined(__cplusplus)
extern "C" {
#endif // __cplusplus
// Returns size of uint64_t when encoded using LEB128.
size_t aom_uleb_size_in_bytes(uint64_t value);
// Returns 0 on success, -1 on decode failure.
// On success, 'value' stores the decoded LEB128 value and 'length' stores
// the number of bytes decoded.
int aom_uleb_decode(const uint8_t *buffer, size_t available, uint64_t *value,
size_t *length);
// Encodes LEB128 integer. Returns 0 when successful, and -1 upon failure.
int aom_uleb_encode(uint64_t value, size_t available, uint8_t *coded_value,
size_t *coded_size);
// Encodes LEB128 integer to size specified. Returns 0 when successful, and -1
// upon failure.
// Note: This will write exactly pad_to_size bytes; if the value cannot be
// encoded in this many bytes, then this will fail.
int aom_uleb_encode_fixed_size(uint64_t value, size_t available,
size_t pad_to_size, uint8_t *coded_value,
size_t *coded_size);
#if defined(__cplusplus)
} // extern "C"
#endif // __cplusplus
#endif // AOM_AOM_AOM_INTEGER_H_
File diff suppressed because it is too large Load Diff
+604
View File
@@ -0,0 +1,604 @@
/*
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
*
* This source code is subject to the terms of the BSD 2 Clause License and
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
* was not distributed with this source code in the LICENSE file, you can
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
* Media Patent License 1.0 was not distributed with this source code in the
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
/*!\defgroup aom_decoder AOMedia AOM/AV1 Decoder
* \ingroup aom
*
* @{
*/
/*!\file
* \brief Provides definitions for using AOM or AV1 within the aom Decoder
* interface.
*/
#ifndef AOM_AOM_AOMDX_H_
#define AOM_AOM_AOMDX_H_
#ifdef __cplusplus
extern "C" {
#endif
/* Include controls common to both the encoder and decoder */
#include "aom/aom.h"
/*!\name Algorithm interface for AV1
*
* This interface provides the capability to decode AV1 streams.
* @{
*/
/*!\brief A single instance of the AV1 decoder.
*\deprecated This access mechanism is provided for backwards compatibility;
* prefer aom_codec_av1_dx().
*/
extern aom_codec_iface_t aom_codec_av1_dx_algo;
/*!\brief The interface to the AV1 decoder.
*/
extern aom_codec_iface_t *aom_codec_av1_dx(void);
/*!@} - end algorithm interface member group */
/** Data structure that stores bit accounting for debug
*/
typedef struct Accounting Accounting;
#ifndef AOM_INSPECTION_H_
/** Callback that inspects decoder frame data.
*/
typedef void (*aom_inspect_cb)(void *decoder, void *ctx);
#endif
/*!\brief Structure to hold inspection callback and context.
*
* Defines a structure to hold the inspection callback function and calling
* context.
*/
typedef struct aom_inspect_init {
/*! Inspection callback. */
aom_inspect_cb inspect_cb;
/*! Inspection context. */
void *inspect_ctx;
} aom_inspect_init;
/*!\brief Structure to collect a buffer index when inspecting.
*
* Defines a structure to hold the buffer and return an index
* when calling decode from inspect. This enables us to decode
* non showable sub frames.
*/
typedef struct {
/*! Pointer for new position in compressed buffer after decoding 1 OBU. */
const unsigned char *buf;
/*! Index into reference buffer array to see result of decoding 1 OBU. */
int idx;
/*! Is a show existing frame. */
int show_existing;
} Av1DecodeReturn;
/*!\brief Structure to hold a tile's start address and size in the bitstream.
*
* Defines a structure to hold a tile's start address and size in the bitstream.
*/
typedef struct aom_tile_data {
/*! Tile data size. */
size_t coded_tile_data_size;
/*! Tile's start address. */
const void *coded_tile_data;
/*! Extra size information. */
size_t extra_size;
} aom_tile_data;
/*!\brief Max number of tile columns
*
* This is the limit of number of tile columns allowed within a frame.
*
* Currently same as "MAX_TILE_COLS" in AV1, the maximum that AV1 supports.
*
*/
#define AOM_MAX_TILE_COLS 64
/*!\brief Max number of tile rows
*
* This is the limit of number of tile rows allowed within a frame.
*
* Currently same as "MAX_TILE_ROWS" in AV1, the maximum that AV1 supports.
*
*/
#define AOM_MAX_TILE_ROWS 64
/*!\brief Structure to hold information about tiles in a frame.
*
* Defines a structure to hold a frame's tile information, namely
* number of tile columns, number of tile_rows, and the width and
* height of each tile.
*/
typedef struct aom_tile_info {
/*! Indicates the number of tile columns. */
int tile_columns;
/*! Indicates the number of tile rows. */
int tile_rows;
/*! Indicates the tile widths in units of SB. */
int tile_widths[AOM_MAX_TILE_COLS];
/*! Indicates the tile heights in units of SB. */
int tile_heights[AOM_MAX_TILE_ROWS];
/*! Indicates the number of tile groups present in a frame. */
int num_tile_groups;
} aom_tile_info;
/*!\brief Structure to hold information about still image coding.
*
* Defines a structure to hold a information regarding still picture
* and its header type.
*/
typedef struct aom_still_picture_info {
/*! Video is a single frame still picture */
int is_still_picture;
/*! Use full header for still picture */
int is_reduced_still_picture_hdr;
} aom_still_picture_info;
/*!\brief Structure to hold information about S_FRAME.
*
* Defines a structure to hold a information regarding S_FRAME
* and its position.
*/
typedef struct aom_s_frame_info {
/*! Indicates if current frame is S_FRAME */
int is_s_frame;
/*! Indicates if current S_FRAME is present at ALTREF frame*/
int is_s_frame_at_altref;
} aom_s_frame_info;
/*!\brief Structure to hold information about screen content tools.
*
* Defines a structure to hold information about screen content
* tools, namely: allow_screen_content_tools, allow_intrabc, and
* force_integer_mv.
*/
typedef struct aom_screen_content_tools_info {
/*! Are screen content tools allowed */
int allow_screen_content_tools;
/*! Is intrabc allowed */
int allow_intrabc;
/*! Is integer mv forced */
int force_integer_mv;
} aom_screen_content_tools_info;
/*!\brief Structure to hold the external reference frame pointer.
*
* Define a structure to hold the external reference frame pointer.
*/
typedef struct av1_ext_ref_frame {
/*! Start pointer of external references. */
aom_image_t *img;
/*! Number of available external references. */
int num;
} av1_ext_ref_frame_t;
/*!\enum aom_dec_control_id
* \brief AOM decoder control functions
*
* This set of macros define the control functions available for the AOM
* decoder interface.
* The range for decoder control ID is >= 256.
*
* \sa #aom_codec_control(aom_codec_ctx_t *ctx, int ctrl_id, ...)
*/
enum aom_dec_control_id {
/*!\brief Codec control function to get info on which reference frames were
* updated by the last decode, int* parameter
*/
AOMD_GET_LAST_REF_UPDATES = AOM_DECODER_CTRL_ID_START,
/*!\brief Codec control function to check if the indicated frame is
corrupted, int* parameter
*/
AOMD_GET_FRAME_CORRUPTED,
/*!\brief Codec control function to get info on which reference frames were
* used by the last decode, int* parameter
*/
AOMD_GET_LAST_REF_USED,
/*!\brief Codec control function to get the dimensions that the current
* frame is decoded at, int* parameter
*
* This may be different to the intended display size for the frame as
* specified in the wrapper or frame header (see AV1D_GET_DISPLAY_SIZE).
*/
AV1D_GET_FRAME_SIZE,
/*!\brief Codec control function to get the current frame's intended display
* dimensions (as specified in the wrapper or frame header), int* parameter
*
* This may be different to the decoded dimensions of this frame (see
* AV1D_GET_FRAME_SIZE).
*/
AV1D_GET_DISPLAY_SIZE,
/*!\brief Codec control function to get the bit depth of the stream,
* unsigned int* parameter
*/
AV1D_GET_BIT_DEPTH,
/*!\brief Codec control function to get the image format of the stream,
* aom_img_fmt_t* parameter
*/
AV1D_GET_IMG_FORMAT,
/*!\brief Codec control function to get the size of the tile, unsigned int*
* parameter
*/
AV1D_GET_TILE_SIZE,
/*!\brief Codec control function to get the tile count in a tile list,
* unsigned int* parameter
*/
AV1D_GET_TILE_COUNT,
/*!\brief Codec control function to set the byte alignment of the planes in
* the reference buffers, int parameter
*
* Valid values are power of 2, from 32 to 1024. A value of 0 sets
* legacy alignment. I.e. Y plane is aligned to 32 bytes, U plane directly
* follows Y plane, and V plane directly follows U plane. Default value is 0.
*/
AV1_SET_BYTE_ALIGNMENT,
/*!\brief Codec control function to invert the decoding order to from right to
* left, int parameter
*
* The function is used in a test to confirm the decoding independence of tile
* columns. The function may be used in application where this order
* of decoding is desired. int parameter
*
* TODO(yaowu): Rework the unit test that uses this control, and in a future
* release, this test-only control shall be removed.
*/
AV1_INVERT_TILE_DECODE_ORDER,
/*!\brief Codec control function to set the skip loop filter flag, int
* parameter
*
* Valid values are integers. The decoder will skip the loop filter
* when its value is set to nonzero. If the loop filter is skipped the
* decoder may accumulate decode artifacts. The default value is 0.
*/
AV1_SET_SKIP_LOOP_FILTER,
/*!\brief Codec control function to retrieve a pointer to the Accounting
* struct, takes Accounting** as parameter
*
* If called before a frame has been decoded, this returns AOM_CODEC_ERROR.
* The caller should ensure that AOM_CODEC_OK is returned before attempting
* to dereference the Accounting pointer.
*
* \attention When configured with -DCONFIG_ACCOUNTING=0, the default, this
* returns AOM_CODEC_INCAPABLE.
*/
AV1_GET_ACCOUNTING,
/*!\brief Codec control function to get last decoded frame quantizer,
* int* parameter
*
* Returned value uses internal quantizer scale defined by the codec.
*/
AOMD_GET_LAST_QUANTIZER,
/*!\brief Codec control function to set the range of tile decoding, int
* parameter
*
* A value that is greater and equal to zero indicates only the specific
* row/column is decoded. A value that is -1 indicates the whole row/column
* is decoded. A special case is both values are -1 that means the whole
* frame is decoded.
*/
AV1_SET_DECODE_TILE_ROW,
AV1_SET_DECODE_TILE_COL,
/*!\brief Codec control function to set the tile coding mode, unsigned int
* parameter
*
* - 0 = tiles are coded in normal tile mode
* - 1 = tiles are coded in large-scale tile mode
*/
AV1_SET_TILE_MODE,
/*!\brief Codec control function to get the frame header information of an
* encoded frame, aom_tile_data* parameter
*/
AV1D_GET_FRAME_HEADER_INFO,
/*!\brief Codec control function to get the start address and size of a
* tile in the coded bitstream, aom_tile_data* parameter.
*/
AV1D_GET_TILE_DATA,
/*!\brief Codec control function to set the external references' pointers in
* the decoder, av1_ext_ref_frame_t* parameter.
*
* This is used while decoding the tile list OBU in large-scale tile coding
* mode.
*/
AV1D_SET_EXT_REF_PTR,
/*!\brief Codec control function to enable the ext-tile software debug and
* testing code in the decoder, unsigned int parameter
*/
AV1D_EXT_TILE_DEBUG,
/*!\brief Codec control function to enable the row based multi-threading of
* decoding, unsigned int parameter
*
* - 0 = disabled
* - 1 = enabled (default)
*/
AV1D_SET_ROW_MT,
/*!\brief Codec control function to indicate whether bitstream is in
* Annex-B format, unsigned int parameter
*/
AV1D_SET_IS_ANNEXB,
/*!\brief Codec control function to indicate which operating point to use,
* int parameter
*
* A scalable stream may define multiple operating points, each of which
* defines a set of temporal and spatial layers to be processed. The
* operating point index may take a value between 0 and
* operating_points_cnt_minus_1 (which is at most 31).
*/
AV1D_SET_OPERATING_POINT,
/*!\brief Codec control function to indicate whether to output one frame per
* temporal unit (the default), or one frame per spatial layer, int parameter
*
* In a scalable stream, each temporal unit corresponds to a single "frame"
* of video, and within a temporal unit there may be multiple spatial layers
* with different versions of that frame.
* For video playback, only the highest-quality version (within the
* selected operating point) is needed, but for some use cases it is useful
* to have access to multiple versions of a frame when they are available.
*/
AV1D_SET_OUTPUT_ALL_LAYERS,
/*!\brief Codec control function to set an aom_inspect_cb callback that is
* invoked each time a frame is decoded, aom_inspect_init* parameter
*
* \attention When configured with -DCONFIG_INSPECTION=0, the default, this
* returns AOM_CODEC_INCAPABLE.
*/
AV1_SET_INSPECTION_CALLBACK,
/*!\brief Codec control function to set the skip film grain flag, int
* parameter
*
* Valid values are integers. The decoder will skip the film grain when its
* value is set to nonzero. The default value is 0.
*/
AV1D_SET_SKIP_FILM_GRAIN,
/*!\brief Codec control function to check the presence of forward key frames,
* int* parameter
*/
AOMD_GET_FWD_KF_PRESENT,
/*!\brief Codec control function to get the frame flags of the previous frame
* decoded, int* parameter
*
* This will return a flag of type aom_codec_frame_flags_t.
*/
AOMD_GET_FRAME_FLAGS,
/*!\brief Codec control function to check the presence of altref frames, int*
* parameter
*/
AOMD_GET_ALTREF_PRESENT,
/*!\brief Codec control function to get tile information of the previous frame
* decoded, aom_tile_info* parameter
*
* This will return a struct of type aom_tile_info.
*/
AOMD_GET_TILE_INFO,
/*!\brief Codec control function to get screen content tools information,
* aom_screen_content_tools_info* parameter
*
* It returns a struct of type aom_screen_content_tools_info, which contains
* the header flags allow_screen_content_tools, allow_intrabc, and
* force_integer_mv.
*/
AOMD_GET_SCREEN_CONTENT_TOOLS_INFO,
/*!\brief Codec control function to get the still picture coding information,
* aom_still_picture_info* parameter
*/
AOMD_GET_STILL_PICTURE,
/*!\brief Codec control function to get superblock size,
* aom_superblock_size_t* parameter
*
* It returns an enum, indicating the superblock size read from the sequence
* header(0 for BLOCK_64X64 and 1 for BLOCK_128X128)
*/
AOMD_GET_SB_SIZE,
/*!\brief Codec control function to check if the previous frame
* decoded has show existing frame flag set, int* parameter
*/
AOMD_GET_SHOW_EXISTING_FRAME_FLAG,
/*!\brief Codec control function to get the S_FRAME coding information,
* aom_s_frame_info* parameter
*/
AOMD_GET_S_FRAME_INFO,
/*!\brief Codec control function to get the show frame flag, int* parameter
*/
AOMD_GET_SHOW_FRAME_FLAG,
/*!\brief Codec control function to get the base q index of a frame, int*
* parameter
*/
AOMD_GET_BASE_Q_IDX,
/*!\brief Codec control function to get the order hint of a frame, unsigned
* int* parameter
*/
AOMD_GET_ORDER_HINT,
/*!\brief Codec control function to get the info of a 4x4 block.
* Parameters: int mi_row, int mi_col, and MB_MODE_INFO*.
*
* \note This only returns a shallow copy, so all pointer members should not
* be used.
*/
AV1D_GET_MI_INFO,
};
/*!\cond */
/*!\brief AOM decoder control function parameter type
*
* Defines the data types that AOMD control functions take.
*
* \note Additional common controls are defined in aom.h.
*
* \note For each control ID "X", a macro-define of
* AOM_CTRL_X is provided. It is used at compile time to determine
* if the control ID is supported by the libaom library available,
* when the libaom version cannot be controlled.
*/
AOM_CTRL_USE_TYPE(AOMD_GET_LAST_REF_UPDATES, int *)
#define AOM_CTRL_AOMD_GET_LAST_REF_UPDATES
AOM_CTRL_USE_TYPE(AOMD_GET_FRAME_CORRUPTED, int *)
#define AOM_CTRL_AOMD_GET_FRAME_CORRUPTED
AOM_CTRL_USE_TYPE(AOMD_GET_LAST_REF_USED, int *)
#define AOM_CTRL_AOMD_GET_LAST_REF_USED
AOM_CTRL_USE_TYPE(AV1D_GET_FRAME_SIZE, int *)
#define AOM_CTRL_AV1D_GET_FRAME_SIZE
AOM_CTRL_USE_TYPE(AV1D_GET_DISPLAY_SIZE, int *)
#define AOM_CTRL_AV1D_GET_DISPLAY_SIZE
AOM_CTRL_USE_TYPE(AV1D_GET_BIT_DEPTH, unsigned int *)
#define AOM_CTRL_AV1D_GET_BIT_DEPTH
AOM_CTRL_USE_TYPE(AV1D_GET_IMG_FORMAT, aom_img_fmt_t *)
#define AOM_CTRL_AV1D_GET_IMG_FORMAT
AOM_CTRL_USE_TYPE(AV1D_GET_TILE_SIZE, unsigned int *)
#define AOM_CTRL_AV1D_GET_TILE_SIZE
AOM_CTRL_USE_TYPE(AV1D_GET_TILE_COUNT, unsigned int *)
#define AOM_CTRL_AV1D_GET_TILE_COUNT
AOM_CTRL_USE_TYPE(AV1_INVERT_TILE_DECODE_ORDER, int)
#define AOM_CTRL_AV1_INVERT_TILE_DECODE_ORDER
AOM_CTRL_USE_TYPE(AV1_SET_SKIP_LOOP_FILTER, int)
#define AOM_CTRL_AV1_SET_SKIP_LOOP_FILTER
AOM_CTRL_USE_TYPE(AV1_GET_ACCOUNTING, Accounting **)
#define AOM_CTRL_AV1_GET_ACCOUNTING
AOM_CTRL_USE_TYPE(AOMD_GET_LAST_QUANTIZER, int *)
#define AOM_CTRL_AOMD_GET_LAST_QUANTIZER
AOM_CTRL_USE_TYPE(AV1_SET_DECODE_TILE_ROW, int)
#define AOM_CTRL_AV1_SET_DECODE_TILE_ROW
AOM_CTRL_USE_TYPE(AV1_SET_DECODE_TILE_COL, int)
#define AOM_CTRL_AV1_SET_DECODE_TILE_COL
AOM_CTRL_USE_TYPE(AV1_SET_TILE_MODE, unsigned int)
#define AOM_CTRL_AV1_SET_TILE_MODE
AOM_CTRL_USE_TYPE(AV1D_GET_FRAME_HEADER_INFO, aom_tile_data *)
#define AOM_CTRL_AV1D_GET_FRAME_HEADER_INFO
AOM_CTRL_USE_TYPE(AV1D_GET_TILE_DATA, aom_tile_data *)
#define AOM_CTRL_AV1D_GET_TILE_DATA
AOM_CTRL_USE_TYPE(AV1D_SET_EXT_REF_PTR, av1_ext_ref_frame_t *)
#define AOM_CTRL_AV1D_SET_EXT_REF_PTR
AOM_CTRL_USE_TYPE(AV1D_EXT_TILE_DEBUG, unsigned int)
#define AOM_CTRL_AV1D_EXT_TILE_DEBUG
AOM_CTRL_USE_TYPE(AV1D_SET_ROW_MT, unsigned int)
#define AOM_CTRL_AV1D_SET_ROW_MT
AOM_CTRL_USE_TYPE(AV1D_SET_IS_ANNEXB, unsigned int)
#define AOM_CTRL_AV1D_SET_IS_ANNEXB
AOM_CTRL_USE_TYPE(AV1D_SET_OPERATING_POINT, int)
#define AOM_CTRL_AV1D_SET_OPERATING_POINT
AOM_CTRL_USE_TYPE(AV1D_SET_OUTPUT_ALL_LAYERS, int)
#define AOM_CTRL_AV1D_SET_OUTPUT_ALL_LAYERS
AOM_CTRL_USE_TYPE(AV1_SET_INSPECTION_CALLBACK, aom_inspect_init *)
#define AOM_CTRL_AV1_SET_INSPECTION_CALLBACK
AOM_CTRL_USE_TYPE(AV1D_SET_SKIP_FILM_GRAIN, int)
#define AOM_CTRL_AV1D_SET_SKIP_FILM_GRAIN
AOM_CTRL_USE_TYPE(AOMD_GET_FWD_KF_PRESENT, int *)
#define AOM_CTRL_AOMD_GET_FWD_KF_PRESENT
AOM_CTRL_USE_TYPE(AOMD_GET_FRAME_FLAGS, int *)
#define AOM_CTRL_AOMD_GET_FRAME_FLAGS
AOM_CTRL_USE_TYPE(AOMD_GET_ALTREF_PRESENT, int *)
#define AOM_CTRL_AOMD_GET_ALTREF_PRESENT
AOM_CTRL_USE_TYPE(AOMD_GET_TILE_INFO, aom_tile_info *)
#define AOM_CTRL_AOMD_GET_TILE_INFO
AOM_CTRL_USE_TYPE(AOMD_GET_SCREEN_CONTENT_TOOLS_INFO,
aom_screen_content_tools_info *)
#define AOM_CTRL_AOMD_GET_SCREEN_CONTENT_TOOLS_INFO
AOM_CTRL_USE_TYPE(AOMD_GET_STILL_PICTURE, aom_still_picture_info *)
#define AOM_CTRL_AOMD_GET_STILL_PICTURE
AOM_CTRL_USE_TYPE(AOMD_GET_SB_SIZE, aom_superblock_size_t *)
#define AOMD_CTRL_AOMD_GET_SB_SIZE
AOM_CTRL_USE_TYPE(AOMD_GET_SHOW_EXISTING_FRAME_FLAG, int *)
#define AOMD_CTRL_AOMD_GET_SHOW_EXISTING_FRAME_FLAG
AOM_CTRL_USE_TYPE(AOMD_GET_S_FRAME_INFO, aom_s_frame_info *)
#define AOMD_CTRL_AOMD_GET_S_FRAME_INFO
AOM_CTRL_USE_TYPE(AOMD_GET_SHOW_FRAME_FLAG, int *)
#define AOM_CTRL_AOMD_GET_SHOW_FRAME_FLAG
AOM_CTRL_USE_TYPE(AOMD_GET_BASE_Q_IDX, int *)
#define AOM_CTRL_AOMD_GET_BASE_Q_IDX
AOM_CTRL_USE_TYPE(AOMD_GET_ORDER_HINT, unsigned int *)
#define AOM_CTRL_AOMD_GET_ORDER_HINT
// The AOM_CTRL_USE_TYPE macro can't be used with AV1D_GET_MI_INFO because
// AV1D_GET_MI_INFO takes more than one parameter.
#define AOM_CTRL_AV1D_GET_MI_INFO
/*!\endcond */
/*! @} - end defgroup aom_decoder */
#ifdef __cplusplus
} // extern "C"
#endif
#endif // AOM_AOM_AOMDX_H_
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,723 @@
/*-
* Copyright (c) 2003-2008 Tim Kientzle
* Copyright (c) 2016 Martin Matuska
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD: head/lib/libarchive/archive_entry.h 201096 2009-12-28 02:41:27Z kientzle $
*/
#ifndef ARCHIVE_ENTRY_H_INCLUDED
#define ARCHIVE_ENTRY_H_INCLUDED
/* Note: Compiler will complain if this does not match archive.h! */
#define ARCHIVE_VERSION_NUMBER 3007002
/*
* Note: archive_entry.h is for use outside of libarchive; the
* configuration headers (config.h, archive_platform.h, etc.) are
* purely internal. Do NOT use HAVE_XXX configuration macros to
* control the behavior of this header! If you must conditionalize,
* use predefined compiler and/or platform macros.
*/
#include <sys/types.h>
#include <stddef.h> /* for wchar_t */
#include <stdint.h>
#include <time.h>
#if defined(_WIN32) && !defined(__CYGWIN__)
#include <windows.h>
#endif
/* Get a suitable 64-bit integer type. */
#if !defined(__LA_INT64_T_DEFINED)
# if ARCHIVE_VERSION_NUMBER < 4000000
#define __LA_INT64_T la_int64_t
# endif
#define __LA_INT64_T_DEFINED
# if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__WATCOMC__)
typedef __int64 la_int64_t;
# else
#include <unistd.h>
# if defined(_SCO_DS) || defined(__osf__)
typedef long long la_int64_t;
# else
typedef int64_t la_int64_t;
# endif
# endif
#endif
/* The la_ssize_t should match the type used in 'struct stat' */
#if !defined(__LA_SSIZE_T_DEFINED)
/* Older code relied on the __LA_SSIZE_T macro; after 4.0 we'll switch to the typedef exclusively. */
# if ARCHIVE_VERSION_NUMBER < 4000000
#define __LA_SSIZE_T la_ssize_t
# endif
#define __LA_SSIZE_T_DEFINED
# if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__WATCOMC__)
# if defined(_SSIZE_T_DEFINED) || defined(_SSIZE_T_)
typedef ssize_t la_ssize_t;
# elif defined(_WIN64)
typedef __int64 la_ssize_t;
# else
typedef long la_ssize_t;
# endif
# else
# include <unistd.h> /* ssize_t */
typedef ssize_t la_ssize_t;
# endif
#endif
/* Get a suitable definition for mode_t */
#if ARCHIVE_VERSION_NUMBER >= 3999000
/* Switch to plain 'int' for libarchive 4.0. It's less broken than 'mode_t' */
# define __LA_MODE_T int
#elif defined(_WIN32) && !defined(__CYGWIN__) && !defined(__BORLANDC__) && !defined(__WATCOMC__)
# define __LA_MODE_T unsigned short
#else
# define __LA_MODE_T mode_t
#endif
/* Large file support for Android */
#if defined(__LIBARCHIVE_BUILD) && defined(__ANDROID__)
#include "android_lf.h"
#endif
/*
* On Windows, define LIBARCHIVE_STATIC if you're building or using a
* .lib. The default here assumes you're building a DLL. Only
* libarchive source should ever define __LIBARCHIVE_BUILD.
*/
#if ((defined __WIN32__) || (defined _WIN32) || defined(__CYGWIN__)) && (!defined LIBARCHIVE_STATIC)
# ifdef __LIBARCHIVE_BUILD
# ifdef __GNUC__
# define __LA_DECL __attribute__((dllexport)) extern
# else
# define __LA_DECL __declspec(dllexport)
# endif
# else
# ifdef __GNUC__
# define __LA_DECL
# else
# define __LA_DECL __declspec(dllimport)
# endif
# endif
#elif defined __LIBARCHIVE_ENABLE_VISIBILITY
# define __LA_DECL __attribute__((visibility("default")))
#else
/* Static libraries on all platforms and shared libraries on non-Windows. */
# define __LA_DECL
#endif
#if defined(__GNUC__) && __GNUC__ >= 3 && __GNUC_MINOR__ >= 1
# define __LA_DEPRECATED __attribute__((deprecated))
#else
# define __LA_DEPRECATED
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*
* Description of an archive entry.
*
* You can think of this as "struct stat" with some text fields added in.
*
* TODO: Add "comment", "charset", and possibly other entries that are
* supported by "pax interchange" format. However, GNU, ustar, cpio,
* and other variants don't support these features, so they're not an
* excruciatingly high priority right now.
*
* TODO: "pax interchange" format allows essentially arbitrary
* key/value attributes to be attached to any entry. Supporting
* such extensions may make this library useful for special
* applications (e.g., a package manager could attach special
* package-management attributes to each entry).
*/
struct archive;
struct archive_entry;
/*
* File-type constants. These are returned from archive_entry_filetype()
* and passed to archive_entry_set_filetype().
*
* These values match S_XXX defines on every platform I've checked,
* including Windows, AIX, Linux, Solaris, and BSD. They're
* (re)defined here because platforms generally don't define the ones
* they don't support. For example, Windows doesn't define S_IFLNK or
* S_IFBLK. Instead of having a mass of conditional logic and system
* checks to define any S_XXX values that aren't supported locally,
* I've just defined a new set of such constants so that
* libarchive-based applications can manipulate and identify archive
* entries properly even if the hosting platform can't store them on
* disk.
*
* These values are also used directly within some portable formats,
* such as cpio. If you find a platform that varies from these, the
* correct solution is to leave these alone and translate from these
* portable values to platform-native values when entries are read from
* or written to disk.
*/
/*
* In libarchive 4.0, we can drop the casts here.
* They're needed to work around Borland C's broken mode_t.
*/
#define AE_IFMT ((__LA_MODE_T)0170000)
#define AE_IFREG ((__LA_MODE_T)0100000)
#define AE_IFLNK ((__LA_MODE_T)0120000)
#define AE_IFSOCK ((__LA_MODE_T)0140000)
#define AE_IFCHR ((__LA_MODE_T)0020000)
#define AE_IFBLK ((__LA_MODE_T)0060000)
#define AE_IFDIR ((__LA_MODE_T)0040000)
#define AE_IFIFO ((__LA_MODE_T)0010000)
/*
* Symlink types
*/
#define AE_SYMLINK_TYPE_UNDEFINED 0
#define AE_SYMLINK_TYPE_FILE 1
#define AE_SYMLINK_TYPE_DIRECTORY 2
/*
* Basic object manipulation
*/
__LA_DECL struct archive_entry *archive_entry_clear(struct archive_entry *);
/* The 'clone' function does a deep copy; all of the strings are copied too. */
__LA_DECL struct archive_entry *archive_entry_clone(struct archive_entry *);
__LA_DECL void archive_entry_free(struct archive_entry *);
__LA_DECL struct archive_entry *archive_entry_new(void);
/*
* This form of archive_entry_new2() will pull character-set
* conversion information from the specified archive handle. The
* older archive_entry_new(void) form is equivalent to calling
* archive_entry_new2(NULL) and will result in the use of an internal
* default character-set conversion.
*/
__LA_DECL struct archive_entry *archive_entry_new2(struct archive *);
/*
* Retrieve fields from an archive_entry.
*
* There are a number of implicit conversions among these fields. For
* example, if a regular string field is set and you read the _w wide
* character field, the entry will implicitly convert narrow-to-wide
* using the current locale. Similarly, dev values are automatically
* updated when you write devmajor or devminor and vice versa.
*
* In addition, fields can be "set" or "unset." Unset string fields
* return NULL, non-string fields have _is_set() functions to test
* whether they've been set. You can "unset" a string field by
* assigning NULL; non-string fields have _unset() functions to
* unset them.
*
* Note: There is one ambiguity in the above; string fields will
* also return NULL when implicit character set conversions fail.
* This is usually what you want.
*/
__LA_DECL time_t archive_entry_atime(struct archive_entry *);
__LA_DECL long archive_entry_atime_nsec(struct archive_entry *);
__LA_DECL int archive_entry_atime_is_set(struct archive_entry *);
__LA_DECL time_t archive_entry_birthtime(struct archive_entry *);
__LA_DECL long archive_entry_birthtime_nsec(struct archive_entry *);
__LA_DECL int archive_entry_birthtime_is_set(struct archive_entry *);
__LA_DECL time_t archive_entry_ctime(struct archive_entry *);
__LA_DECL long archive_entry_ctime_nsec(struct archive_entry *);
__LA_DECL int archive_entry_ctime_is_set(struct archive_entry *);
__LA_DECL dev_t archive_entry_dev(struct archive_entry *);
__LA_DECL int archive_entry_dev_is_set(struct archive_entry *);
__LA_DECL dev_t archive_entry_devmajor(struct archive_entry *);
__LA_DECL dev_t archive_entry_devminor(struct archive_entry *);
__LA_DECL __LA_MODE_T archive_entry_filetype(struct archive_entry *);
__LA_DECL void archive_entry_fflags(struct archive_entry *,
unsigned long * /* set */,
unsigned long * /* clear */);
__LA_DECL const char *archive_entry_fflags_text(struct archive_entry *);
__LA_DECL la_int64_t archive_entry_gid(struct archive_entry *);
__LA_DECL const char *archive_entry_gname(struct archive_entry *);
__LA_DECL const char *archive_entry_gname_utf8(struct archive_entry *);
__LA_DECL const wchar_t *archive_entry_gname_w(struct archive_entry *);
__LA_DECL const char *archive_entry_hardlink(struct archive_entry *);
__LA_DECL const char *archive_entry_hardlink_utf8(struct archive_entry *);
__LA_DECL const wchar_t *archive_entry_hardlink_w(struct archive_entry *);
__LA_DECL la_int64_t archive_entry_ino(struct archive_entry *);
__LA_DECL la_int64_t archive_entry_ino64(struct archive_entry *);
__LA_DECL int archive_entry_ino_is_set(struct archive_entry *);
__LA_DECL __LA_MODE_T archive_entry_mode(struct archive_entry *);
__LA_DECL time_t archive_entry_mtime(struct archive_entry *);
__LA_DECL long archive_entry_mtime_nsec(struct archive_entry *);
__LA_DECL int archive_entry_mtime_is_set(struct archive_entry *);
__LA_DECL unsigned int archive_entry_nlink(struct archive_entry *);
__LA_DECL const char *archive_entry_pathname(struct archive_entry *);
__LA_DECL const char *archive_entry_pathname_utf8(struct archive_entry *);
__LA_DECL const wchar_t *archive_entry_pathname_w(struct archive_entry *);
__LA_DECL __LA_MODE_T archive_entry_perm(struct archive_entry *);
__LA_DECL dev_t archive_entry_rdev(struct archive_entry *);
__LA_DECL dev_t archive_entry_rdevmajor(struct archive_entry *);
__LA_DECL dev_t archive_entry_rdevminor(struct archive_entry *);
__LA_DECL const char *archive_entry_sourcepath(struct archive_entry *);
__LA_DECL const wchar_t *archive_entry_sourcepath_w(struct archive_entry *);
__LA_DECL la_int64_t archive_entry_size(struct archive_entry *);
__LA_DECL int archive_entry_size_is_set(struct archive_entry *);
__LA_DECL const char *archive_entry_strmode(struct archive_entry *);
__LA_DECL const char *archive_entry_symlink(struct archive_entry *);
__LA_DECL const char *archive_entry_symlink_utf8(struct archive_entry *);
__LA_DECL int archive_entry_symlink_type(struct archive_entry *);
__LA_DECL const wchar_t *archive_entry_symlink_w(struct archive_entry *);
__LA_DECL la_int64_t archive_entry_uid(struct archive_entry *);
__LA_DECL const char *archive_entry_uname(struct archive_entry *);
__LA_DECL const char *archive_entry_uname_utf8(struct archive_entry *);
__LA_DECL const wchar_t *archive_entry_uname_w(struct archive_entry *);
__LA_DECL int archive_entry_is_data_encrypted(struct archive_entry *);
__LA_DECL int archive_entry_is_metadata_encrypted(struct archive_entry *);
__LA_DECL int archive_entry_is_encrypted(struct archive_entry *);
/*
* Set fields in an archive_entry.
*
* Note: Before libarchive 2.4, there were 'set' and 'copy' versions
* of the string setters. 'copy' copied the actual string, 'set' just
* stored the pointer. In libarchive 2.4 and later, strings are
* always copied.
*/
__LA_DECL void archive_entry_set_atime(struct archive_entry *, time_t, long);
__LA_DECL void archive_entry_unset_atime(struct archive_entry *);
#if defined(_WIN32) && !defined(__CYGWIN__)
__LA_DECL void archive_entry_copy_bhfi(struct archive_entry *, BY_HANDLE_FILE_INFORMATION *);
#endif
__LA_DECL void archive_entry_set_birthtime(struct archive_entry *, time_t, long);
__LA_DECL void archive_entry_unset_birthtime(struct archive_entry *);
__LA_DECL void archive_entry_set_ctime(struct archive_entry *, time_t, long);
__LA_DECL void archive_entry_unset_ctime(struct archive_entry *);
__LA_DECL void archive_entry_set_dev(struct archive_entry *, dev_t);
__LA_DECL void archive_entry_set_devmajor(struct archive_entry *, dev_t);
__LA_DECL void archive_entry_set_devminor(struct archive_entry *, dev_t);
__LA_DECL void archive_entry_set_filetype(struct archive_entry *, unsigned int);
__LA_DECL void archive_entry_set_fflags(struct archive_entry *,
unsigned long /* set */, unsigned long /* clear */);
/* Returns pointer to start of first invalid token, or NULL if none. */
/* Note that all recognized tokens are processed, regardless. */
__LA_DECL const char *archive_entry_copy_fflags_text(struct archive_entry *,
const char *);
__LA_DECL const wchar_t *archive_entry_copy_fflags_text_w(struct archive_entry *,
const wchar_t *);
__LA_DECL void archive_entry_set_gid(struct archive_entry *, la_int64_t);
__LA_DECL void archive_entry_set_gname(struct archive_entry *, const char *);
__LA_DECL void archive_entry_set_gname_utf8(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_gname(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_gname_w(struct archive_entry *, const wchar_t *);
__LA_DECL int archive_entry_update_gname_utf8(struct archive_entry *, const char *);
__LA_DECL void archive_entry_set_hardlink(struct archive_entry *, const char *);
__LA_DECL void archive_entry_set_hardlink_utf8(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_hardlink(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_hardlink_w(struct archive_entry *, const wchar_t *);
__LA_DECL int archive_entry_update_hardlink_utf8(struct archive_entry *, const char *);
__LA_DECL void archive_entry_set_ino(struct archive_entry *, la_int64_t);
__LA_DECL void archive_entry_set_ino64(struct archive_entry *, la_int64_t);
__LA_DECL void archive_entry_set_link(struct archive_entry *, const char *);
__LA_DECL void archive_entry_set_link_utf8(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_link(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_link_w(struct archive_entry *, const wchar_t *);
__LA_DECL int archive_entry_update_link_utf8(struct archive_entry *, const char *);
__LA_DECL void archive_entry_set_mode(struct archive_entry *, __LA_MODE_T);
__LA_DECL void archive_entry_set_mtime(struct archive_entry *, time_t, long);
__LA_DECL void archive_entry_unset_mtime(struct archive_entry *);
__LA_DECL void archive_entry_set_nlink(struct archive_entry *, unsigned int);
__LA_DECL void archive_entry_set_pathname(struct archive_entry *, const char *);
__LA_DECL void archive_entry_set_pathname_utf8(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_pathname(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_pathname_w(struct archive_entry *, const wchar_t *);
__LA_DECL int archive_entry_update_pathname_utf8(struct archive_entry *, const char *);
__LA_DECL void archive_entry_set_perm(struct archive_entry *, __LA_MODE_T);
__LA_DECL void archive_entry_set_rdev(struct archive_entry *, dev_t);
__LA_DECL void archive_entry_set_rdevmajor(struct archive_entry *, dev_t);
__LA_DECL void archive_entry_set_rdevminor(struct archive_entry *, dev_t);
__LA_DECL void archive_entry_set_size(struct archive_entry *, la_int64_t);
__LA_DECL void archive_entry_unset_size(struct archive_entry *);
__LA_DECL void archive_entry_copy_sourcepath(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_sourcepath_w(struct archive_entry *, const wchar_t *);
__LA_DECL void archive_entry_set_symlink(struct archive_entry *, const char *);
__LA_DECL void archive_entry_set_symlink_type(struct archive_entry *, int);
__LA_DECL void archive_entry_set_symlink_utf8(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_symlink(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_symlink_w(struct archive_entry *, const wchar_t *);
__LA_DECL int archive_entry_update_symlink_utf8(struct archive_entry *, const char *);
__LA_DECL void archive_entry_set_uid(struct archive_entry *, la_int64_t);
__LA_DECL void archive_entry_set_uname(struct archive_entry *, const char *);
__LA_DECL void archive_entry_set_uname_utf8(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_uname(struct archive_entry *, const char *);
__LA_DECL void archive_entry_copy_uname_w(struct archive_entry *, const wchar_t *);
__LA_DECL int archive_entry_update_uname_utf8(struct archive_entry *, const char *);
__LA_DECL void archive_entry_set_is_data_encrypted(struct archive_entry *, char is_encrypted);
__LA_DECL void archive_entry_set_is_metadata_encrypted(struct archive_entry *, char is_encrypted);
/*
* Routines to bulk copy fields to/from a platform-native "struct
* stat." Libarchive used to just store a struct stat inside of each
* archive_entry object, but this created issues when trying to
* manipulate archives on systems different than the ones they were
* created on.
*
* TODO: On Linux and other LFS systems, provide both stat32 and
* stat64 versions of these functions and all of the macro glue so
* that archive_entry_stat is magically defined to
* archive_entry_stat32 or archive_entry_stat64 as appropriate.
*/
__LA_DECL const struct stat *archive_entry_stat(struct archive_entry *);
__LA_DECL void archive_entry_copy_stat(struct archive_entry *, const struct stat *);
/*
* Storage for Mac OS-specific AppleDouble metadata information.
* Apple-format tar files store a separate binary blob containing
* encoded metadata with ACL, extended attributes, etc.
* This provides a place to store that blob.
*/
__LA_DECL const void * archive_entry_mac_metadata(struct archive_entry *, size_t *);
__LA_DECL void archive_entry_copy_mac_metadata(struct archive_entry *, const void *, size_t);
/*
* Digest routine. This is used to query the raw hex digest for the
* given entry. The type of digest is provided as an argument.
*/
#define ARCHIVE_ENTRY_DIGEST_MD5 0x00000001
#define ARCHIVE_ENTRY_DIGEST_RMD160 0x00000002
#define ARCHIVE_ENTRY_DIGEST_SHA1 0x00000003
#define ARCHIVE_ENTRY_DIGEST_SHA256 0x00000004
#define ARCHIVE_ENTRY_DIGEST_SHA384 0x00000005
#define ARCHIVE_ENTRY_DIGEST_SHA512 0x00000006
__LA_DECL const unsigned char * archive_entry_digest(struct archive_entry *, int /* type */);
/*
* ACL routines. This used to simply store and return text-format ACL
* strings, but that proved insufficient for a number of reasons:
* = clients need control over uname/uid and gname/gid mappings
* = there are many different ACL text formats
* = would like to be able to read/convert archives containing ACLs
* on platforms that lack ACL libraries
*
* This last point, in particular, forces me to implement a reasonably
* complete set of ACL support routines.
*/
/*
* Permission bits.
*/
#define ARCHIVE_ENTRY_ACL_EXECUTE 0x00000001
#define ARCHIVE_ENTRY_ACL_WRITE 0x00000002
#define ARCHIVE_ENTRY_ACL_READ 0x00000004
#define ARCHIVE_ENTRY_ACL_READ_DATA 0x00000008
#define ARCHIVE_ENTRY_ACL_LIST_DIRECTORY 0x00000008
#define ARCHIVE_ENTRY_ACL_WRITE_DATA 0x00000010
#define ARCHIVE_ENTRY_ACL_ADD_FILE 0x00000010
#define ARCHIVE_ENTRY_ACL_APPEND_DATA 0x00000020
#define ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY 0x00000020
#define ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS 0x00000040
#define ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS 0x00000080
#define ARCHIVE_ENTRY_ACL_DELETE_CHILD 0x00000100
#define ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES 0x00000200
#define ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES 0x00000400
#define ARCHIVE_ENTRY_ACL_DELETE 0x00000800
#define ARCHIVE_ENTRY_ACL_READ_ACL 0x00001000
#define ARCHIVE_ENTRY_ACL_WRITE_ACL 0x00002000
#define ARCHIVE_ENTRY_ACL_WRITE_OWNER 0x00004000
#define ARCHIVE_ENTRY_ACL_SYNCHRONIZE 0x00008000
#define ARCHIVE_ENTRY_ACL_PERMS_POSIX1E \
(ARCHIVE_ENTRY_ACL_EXECUTE \
| ARCHIVE_ENTRY_ACL_WRITE \
| ARCHIVE_ENTRY_ACL_READ)
#define ARCHIVE_ENTRY_ACL_PERMS_NFS4 \
(ARCHIVE_ENTRY_ACL_EXECUTE \
| ARCHIVE_ENTRY_ACL_READ_DATA \
| ARCHIVE_ENTRY_ACL_LIST_DIRECTORY \
| ARCHIVE_ENTRY_ACL_WRITE_DATA \
| ARCHIVE_ENTRY_ACL_ADD_FILE \
| ARCHIVE_ENTRY_ACL_APPEND_DATA \
| ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY \
| ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS \
| ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS \
| ARCHIVE_ENTRY_ACL_DELETE_CHILD \
| ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES \
| ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES \
| ARCHIVE_ENTRY_ACL_DELETE \
| ARCHIVE_ENTRY_ACL_READ_ACL \
| ARCHIVE_ENTRY_ACL_WRITE_ACL \
| ARCHIVE_ENTRY_ACL_WRITE_OWNER \
| ARCHIVE_ENTRY_ACL_SYNCHRONIZE)
/*
* Inheritance values (NFS4 ACLs only); included in permset.
*/
#define ARCHIVE_ENTRY_ACL_ENTRY_INHERITED 0x01000000
#define ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT 0x02000000
#define ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT 0x04000000
#define ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT 0x08000000
#define ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY 0x10000000
#define ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS 0x20000000
#define ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS 0x40000000
#define ARCHIVE_ENTRY_ACL_INHERITANCE_NFS4 \
(ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT \
| ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT \
| ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT \
| ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY \
| ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS \
| ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS \
| ARCHIVE_ENTRY_ACL_ENTRY_INHERITED)
/* We need to be able to specify combinations of these. */
#define ARCHIVE_ENTRY_ACL_TYPE_ACCESS 0x00000100 /* POSIX.1e only */
#define ARCHIVE_ENTRY_ACL_TYPE_DEFAULT 0x00000200 /* POSIX.1e only */
#define ARCHIVE_ENTRY_ACL_TYPE_ALLOW 0x00000400 /* NFS4 only */
#define ARCHIVE_ENTRY_ACL_TYPE_DENY 0x00000800 /* NFS4 only */
#define ARCHIVE_ENTRY_ACL_TYPE_AUDIT 0x00001000 /* NFS4 only */
#define ARCHIVE_ENTRY_ACL_TYPE_ALARM 0x00002000 /* NFS4 only */
#define ARCHIVE_ENTRY_ACL_TYPE_POSIX1E (ARCHIVE_ENTRY_ACL_TYPE_ACCESS \
| ARCHIVE_ENTRY_ACL_TYPE_DEFAULT)
#define ARCHIVE_ENTRY_ACL_TYPE_NFS4 (ARCHIVE_ENTRY_ACL_TYPE_ALLOW \
| ARCHIVE_ENTRY_ACL_TYPE_DENY \
| ARCHIVE_ENTRY_ACL_TYPE_AUDIT \
| ARCHIVE_ENTRY_ACL_TYPE_ALARM)
/* Tag values mimic POSIX.1e */
#define ARCHIVE_ENTRY_ACL_USER 10001 /* Specified user. */
#define ARCHIVE_ENTRY_ACL_USER_OBJ 10002 /* User who owns the file. */
#define ARCHIVE_ENTRY_ACL_GROUP 10003 /* Specified group. */
#define ARCHIVE_ENTRY_ACL_GROUP_OBJ 10004 /* Group who owns the file. */
#define ARCHIVE_ENTRY_ACL_MASK 10005 /* Modify group access (POSIX.1e only) */
#define ARCHIVE_ENTRY_ACL_OTHER 10006 /* Public (POSIX.1e only) */
#define ARCHIVE_ENTRY_ACL_EVERYONE 10107 /* Everyone (NFS4 only) */
/*
* Set the ACL by clearing it and adding entries one at a time.
* Unlike the POSIX.1e ACL routines, you must specify the type
* (access/default) for each entry. Internally, the ACL data is just
* a soup of entries. API calls here allow you to retrieve just the
* entries of interest. This design (which goes against the spirit of
* POSIX.1e) is useful for handling archive formats that combine
* default and access information in a single ACL list.
*/
__LA_DECL void archive_entry_acl_clear(struct archive_entry *);
__LA_DECL int archive_entry_acl_add_entry(struct archive_entry *,
int /* type */, int /* permset */, int /* tag */,
int /* qual */, const char * /* name */);
__LA_DECL int archive_entry_acl_add_entry_w(struct archive_entry *,
int /* type */, int /* permset */, int /* tag */,
int /* qual */, const wchar_t * /* name */);
/*
* To retrieve the ACL, first "reset", then repeatedly ask for the
* "next" entry. The want_type parameter allows you to request only
* certain types of entries.
*/
__LA_DECL int archive_entry_acl_reset(struct archive_entry *, int /* want_type */);
__LA_DECL int archive_entry_acl_next(struct archive_entry *, int /* want_type */,
int * /* type */, int * /* permset */, int * /* tag */,
int * /* qual */, const char ** /* name */);
/*
* Construct a text-format ACL. The flags argument is a bitmask that
* can include any of the following:
*
* Flags only for archive entries with POSIX.1e ACL:
* ARCHIVE_ENTRY_ACL_TYPE_ACCESS - Include POSIX.1e "access" entries.
* ARCHIVE_ENTRY_ACL_TYPE_DEFAULT - Include POSIX.1e "default" entries.
* ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT - Include "default:" before each
* default ACL entry.
* ARCHIVE_ENTRY_ACL_STYLE_SOLARIS - Output only one colon after "other" and
* "mask" entries.
*
* Flags only for archive entries with NFSv4 ACL:
* ARCHIVE_ENTRY_ACL_STYLE_COMPACT - Do not output the minus character for
* unset permissions and flags in NFSv4 ACL permission and flag fields
*
* Flags for for archive entries with POSIX.1e ACL or NFSv4 ACL:
* ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID - Include extra numeric ID field in
* each ACL entry.
* ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA - Separate entries with comma
* instead of newline.
*/
#define ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID 0x00000001
#define ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT 0x00000002
#define ARCHIVE_ENTRY_ACL_STYLE_SOLARIS 0x00000004
#define ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA 0x00000008
#define ARCHIVE_ENTRY_ACL_STYLE_COMPACT 0x00000010
__LA_DECL wchar_t *archive_entry_acl_to_text_w(struct archive_entry *,
la_ssize_t * /* len */, int /* flags */);
__LA_DECL char *archive_entry_acl_to_text(struct archive_entry *,
la_ssize_t * /* len */, int /* flags */);
__LA_DECL int archive_entry_acl_from_text_w(struct archive_entry *,
const wchar_t * /* wtext */, int /* type */);
__LA_DECL int archive_entry_acl_from_text(struct archive_entry *,
const char * /* text */, int /* type */);
/* Deprecated constants */
#define OLD_ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID 1024
#define OLD_ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT 2048
/* Deprecated functions */
__LA_DECL const wchar_t *archive_entry_acl_text_w(struct archive_entry *,
int /* flags */) __LA_DEPRECATED;
__LA_DECL const char *archive_entry_acl_text(struct archive_entry *,
int /* flags */) __LA_DEPRECATED;
/* Return bitmask of ACL types in an archive entry */
__LA_DECL int archive_entry_acl_types(struct archive_entry *);
/* Return a count of entries matching 'want_type' */
__LA_DECL int archive_entry_acl_count(struct archive_entry *, int /* want_type */);
/* Return an opaque ACL object. */
/* There's not yet anything clients can actually do with this... */
struct archive_acl;
__LA_DECL struct archive_acl *archive_entry_acl(struct archive_entry *);
/*
* extended attributes
*/
__LA_DECL void archive_entry_xattr_clear(struct archive_entry *);
__LA_DECL void archive_entry_xattr_add_entry(struct archive_entry *,
const char * /* name */, const void * /* value */,
size_t /* size */);
/*
* To retrieve the xattr list, first "reset", then repeatedly ask for the
* "next" entry.
*/
__LA_DECL int archive_entry_xattr_count(struct archive_entry *);
__LA_DECL int archive_entry_xattr_reset(struct archive_entry *);
__LA_DECL int archive_entry_xattr_next(struct archive_entry *,
const char ** /* name */, const void ** /* value */, size_t *);
/*
* sparse
*/
__LA_DECL void archive_entry_sparse_clear(struct archive_entry *);
__LA_DECL void archive_entry_sparse_add_entry(struct archive_entry *,
la_int64_t /* offset */, la_int64_t /* length */);
/*
* To retrieve the xattr list, first "reset", then repeatedly ask for the
* "next" entry.
*/
__LA_DECL int archive_entry_sparse_count(struct archive_entry *);
__LA_DECL int archive_entry_sparse_reset(struct archive_entry *);
__LA_DECL int archive_entry_sparse_next(struct archive_entry *,
la_int64_t * /* offset */, la_int64_t * /* length */);
/*
* Utility to match up hardlinks.
*
* The 'struct archive_entry_linkresolver' is a cache of archive entries
* for files with multiple links. Here's how to use it:
* 1. Create a lookup object with archive_entry_linkresolver_new()
* 2. Tell it the archive format you're using.
* 3. Hand each archive_entry to archive_entry_linkify().
* That function will return 0, 1, or 2 entries that should
* be written.
* 4. Call archive_entry_linkify(resolver, NULL) until
* no more entries are returned.
* 5. Call archive_entry_linkresolver_free(resolver) to free resources.
*
* The entries returned have their hardlink and size fields updated
* appropriately. If an entry is passed in that does not refer to
* a file with multiple links, it is returned unchanged. The intention
* is that you should be able to simply filter all entries through
* this machine.
*
* To make things more efficient, be sure that each entry has a valid
* nlinks value. The hardlink cache uses this to track when all links
* have been found. If the nlinks value is zero, it will keep every
* name in the cache indefinitely, which can use a lot of memory.
*
* Note that archive_entry_size() is reset to zero if the file
* body should not be written to the archive. Pay attention!
*/
struct archive_entry_linkresolver;
/*
* There are three different strategies for marking hardlinks.
* The descriptions below name them after the best-known
* formats that rely on each strategy:
*
* "Old cpio" is the simplest, it always returns any entry unmodified.
* As far as I know, only cpio formats use this. Old cpio archives
* store every link with the full body; the onus is on the dearchiver
* to detect and properly link the files as they are restored.
* "tar" is also pretty simple; it caches a copy the first time it sees
* any link. Subsequent appearances are modified to be hardlink
* references to the first one without any body. Used by all tar
* formats, although the newest tar formats permit the "old cpio" strategy
* as well. This strategy is very simple for the dearchiver,
* and reasonably straightforward for the archiver.
* "new cpio" is trickier. It stores the body only with the last
* occurrence. The complication is that we might not
* see every link to a particular file in a single session, so
* there's no easy way to know when we've seen the last occurrence.
* The solution here is to queue one link until we see the next.
* At the end of the session, you can enumerate any remaining
* entries by calling archive_entry_linkify(NULL) and store those
* bodies. If you have a file with three links l1, l2, and l3,
* you'll get the following behavior if you see all three links:
* linkify(l1) => NULL (the resolver stores l1 internally)
* linkify(l2) => l1 (resolver stores l2, you write l1)
* linkify(l3) => l2, l3 (all links seen, you can write both).
* If you only see l1 and l2, you'll get this behavior:
* linkify(l1) => NULL
* linkify(l2) => l1
* linkify(NULL) => l2 (at end, you retrieve remaining links)
* As the name suggests, this strategy is used by newer cpio variants.
* It's noticeably more complex for the archiver, slightly more complex
* for the dearchiver than the tar strategy, but makes it straightforward
* to restore a file using any link by simply continuing to scan until
* you see a link that is stored with a body. In contrast, the tar
* strategy requires you to rescan the archive from the beginning to
* correctly extract an arbitrary link.
*/
__LA_DECL struct archive_entry_linkresolver *archive_entry_linkresolver_new(void);
__LA_DECL void archive_entry_linkresolver_set_strategy(
struct archive_entry_linkresolver *, int /* format_code */);
__LA_DECL void archive_entry_linkresolver_free(struct archive_entry_linkresolver *);
__LA_DECL void archive_entry_linkify(struct archive_entry_linkresolver *,
struct archive_entry **, struct archive_entry **);
__LA_DECL struct archive_entry *archive_entry_partial_links(
struct archive_entry_linkresolver *res, unsigned int *links);
#ifdef __cplusplus
}
#endif
/* This is meaningless outside of this header. */
#undef __LA_DECL
#endif /* !ARCHIVE_ENTRY_H_INCLUDED */
@@ -0,0 +1,123 @@
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2006 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is Red Hat, Inc.
*
* Contributor(s):
* Carl D. Worth <cworth@cworth.org>
*/
#ifndef CAIRO_DEPRECATED_H
#define CAIRO_DEPRECATED_H
#define CAIRO_FONT_TYPE_ATSUI CAIRO_FONT_TYPE_QUARTZ
/* Obsolete functions. These definitions exist to coerce the compiler
* into providing a little bit of guidance with its error
* messages. The idea is to help users port their old code without
* having to dig through lots of documentation.
*
* The first set of REPLACED_BY functions is for functions whose names
* have just been changed. So fixing these up is mechanical, (and
* automated by means of the cairo/util/cairo-api-update script.
*
* The second set of DEPRECATED_BY functions is for functions where
* the replacement is used in a different way, (ie. different
* arguments, multiple functions instead of one, etc). Fixing these up
* will require a bit more work on the user's part, (and hopefully we
* can get cairo-api-update to find these and print some guiding
* information).
*/
#define cairo_current_font_extents cairo_current_font_extents_REPLACED_BY_cairo_font_extents
#define cairo_get_font_extents cairo_get_font_extents_REPLACED_BY_cairo_font_extents
#define cairo_current_operator cairo_current_operator_REPLACED_BY_cairo_get_operator
#define cairo_current_tolerance cairo_current_tolerance_REPLACED_BY_cairo_get_tolerance
#define cairo_current_point cairo_current_point_REPLACED_BY_cairo_get_current_point
#define cairo_current_fill_rule cairo_current_fill_rule_REPLACED_BY_cairo_get_fill_rule
#define cairo_current_line_width cairo_current_line_width_REPLACED_BY_cairo_get_line_width
#define cairo_current_line_cap cairo_current_line_cap_REPLACED_BY_cairo_get_line_cap
#define cairo_current_line_join cairo_current_line_join_REPLACED_BY_cairo_get_line_join
#define cairo_current_miter_limit cairo_current_miter_limit_REPLACED_BY_cairo_get_miter_limit
#define cairo_current_matrix cairo_current_matrix_REPLACED_BY_cairo_get_matrix
#define cairo_current_target_surface cairo_current_target_surface_REPLACED_BY_cairo_get_target
#define cairo_get_status cairo_get_status_REPLACED_BY_cairo_status
#define cairo_concat_matrix cairo_concat_matrix_REPLACED_BY_cairo_transform
#define cairo_scale_font cairo_scale_font_REPLACED_BY_cairo_set_font_size
#define cairo_select_font cairo_select_font_REPLACED_BY_cairo_select_font_face
#define cairo_transform_font cairo_transform_font_REPLACED_BY_cairo_set_font_matrix
#define cairo_transform_point cairo_transform_point_REPLACED_BY_cairo_user_to_device
#define cairo_transform_distance cairo_transform_distance_REPLACED_BY_cairo_user_to_device_distance
#define cairo_inverse_transform_point cairo_inverse_transform_point_REPLACED_BY_cairo_device_to_user
#define cairo_inverse_transform_distance cairo_inverse_transform_distance_REPLACED_BY_cairo_device_to_user_distance
#define cairo_init_clip cairo_init_clip_REPLACED_BY_cairo_reset_clip
#define cairo_surface_create_for_image cairo_surface_create_for_image_REPLACED_BY_cairo_image_surface_create_for_data
#define cairo_default_matrix cairo_default_matrix_REPLACED_BY_cairo_identity_matrix
#define cairo_matrix_set_affine cairo_matrix_set_affine_REPLACED_BY_cairo_matrix_init
#define cairo_matrix_set_identity cairo_matrix_set_identity_REPLACED_BY_cairo_matrix_init_identity
#define cairo_pattern_add_color_stop cairo_pattern_add_color_stop_REPLACED_BY_cairo_pattern_add_color_stop_rgba
#define cairo_set_rgb_color cairo_set_rgb_color_REPLACED_BY_cairo_set_source_rgb
#define cairo_set_pattern cairo_set_pattern_REPLACED_BY_cairo_set_source
#define cairo_xlib_surface_create_for_pixmap_with_visual cairo_xlib_surface_create_for_pixmap_with_visual_REPLACED_BY_cairo_xlib_surface_create
#define cairo_xlib_surface_create_for_window_with_visual cairo_xlib_surface_create_for_window_with_visual_REPLACED_BY_cairo_xlib_surface_create
#define cairo_xcb_surface_create_for_pixmap_with_visual cairo_xcb_surface_create_for_pixmap_with_visual_REPLACED_BY_cairo_xcb_surface_create
#define cairo_xcb_surface_create_for_window_with_visual cairo_xcb_surface_create_for_window_with_visual_REPLACED_BY_cairo_xcb_surface_create
#define cairo_ps_surface_set_dpi cairo_ps_surface_set_dpi_REPLACED_BY_cairo_surface_set_fallback_resolution
#define cairo_pdf_surface_set_dpi cairo_pdf_surface_set_dpi_REPLACED_BY_cairo_surface_set_fallback_resolution
#define cairo_svg_surface_set_dpi cairo_svg_surface_set_dpi_REPLACED_BY_cairo_surface_set_fallback_resolution
#define cairo_atsui_font_face_create_for_atsu_font_id cairo_atsui_font_face_create_for_atsu_font_id_REPLACED_BY_cairo_quartz_font_face_create_for_atsu_font_id
#define cairo_current_path cairo_current_path_DEPRECATED_BY_cairo_copy_path
#define cairo_current_path_flat cairo_current_path_flat_DEPRECATED_BY_cairo_copy_path_flat
#define cairo_get_path cairo_get_path_DEPRECATED_BY_cairo_copy_path
#define cairo_get_path_flat cairo_get_path_flat_DEPRECATED_BY_cairo_get_path_flat
#define cairo_set_alpha cairo_set_alpha_DEPRECATED_BY_cairo_set_source_rgba_OR_cairo_paint_with_alpha
#define cairo_show_surface cairo_show_surface_DEPRECATED_BY_cairo_set_source_surface_AND_cairo_paint
#define cairo_copy cairo_copy_DEPRECATED_BY_cairo_create_AND_MANY_INDIVIDUAL_FUNCTIONS
#define cairo_surface_set_repeat cairo_surface_set_repeat_DEPRECATED_BY_cairo_pattern_set_extend
#define cairo_surface_set_matrix cairo_surface_set_matrix_DEPRECATED_BY_cairo_pattern_set_matrix
#define cairo_surface_get_matrix cairo_surface_get_matrix_DEPRECATED_BY_cairo_pattern_get_matrix
#define cairo_surface_set_filter cairo_surface_set_filter_DEPRECATED_BY_cairo_pattern_set_filter
#define cairo_surface_get_filter cairo_surface_get_filter_DEPRECATED_BY_cairo_pattern_get_filter
#define cairo_matrix_create cairo_matrix_create_DEPRECATED_BY_cairo_matrix_t
#define cairo_matrix_destroy cairo_matrix_destroy_DEPRECATED_BY_cairo_matrix_t
#define cairo_matrix_copy cairo_matrix_copy_DEPRECATED_BY_cairo_matrix_t
#define cairo_matrix_get_affine cairo_matrix_get_affine_DEPRECATED_BY_cairo_matrix_t
#define cairo_set_target_surface cairo_set_target_surface_DEPRECATED_BY_cairo_create
#define cairo_set_target_image cairo_set_target_image_DEPRECATED_BY_cairo_image_surface_create_for_data
#define cairo_set_target_pdf cairo_set_target_pdf_DEPRECATED_BY_cairo_pdf_surface_create
#define cairo_set_target_png cairo_set_target_png_DEPRECATED_BY_cairo_surface_write_to_png
#define cairo_set_target_ps cairo_set_target_ps_DEPRECATED_BY_cairo_ps_surface_create
#define cairo_set_target_quartz cairo_set_target_quartz_DEPRECATED_BY_cairo_quartz_surface_create
#define cairo_set_target_win32 cairo_set_target_win32_DEPRECATED_BY_cairo_win32_surface_create
#define cairo_set_target_xcb cairo_set_target_xcb_DEPRECATED_BY_cairo_xcb_surface_create
#define cairo_set_target_drawable cairo_set_target_drawable_DEPRECATED_BY_cairo_xlib_surface_create
#define cairo_get_status_string cairo_get_status_string_DEPRECATED_BY_cairo_status_AND_cairo_status_to_string
#define cairo_status_string cairo_status_string_DEPRECATED_BY_cairo_status_AND_cairo_status_to_string
#endif /* CAIRO_DEPRECATED_H */
@@ -0,0 +1,29 @@
/*
* Autogenerated by the Meson build system.
* Do not edit, your changes will be lost.
*/
#pragma once
#define CAIRO_FEATURES_H
#define CAIRO_HAS_FC_FONT 1
#define CAIRO_HAS_FT_FONT 1
#define CAIRO_HAS_GOBJECT_FUNCTIONS 1
#define CAIRO_HAS_IMAGE_SURFACE 1
#define CAIRO_HAS_MIME_SURFACE 1
#define CAIRO_HAS_OBSERVER_SURFACE 1
#define CAIRO_HAS_PNG_FUNCTIONS 1
#define CAIRO_HAS_RECORDING_SURFACE 1
#define CAIRO_HAS_SVG_SURFACE 1
#define CAIRO_HAS_USER_FONT 1
@@ -0,0 +1,118 @@
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2005 Red Hat, Inc
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is Red Hat, Inc.
*
* Contributor(s):
* Graydon Hoare <graydon@redhat.com>
* Owen Taylor <otaylor@redhat.com>
*/
#ifndef CAIRO_FT_H
#define CAIRO_FT_H
#include "cairo.h"
#if CAIRO_HAS_FT_FONT
/* Fontconfig/Freetype platform-specific font interface */
#include <ft2build.h>
#include FT_FREETYPE_H
#if CAIRO_HAS_FC_FONT
#include <fontconfig/fontconfig.h>
#endif
CAIRO_BEGIN_DECLS
cairo_public cairo_font_face_t *
cairo_ft_font_face_create_for_ft_face (FT_Face face,
int load_flags);
/**
* cairo_ft_synthesize_t:
* @CAIRO_FT_SYNTHESIZE_BOLD: Embolden the glyphs (redraw with a pixel offset)
* @CAIRO_FT_SYNTHESIZE_OBLIQUE: Slant the glyph outline by 12 degrees to the
* right.
*
* A set of synthesis options to control how FreeType renders the glyphs
* for a particular font face.
*
* Individual synthesis features of a #cairo_ft_font_face_t can be set
* using cairo_ft_font_face_set_synthesize(), or disabled using
* cairo_ft_font_face_unset_synthesize(). The currently enabled set of
* synthesis options can be queried with cairo_ft_font_face_get_synthesize().
*
* Note: that when synthesizing glyphs, the font metrics returned will only
* be estimates.
*
* Since: 1.12
**/
typedef enum {
CAIRO_FT_SYNTHESIZE_BOLD = 1 << 0,
CAIRO_FT_SYNTHESIZE_OBLIQUE = 1 << 1
} cairo_ft_synthesize_t;
cairo_public void
cairo_ft_font_face_set_synthesize (cairo_font_face_t *font_face,
unsigned int synth_flags);
cairo_public void
cairo_ft_font_face_unset_synthesize (cairo_font_face_t *font_face,
unsigned int synth_flags);
cairo_public unsigned int
cairo_ft_font_face_get_synthesize (cairo_font_face_t *font_face);
cairo_public FT_Face
cairo_ft_scaled_font_lock_face (cairo_scaled_font_t *scaled_font);
cairo_public void
cairo_ft_scaled_font_unlock_face (cairo_scaled_font_t *scaled_font);
#if CAIRO_HAS_FC_FONT
cairo_public cairo_font_face_t *
cairo_ft_font_face_create_for_pattern (FcPattern *pattern);
cairo_public void
cairo_ft_font_options_substitute (const cairo_font_options_t *options,
FcPattern *pattern);
#endif
CAIRO_END_DECLS
#else /* CAIRO_HAS_FT_FONT */
# error Cairo was not compiled with support for the freetype font backend
#endif /* CAIRO_HAS_FT_FONT */
#endif /* CAIRO_FT_H */
@@ -0,0 +1,192 @@
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2010 Red Hat Inc.
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is University of Southern
* California.
*
* Contributor(s):
* Benjamin Otte <otte@redhat.com>
*/
#ifndef CAIRO_GOBJECT_H
#define CAIRO_GOBJECT_H
#include <cairo.h>
#if CAIRO_HAS_GOBJECT_FUNCTIONS
#include <glib-object.h>
CAIRO_BEGIN_DECLS
/* structs */
#define CAIRO_GOBJECT_TYPE_CONTEXT cairo_gobject_context_get_type ()
cairo_public GType
cairo_gobject_context_get_type (void);
#define CAIRO_GOBJECT_TYPE_DEVICE cairo_gobject_device_get_type ()
cairo_public GType
cairo_gobject_device_get_type (void);
#define CAIRO_GOBJECT_TYPE_MATRIX cairo_gobject_matrix_get_type ()
cairo_public GType
cairo_gobject_matrix_get_type (void);
#define CAIRO_GOBJECT_TYPE_PATTERN cairo_gobject_pattern_get_type ()
cairo_public GType
cairo_gobject_pattern_get_type (void);
#define CAIRO_GOBJECT_TYPE_SURFACE cairo_gobject_surface_get_type ()
cairo_public GType
cairo_gobject_surface_get_type (void);
#define CAIRO_GOBJECT_TYPE_RECTANGLE cairo_gobject_rectangle_get_type ()
cairo_public GType
cairo_gobject_rectangle_get_type (void);
#define CAIRO_GOBJECT_TYPE_SCALED_FONT cairo_gobject_scaled_font_get_type ()
cairo_public GType
cairo_gobject_scaled_font_get_type (void);
#define CAIRO_GOBJECT_TYPE_FONT_FACE cairo_gobject_font_face_get_type ()
cairo_public GType
cairo_gobject_font_face_get_type (void);
#define CAIRO_GOBJECT_TYPE_FONT_OPTIONS cairo_gobject_font_options_get_type ()
cairo_public GType
cairo_gobject_font_options_get_type (void);
#define CAIRO_GOBJECT_TYPE_RECTANGLE_INT cairo_gobject_rectangle_int_get_type ()
cairo_public GType
cairo_gobject_rectangle_int_get_type (void);
#define CAIRO_GOBJECT_TYPE_REGION cairo_gobject_region_get_type ()
cairo_public GType
cairo_gobject_region_get_type (void);
/* enums */
#define CAIRO_GOBJECT_TYPE_STATUS cairo_gobject_status_get_type ()
cairo_public GType
cairo_gobject_status_get_type (void);
#define CAIRO_GOBJECT_TYPE_CONTENT cairo_gobject_content_get_type ()
cairo_public GType
cairo_gobject_content_get_type (void);
#define CAIRO_GOBJECT_TYPE_OPERATOR cairo_gobject_operator_get_type ()
cairo_public GType
cairo_gobject_operator_get_type (void);
#define CAIRO_GOBJECT_TYPE_ANTIALIAS cairo_gobject_antialias_get_type ()
cairo_public GType
cairo_gobject_antialias_get_type (void);
#define CAIRO_GOBJECT_TYPE_FILL_RULE cairo_gobject_fill_rule_get_type ()
cairo_public GType
cairo_gobject_fill_rule_get_type (void);
#define CAIRO_GOBJECT_TYPE_LINE_CAP cairo_gobject_line_cap_get_type ()
cairo_public GType
cairo_gobject_line_cap_get_type (void);
#define CAIRO_GOBJECT_TYPE_LINE_JOIN cairo_gobject_line_join_get_type ()
cairo_public GType
cairo_gobject_line_join_get_type (void);
#define CAIRO_GOBJECT_TYPE_TEXT_CLUSTER_FLAGS cairo_gobject_text_cluster_flags_get_type ()
cairo_public GType
cairo_gobject_text_cluster_flags_get_type (void);
#define CAIRO_GOBJECT_TYPE_FONT_SLANT cairo_gobject_font_slant_get_type ()
cairo_public GType
cairo_gobject_font_slant_get_type (void);
#define CAIRO_GOBJECT_TYPE_FONT_WEIGHT cairo_gobject_font_weight_get_type ()
cairo_public GType
cairo_gobject_font_weight_get_type (void);
#define CAIRO_GOBJECT_TYPE_SUBPIXEL_ORDER cairo_gobject_subpixel_order_get_type ()
cairo_public GType
cairo_gobject_subpixel_order_get_type (void);
#define CAIRO_GOBJECT_TYPE_HINT_STYLE cairo_gobject_hint_style_get_type ()
cairo_public GType
cairo_gobject_hint_style_get_type (void);
/* historical accident */
#define CAIRO_GOBJECT_TYPE_HNT_METRICS cairo_gobject_hint_metrics_get_type ()
#define CAIRO_GOBJECT_TYPE_HINT_METRICS cairo_gobject_hint_metrics_get_type ()
cairo_public GType
cairo_gobject_hint_metrics_get_type (void);
#define CAIRO_GOBJECT_TYPE_FONT_TYPE cairo_gobject_font_type_get_type ()
cairo_public GType
cairo_gobject_font_type_get_type (void);
#define CAIRO_GOBJECT_TYPE_PATH_DATA_TYPE cairo_gobject_path_data_type_get_type ()
cairo_public GType
cairo_gobject_path_data_type_get_type (void);
#define CAIRO_GOBJECT_TYPE_DEVICE_TYPE cairo_gobject_device_type_get_type ()
cairo_public GType
cairo_gobject_device_type_get_type (void);
#define CAIRO_GOBJECT_TYPE_SURFACE_TYPE cairo_gobject_surface_type_get_type ()
cairo_public GType
cairo_gobject_surface_type_get_type (void);
#define CAIRO_GOBJECT_TYPE_FORMAT cairo_gobject_format_get_type ()
cairo_public GType
cairo_gobject_format_get_type (void);
#define CAIRO_GOBJECT_TYPE_PATTERN_TYPE cairo_gobject_pattern_type_get_type ()
cairo_public GType
cairo_gobject_pattern_type_get_type (void);
#define CAIRO_GOBJECT_TYPE_EXTEND cairo_gobject_extend_get_type ()
cairo_public GType
cairo_gobject_extend_get_type (void);
#define CAIRO_GOBJECT_TYPE_FILTER cairo_gobject_filter_get_type ()
cairo_public GType
cairo_gobject_filter_get_type (void);
#define CAIRO_GOBJECT_TYPE_REGION_OVERLAP cairo_gobject_region_overlap_get_type ()
cairo_public GType
cairo_gobject_region_overlap_get_type (void);
CAIRO_END_DECLS
#else /* CAIRO_HAS_GOBJECT_FUNCTIONS */
# error Cairo was not compiled with support for GObject
#endif /* CAIRO_HAS_GOBJECT_FUNCTIONS */
#endif /* CAIRO_GOBJECT_H */
@@ -0,0 +1,130 @@
/* cairo - a vector graphics library with display and print output
*
* cairo-svg.h
*
* Copyright © 2005 Emmanuel Pacaud <emmanuel.pacaud@univ-poitiers.fr>
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
*/
#ifndef CAIRO_SVG_H
#define CAIRO_SVG_H
#include "cairo.h"
#if CAIRO_HAS_SVG_SURFACE
CAIRO_BEGIN_DECLS
/**
* cairo_svg_version_t:
* @CAIRO_SVG_VERSION_1_1: The version 1.1 of the SVG specification. (Since 1.2)
* @CAIRO_SVG_VERSION_1_2: The version 1.2 of the SVG specification. (Since 1.2)
*
* #cairo_svg_version_t is used to describe the version number of the SVG
* specification that a generated SVG file will conform to.
*
* Since: 1.2
**/
typedef enum _cairo_svg_version {
CAIRO_SVG_VERSION_1_1,
CAIRO_SVG_VERSION_1_2
} cairo_svg_version_t;
/**
* cairo_svg_unit_t:
* @CAIRO_SVG_UNIT_USER: User unit, a value in the current coordinate system.
* If used in the root element for the initial coordinate systems it
* corresponds to pixels. (Since 1.16)
* @CAIRO_SVG_UNIT_EM: The size of the element's font. (Since 1.16)
* @CAIRO_SVG_UNIT_EX: The x-height of the elements font. (Since 1.16)
* @CAIRO_SVG_UNIT_PX: Pixels (1px = 1/96th of 1in). (Since 1.16)
* @CAIRO_SVG_UNIT_IN: Inches (1in = 2.54cm = 96px). (Since 1.16)
* @CAIRO_SVG_UNIT_CM: Centimeters (1cm = 96px/2.54). (Since 1.16)
* @CAIRO_SVG_UNIT_MM: Millimeters (1mm = 1/10th of 1cm). (Since 1.16)
* @CAIRO_SVG_UNIT_PT: Points (1pt = 1/72th of 1in). (Since 1.16)
* @CAIRO_SVG_UNIT_PC: Picas (1pc = 1/6th of 1in). (Since 1.16)
* @CAIRO_SVG_UNIT_PERCENT: Percent, a value that is some fraction of another
* reference value. (Since 1.16)
*
* #cairo_svg_unit_t is used to describe the units valid for coordinates and
* lengths in the SVG specification.
*
* See also:
* https://www.w3.org/TR/SVG/coords.html#Units
* https://www.w3.org/TR/SVG/types.html#DataTypeLength
* https://www.w3.org/TR/css-values-3/#lengths
*
* Since: 1.16
**/
typedef enum _cairo_svg_unit {
CAIRO_SVG_UNIT_USER = 0,
CAIRO_SVG_UNIT_EM,
CAIRO_SVG_UNIT_EX,
CAIRO_SVG_UNIT_PX,
CAIRO_SVG_UNIT_IN,
CAIRO_SVG_UNIT_CM,
CAIRO_SVG_UNIT_MM,
CAIRO_SVG_UNIT_PT,
CAIRO_SVG_UNIT_PC,
CAIRO_SVG_UNIT_PERCENT
} cairo_svg_unit_t;
cairo_public cairo_surface_t *
cairo_svg_surface_create (const char *filename,
double width_in_points,
double height_in_points);
cairo_public cairo_surface_t *
cairo_svg_surface_create_for_stream (cairo_write_func_t write_func,
void *closure,
double width_in_points,
double height_in_points);
cairo_public void
cairo_svg_surface_restrict_to_version (cairo_surface_t *surface,
cairo_svg_version_t version);
cairo_public void
cairo_svg_get_versions (cairo_svg_version_t const **versions,
int *num_versions);
cairo_public const char *
cairo_svg_version_to_string (cairo_svg_version_t version);
cairo_public void
cairo_svg_surface_set_document_unit (cairo_surface_t *surface,
cairo_svg_unit_t unit);
cairo_public cairo_svg_unit_t
cairo_svg_surface_get_document_unit (cairo_surface_t *surface);
CAIRO_END_DECLS
#else /* CAIRO_HAS_SVG_SURFACE */
# error Cairo was not compiled with support for the svg backend
#endif /* CAIRO_HAS_SVG_SURFACE */
#endif /* CAIRO_SVG_H */
@@ -0,0 +1,8 @@
#ifndef CAIRO_VERSION_H
#define CAIRO_VERSION_H
#define CAIRO_VERSION_MAJOR 1
#define CAIRO_VERSION_MINOR 17
#define CAIRO_VERSION_MICRO 8
#endif
File diff suppressed because it is too large Load Diff
+80
View File
@@ -0,0 +1,80 @@
#ifndef CGIF_H
#define CGIF_H
#include <stdint.h>
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
// flags to set the GIF/frame-attributes
#define CGIF_ATTR_IS_ANIMATED (1uL << 1) // make an animated GIF (default is non-animated GIF)
#define CGIF_ATTR_NO_GLOBAL_TABLE (1uL << 2) // disable global color table (global color table is default)
#define CGIF_ATTR_HAS_TRANSPARENCY (1uL << 3) // first entry in color table contains transparency (alpha channel)
#define CGIF_ATTR_NO_LOOP (1uL << 4) // don't loop a GIF animation: only play it one time.
#define CGIF_FRAME_ATTR_USE_LOCAL_TABLE (1uL << 0) // use a local color table for a frame (local color table is not used by default)
#define CGIF_FRAME_ATTR_HAS_ALPHA (1uL << 1) // alpha channel index provided by user (transIndex field)
#define CGIF_FRAME_ATTR_HAS_SET_TRANS (1uL << 2) // transparency setting provided by user (transIndex field)
#define CGIF_FRAME_ATTR_INTERLACED (1uL << 3) // encode frame interlaced (default is not interlaced)
// flags to decrease GIF-size
#define CGIF_FRAME_GEN_USE_TRANSPARENCY (1uL << 0) // use transparency optimization (setting pixels identical to previous frame transparent)
#define CGIF_FRAME_GEN_USE_DIFF_WINDOW (1uL << 1) // do encoding just for the sub-window that has changed from previous frame
#define CGIF_INFINITE_LOOP (0x0000uL) // for animated GIF: 0 specifies infinite loop
typedef enum {
CGIF_ERROR = -1, // something unspecified failed
CGIF_OK = 0, // everything OK
CGIF_EWRITE, // writing GIF data failed
CGIF_EALLOC, // allocating memory failed
CGIF_ECLOSE, // final call to fclose failed
CGIF_EOPEN, // failed to open output file
CGIF_EINDEX, // invalid index in image data provided by user
// internal section (values subject to change)
CGIF_PENDING,
} cgif_result;
typedef struct st_gif CGIF; // struct for the full GIF
typedef struct st_gifconfig CGIF_Config; // global cofinguration parameters of the GIF
typedef struct st_frameconfig CGIF_FrameConfig; // local configuration parameters for a frame
typedef int cgif_write_fn(void* pContext, const uint8_t* pData, const size_t numBytes); // callback function for stream-based output
// prototypes
CGIF* cgif_newgif (CGIF_Config* pConfig); // creates a new GIF (returns pointer to new GIF or NULL on error)
int cgif_addframe (CGIF* pGIF, CGIF_FrameConfig* pConfig); // adds the next frame to an existing GIF (returns 0 on success)
int cgif_close (CGIF* pGIF); // close file and free allocated memory (returns 0 on success)
// CGIF_Config type (parameters passed by user)
// note: must stay AS IS for backward compatibility
struct st_gifconfig {
uint8_t* pGlobalPalette; // global color table of the GIF
const char* path; // path of the GIF to be created, mutually exclusive with pWriteFn
uint32_t attrFlags; // fixed attributes of the GIF (e.g. whether it is animated or not)
uint32_t genFlags; // flags that determine how the GIF is generated (e.g. optimization)
uint16_t width; // width of each frame in the GIF
uint16_t height; // height of each frame in the GIF
uint16_t numGlobalPaletteEntries; // size of the global color table
uint16_t numLoops; // number of repetitons of an animated GIF (set to INFINITE_LOOP for infinite loop)
cgif_write_fn *pWriteFn; // callback function for chunks of output data, mutually exclusive with path
void* pContext; // opaque pointer passed as the first parameter to pWriteFn
};
// CGIF_FrameConfig type (parameters passed by user)
// note: must stay AS IS for backward compatibility
struct st_frameconfig {
uint8_t* pLocalPalette; // local color table of a frame
uint8_t* pImageData; // image data to be encoded
uint32_t attrFlags; // fixed attributes of the GIF frame
uint32_t genFlags; // flags that determine how the GIF frame is created (e.g. optimization)
uint16_t delay; // delay before the next frame is shown (units of 0.01 s)
uint16_t numLocalPaletteEntries; // size of the local color table
uint8_t transIndex; // introduced with V0.2.0
};
#ifdef __cplusplus
}
#endif
#endif // CGIF_H
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,140 @@
/* expat_config.h. Generated from expat_config.h.in by configure. */
/* expat_config.h.in. Generated from configure.ac by autoheader. */
#ifndef EXPAT_CONFIG_H
#define EXPAT_CONFIG_H 1
/* Define if building universal (internal helper macro) */
/* #undef AC_APPLE_UNIVERSAL_BUILD */
/* 1234 = LILENDIAN, 4321 = BIGENDIAN */
#define BYTEORDER 1234
/* Define to 1 if you have the `arc4random' function. */
/* #undef HAVE_ARC4RANDOM */
/* Define to 1 if you have the `arc4random_buf' function. */
/* #undef HAVE_ARC4RANDOM_BUF */
/* Define to 1 if you have the <dlfcn.h> header file. */
/* #undef HAVE_DLFCN_H */
/* Define to 1 if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 1
/* Define to 1 if you have the `getpagesize' function. */
/* #undef HAVE_GETPAGESIZE */
/* Define to 1 if you have the `getrandom' function. */
/* #undef HAVE_GETRANDOM */
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the `bsd' library (-lbsd). */
/* #undef HAVE_LIBBSD */
/* Define to 1 if you have a working `mmap' system call. */
/* #undef HAVE_MMAP */
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdio.h> header file. */
#define HAVE_STDIO_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have `syscall' and `SYS_getrandom'. */
/* #undef HAVE_SYSCALL_GETRANDOM */
/* Define to 1 if you have the <sys/param.h> header file. */
#define HAVE_SYS_PARAM_H 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to the sub-directory where libtool stores uninstalled libraries. */
#define LT_OBJDIR ".libs/"
/* Name of package */
#define PACKAGE "expat"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "expat-bugs@libexpat.org"
/* Define to the full name of this package. */
#define PACKAGE_NAME "expat"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "expat 2.5.0"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "expat"
/* Define to the home page for this package. */
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION "2.5.0"
/* Define to 1 if all of the C90 standard headers exist (not just the ones
required in a freestanding environment). This macro is provided for
backward compatibility; new code need not use it. */
#define STDC_HEADERS 1
/* Version number of package */
#define VERSION "2.5.0"
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD
# if defined __BIG_ENDIAN__
# define WORDS_BIGENDIAN 1
# endif
#else
# ifndef WORDS_BIGENDIAN
/* # undef WORDS_BIGENDIAN */
# endif
#endif
/* Define to allow retrieving the byte offsets for attribute names and values.
*/
/* #undef XML_ATTR_INFO */
/* Define to specify how much context to retain around the current parse
point. */
#define XML_CONTEXT_BYTES 1024
/* Define to include code reading entropy from `/dev/urandom'. */
#define XML_DEV_URANDOM 1
/* Define to make parameter entity parsing functionality available. */
#define XML_DTD 1
/* Define to make XML Namespaces functionality available. */
#define XML_NS 1
/* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */
/* Define to `long int' if <sys/types.h> does not define. */
/* #undef off_t */
/* Define to `unsigned int' if <sys/types.h> does not define. */
/* #undef size_t */
#endif // ndef EXPAT_CONFIG_H
@@ -0,0 +1,165 @@
/*
__ __ _
___\ \/ /_ __ __ _| |_
/ _ \\ /| '_ \ / _` | __|
| __// \| |_) | (_| | |_
\___/_/\_\ .__/ \__,_|\__|
|_| XML parser
Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
Copyright (c) 2000-2004 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
Copyright (c) 2001-2002 Greg Stein <gstein@users.sourceforge.net>
Copyright (c) 2002-2006 Karl Waclawek <karl@waclawek.net>
Copyright (c) 2016 Cristian Rodríguez <crrodriguez@opensuse.org>
Copyright (c) 2016-2019 Sebastian Pipping <sebastian@pipping.org>
Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
Copyright (c) 2018 Yury Gribov <tetra2005@gmail.com>
Licensed under the MIT license:
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.
*/
#ifndef Expat_External_INCLUDED
#define Expat_External_INCLUDED 1
/* External API definitions */
/* Expat tries very hard to make the API boundary very specifically
defined. There are two macros defined to control this boundary;
each of these can be defined before including this header to
achieve some different behavior, but doing so it not recommended or
tested frequently.
XMLCALL - The calling convention to use for all calls across the
"library boundary." This will default to cdecl, and
try really hard to tell the compiler that's what we
want.
XMLIMPORT - Whatever magic is needed to note that a function is
to be imported from a dynamically loaded library
(.dll, .so, or .sl, depending on your platform).
The XMLCALL macro was added in Expat 1.95.7. The only one which is
expected to be directly useful in client code is XMLCALL.
Note that on at least some Unix versions, the Expat library must be
compiled with the cdecl calling convention as the default since
system headers may assume the cdecl convention.
*/
#ifndef XMLCALL
# if defined(_MSC_VER)
# define XMLCALL __cdecl
# elif defined(__GNUC__) && defined(__i386) && ! defined(__INTEL_COMPILER)
# define XMLCALL __attribute__((cdecl))
# else
/* For any platform which uses this definition and supports more than
one calling convention, we need to extend this definition to
declare the convention used on that platform, if it's possible to
do so.
If this is the case for your platform, please file a bug report
with information on how to identify your platform via the C
pre-processor and how to specify the same calling convention as the
platform's malloc() implementation.
*/
# define XMLCALL
# endif
#endif /* not defined XMLCALL */
#if ! defined(XML_STATIC) && ! defined(XMLIMPORT)
# ifndef XML_BUILDING_EXPAT
/* using Expat from an application */
# if defined(_MSC_EXTENSIONS) && ! defined(__BEOS__) && ! defined(__CYGWIN__)
# define XMLIMPORT __declspec(dllimport)
# endif
# endif
#endif /* not defined XML_STATIC */
#ifndef XML_ENABLE_VISIBILITY
# define XML_ENABLE_VISIBILITY 0
#endif
#if ! defined(XMLIMPORT) && XML_ENABLE_VISIBILITY
# define XMLIMPORT __attribute__((visibility("default")))
#endif
/* If we didn't define it above, define it away: */
#ifndef XMLIMPORT
# define XMLIMPORT
#endif
#if defined(__GNUC__) \
&& (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96))
# define XML_ATTR_MALLOC __attribute__((__malloc__))
#else
# define XML_ATTR_MALLOC
#endif
#if defined(__GNUC__) \
&& ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
# define XML_ATTR_ALLOC_SIZE(x) __attribute__((__alloc_size__(x)))
#else
# define XML_ATTR_ALLOC_SIZE(x)
#endif
#define XMLPARSEAPI(type) XMLIMPORT type XMLCALL
#ifdef __cplusplus
extern "C" {
#endif
#ifdef XML_UNICODE_WCHAR_T
# ifndef XML_UNICODE
# define XML_UNICODE
# endif
# if defined(__SIZEOF_WCHAR_T__) && (__SIZEOF_WCHAR_T__ != 2)
# error "sizeof(wchar_t) != 2; Need -fshort-wchar for both Expat and libc"
# endif
#endif
#ifdef XML_UNICODE /* Information is UTF-16 encoded. */
# ifdef XML_UNICODE_WCHAR_T
typedef wchar_t XML_Char;
typedef wchar_t XML_LChar;
# else
typedef unsigned short XML_Char;
typedef char XML_LChar;
# endif /* XML_UNICODE_WCHAR_T */
#else /* Information is UTF-8 encoded. */
typedef char XML_Char;
typedef char XML_LChar;
#endif /* XML_UNICODE */
#ifdef XML_LARGE_SIZE /* Use large integers for file/stream positions. */
typedef long long XML_Index;
typedef unsigned long long XML_Size;
#else
typedef long XML_Index;
typedef unsigned long XML_Size;
#endif /* XML_LARGE_SIZE */
#ifdef __cplusplus
}
#endif
#endif /* not Expat_External_INCLUDED */
+531
View File
@@ -0,0 +1,531 @@
/* -----------------------------------------------------------------*-C-*-
libffi 3.4.4
- Copyright (c) 2011, 2014, 2019, 2021, 2022 Anthony Green
- Copyright (c) 1996-2003, 2007, 2008 Red Hat, Inc.
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.
----------------------------------------------------------------------- */
/* -------------------------------------------------------------------
Most of the API is documented in doc/libffi.texi.
The raw API is designed to bypass some of the argument packing and
unpacking on architectures for which it can be avoided. Routines
are provided to emulate the raw API if the underlying platform
doesn't allow faster implementation.
More details on the raw API can be found in:
http://gcc.gnu.org/ml/java/1999-q3/msg00138.html
and
http://gcc.gnu.org/ml/java/1999-q3/msg00174.html
-------------------------------------------------------------------- */
#ifndef LIBFFI_H
#define LIBFFI_H
#ifdef __cplusplus
extern "C" {
#endif
/* Specify which architecture libffi is configured for. */
#ifndef X86_WIN64
#define X86_WIN64
#endif
/* ---- System configuration information --------------------------------- */
/* If these change, update src/mips/ffitarget.h. */
#define FFI_TYPE_VOID 0
#define FFI_TYPE_INT 1
#define FFI_TYPE_FLOAT 2
#define FFI_TYPE_DOUBLE 3
#if 1
#define FFI_TYPE_LONGDOUBLE 4
#else
#define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE
#endif
#define FFI_TYPE_UINT8 5
#define FFI_TYPE_SINT8 6
#define FFI_TYPE_UINT16 7
#define FFI_TYPE_SINT16 8
#define FFI_TYPE_UINT32 9
#define FFI_TYPE_SINT32 10
#define FFI_TYPE_UINT64 11
#define FFI_TYPE_SINT64 12
#define FFI_TYPE_STRUCT 13
#define FFI_TYPE_POINTER 14
#define FFI_TYPE_COMPLEX 15
/* This should always refer to the last type code (for sanity checks). */
#define FFI_TYPE_LAST FFI_TYPE_COMPLEX
#include <ffitarget.h>
#ifndef LIBFFI_ASM
#if defined(_MSC_VER) && !defined(__clang__)
#define __attribute__(X)
#endif
#include <stddef.h>
#include <limits.h>
/* LONG_LONG_MAX is not always defined (not if STRICT_ANSI, for example).
But we can find it either under the correct ANSI name, or under GNU
C's internal name. */
#define FFI_64_BIT_MAX 9223372036854775807
#ifdef LONG_LONG_MAX
# define FFI_LONG_LONG_MAX LONG_LONG_MAX
#else
# ifdef LLONG_MAX
# define FFI_LONG_LONG_MAX LLONG_MAX
# ifdef _AIX52 /* or newer has C99 LLONG_MAX */
# undef FFI_64_BIT_MAX
# define FFI_64_BIT_MAX 9223372036854775807LL
# endif /* _AIX52 or newer */
# else
# ifdef __GNUC__
# define FFI_LONG_LONG_MAX __LONG_LONG_MAX__
# endif
# ifdef _AIX /* AIX 5.1 and earlier have LONGLONG_MAX */
# ifndef __PPC64__
# if defined (__IBMC__) || defined (__IBMCPP__)
# define FFI_LONG_LONG_MAX LONGLONG_MAX
# endif
# endif /* __PPC64__ */
# undef FFI_64_BIT_MAX
# define FFI_64_BIT_MAX 9223372036854775807LL
# endif
# endif
#endif
/* The closure code assumes that this works on pointers, i.e. a size_t
can hold a pointer. */
typedef struct _ffi_type
{
size_t size;
unsigned short alignment;
unsigned short type;
struct _ffi_type **elements;
} ffi_type;
/* Need minimal decorations for DLLs to work on Windows. GCC has
autoimport and autoexport. Always mark externally visible symbols
as dllimport for MSVC clients, even if it means an extra indirection
when using the static version of the library.
Besides, as a workaround, they can define FFI_BUILDING if they
*know* they are going to link with the static library. */
#if defined _MSC_VER
# if defined FFI_BUILDING_DLL /* Building libffi.DLL with msvcc.sh */
# define FFI_API __declspec(dllexport)
# elif !defined FFI_BUILDING /* Importing libffi.DLL */
# define FFI_API __declspec(dllimport)
# else /* Building/linking static library */
# define FFI_API
# endif
#else
# define FFI_API
#endif
/* The externally visible type declarations also need the MSVC DLL
decorations, or they will not be exported from the object file. */
#if defined LIBFFI_HIDE_BASIC_TYPES
# define FFI_EXTERN FFI_API
#else
# define FFI_EXTERN extern FFI_API
#endif
#ifndef LIBFFI_HIDE_BASIC_TYPES
#if SCHAR_MAX == 127
# define ffi_type_uchar ffi_type_uint8
# define ffi_type_schar ffi_type_sint8
#else
#error "char size not supported"
#endif
#if SHRT_MAX == 32767
# define ffi_type_ushort ffi_type_uint16
# define ffi_type_sshort ffi_type_sint16
#elif SHRT_MAX == 2147483647
# define ffi_type_ushort ffi_type_uint32
# define ffi_type_sshort ffi_type_sint32
#else
#error "short size not supported"
#endif
#if INT_MAX == 32767
# define ffi_type_uint ffi_type_uint16
# define ffi_type_sint ffi_type_sint16
#elif INT_MAX == 2147483647
# define ffi_type_uint ffi_type_uint32
# define ffi_type_sint ffi_type_sint32
#elif INT_MAX == 9223372036854775807
# define ffi_type_uint ffi_type_uint64
# define ffi_type_sint ffi_type_sint64
#else
#error "int size not supported"
#endif
#if LONG_MAX == 2147483647
# if FFI_LONG_LONG_MAX != FFI_64_BIT_MAX
#error "no 64-bit data type supported"
# endif
#elif LONG_MAX != FFI_64_BIT_MAX
#error "long size not supported"
#endif
#if LONG_MAX == 2147483647
# define ffi_type_ulong ffi_type_uint32
# define ffi_type_slong ffi_type_sint32
#elif LONG_MAX == FFI_64_BIT_MAX
# define ffi_type_ulong ffi_type_uint64
# define ffi_type_slong ffi_type_sint64
#else
#error "long size not supported"
#endif
/* These are defined in types.c. */
FFI_EXTERN ffi_type ffi_type_void;
FFI_EXTERN ffi_type ffi_type_uint8;
FFI_EXTERN ffi_type ffi_type_sint8;
FFI_EXTERN ffi_type ffi_type_uint16;
FFI_EXTERN ffi_type ffi_type_sint16;
FFI_EXTERN ffi_type ffi_type_uint32;
FFI_EXTERN ffi_type ffi_type_sint32;
FFI_EXTERN ffi_type ffi_type_uint64;
FFI_EXTERN ffi_type ffi_type_sint64;
FFI_EXTERN ffi_type ffi_type_float;
FFI_EXTERN ffi_type ffi_type_double;
FFI_EXTERN ffi_type ffi_type_pointer;
#if 1
FFI_EXTERN ffi_type ffi_type_longdouble;
#else
#define ffi_type_longdouble ffi_type_double
#endif
#ifdef FFI_TARGET_HAS_COMPLEX_TYPE
FFI_EXTERN ffi_type ffi_type_complex_float;
FFI_EXTERN ffi_type ffi_type_complex_double;
#if 1
FFI_EXTERN ffi_type ffi_type_complex_longdouble;
#else
#define ffi_type_complex_longdouble ffi_type_complex_double
#endif
#endif
#endif /* LIBFFI_HIDE_BASIC_TYPES */
typedef enum {
FFI_OK = 0,
FFI_BAD_TYPEDEF,
FFI_BAD_ABI,
FFI_BAD_ARGTYPE
} ffi_status;
typedef struct {
ffi_abi abi;
unsigned nargs;
ffi_type **arg_types;
ffi_type *rtype;
unsigned bytes;
unsigned flags;
#ifdef FFI_EXTRA_CIF_FIELDS
FFI_EXTRA_CIF_FIELDS;
#endif
} ffi_cif;
/* ---- Definitions for the raw API -------------------------------------- */
#ifndef FFI_SIZEOF_ARG
# if LONG_MAX == 2147483647
# define FFI_SIZEOF_ARG 4
# elif LONG_MAX == FFI_64_BIT_MAX
# define FFI_SIZEOF_ARG 8
# endif
#endif
#ifndef FFI_SIZEOF_JAVA_RAW
# define FFI_SIZEOF_JAVA_RAW FFI_SIZEOF_ARG
#endif
typedef union {
ffi_sarg sint;
ffi_arg uint;
float flt;
char data[FFI_SIZEOF_ARG];
void* ptr;
} ffi_raw;
#if FFI_SIZEOF_JAVA_RAW == 4 && FFI_SIZEOF_ARG == 8
/* This is a special case for mips64/n32 ABI (and perhaps others) where
sizeof(void *) is 4 and FFI_SIZEOF_ARG is 8. */
typedef union {
signed int sint;
unsigned int uint;
float flt;
char data[FFI_SIZEOF_JAVA_RAW];
void* ptr;
} ffi_java_raw;
#else
typedef ffi_raw ffi_java_raw;
#endif
FFI_API
void ffi_raw_call (ffi_cif *cif,
void (*fn)(void),
void *rvalue,
ffi_raw *avalue);
FFI_API void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
FFI_API void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
FFI_API size_t ffi_raw_size (ffi_cif *cif);
/* This is analogous to the raw API, except it uses Java parameter
packing, even on 64-bit machines. I.e. on 64-bit machines longs
and doubles are followed by an empty 64-bit word. */
#if !FFI_NATIVE_RAW_API
FFI_API
void ffi_java_raw_call (ffi_cif *cif,
void (*fn)(void),
void *rvalue,
ffi_java_raw *avalue) __attribute__((deprecated));
#endif
FFI_API
void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw) __attribute__((deprecated));
FFI_API
void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args) __attribute__((deprecated));
FFI_API
size_t ffi_java_raw_size (ffi_cif *cif) __attribute__((deprecated));
/* ---- Definitions for closures ----------------------------------------- */
#if FFI_CLOSURES
#ifdef _MSC_VER
__declspec(align(8))
#endif
typedef struct {
#if 0
void *trampoline_table;
void *trampoline_table_entry;
#else
union {
char tramp[FFI_TRAMPOLINE_SIZE];
void *ftramp;
};
#endif
ffi_cif *cif;
void (*fun)(ffi_cif*,void*,void**,void*);
void *user_data;
#if defined(_MSC_VER) && defined(_M_IX86)
void *padding;
#endif
} ffi_closure
#ifdef __GNUC__
__attribute__((aligned (8)))
#endif
;
#ifndef __GNUC__
# ifdef __sgi
# pragma pack 0
# endif
#endif
FFI_API void *ffi_closure_alloc (size_t size, void **code);
FFI_API void ffi_closure_free (void *);
#if defined(PA_LINUX) || defined(PA_HPUX)
#define FFI_CLOSURE_PTR(X) ((void *)((unsigned int)(X) | 2))
#define FFI_RESTORE_PTR(X) ((void *)((unsigned int)(X) & ~3))
#else
#define FFI_CLOSURE_PTR(X) (X)
#define FFI_RESTORE_PTR(X) (X)
#endif
FFI_API ffi_status
ffi_prep_closure (ffi_closure*,
ffi_cif *,
void (*fun)(ffi_cif*,void*,void**,void*),
void *user_data)
#if defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 405)
__attribute__((deprecated ("use ffi_prep_closure_loc instead")))
#elif defined(__GNUC__) && __GNUC__ >= 3
__attribute__((deprecated))
#endif
;
FFI_API ffi_status
ffi_prep_closure_loc (ffi_closure*,
ffi_cif *,
void (*fun)(ffi_cif*,void*,void**,void*),
void *user_data,
void *codeloc);
#ifdef __sgi
# pragma pack 8
#endif
typedef struct {
#if 0
void *trampoline_table;
void *trampoline_table_entry;
#else
char tramp[FFI_TRAMPOLINE_SIZE];
#endif
ffi_cif *cif;
#if !FFI_NATIVE_RAW_API
/* If this is enabled, then a raw closure has the same layout
as a regular closure. We use this to install an intermediate
handler to do the translation, void** -> ffi_raw*. */
void (*translate_args)(ffi_cif*,void*,void**,void*);
void *this_closure;
#endif
void (*fun)(ffi_cif*,void*,ffi_raw*,void*);
void *user_data;
} ffi_raw_closure;
typedef struct {
#if 0
void *trampoline_table;
void *trampoline_table_entry;
#else
char tramp[FFI_TRAMPOLINE_SIZE];
#endif
ffi_cif *cif;
#if !FFI_NATIVE_RAW_API
/* If this is enabled, then a raw closure has the same layout
as a regular closure. We use this to install an intermediate
handler to do the translation, void** -> ffi_raw*. */
void (*translate_args)(ffi_cif*,void*,void**,void*);
void *this_closure;
#endif
void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*);
void *user_data;
} ffi_java_raw_closure;
FFI_API ffi_status
ffi_prep_raw_closure (ffi_raw_closure*,
ffi_cif *cif,
void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
void *user_data);
FFI_API ffi_status
ffi_prep_raw_closure_loc (ffi_raw_closure*,
ffi_cif *cif,
void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
void *user_data,
void *codeloc);
#if !FFI_NATIVE_RAW_API
FFI_API ffi_status
ffi_prep_java_raw_closure (ffi_java_raw_closure*,
ffi_cif *cif,
void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
void *user_data) __attribute__((deprecated));
FFI_API ffi_status
ffi_prep_java_raw_closure_loc (ffi_java_raw_closure*,
ffi_cif *cif,
void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
void *user_data,
void *codeloc) __attribute__((deprecated));
#endif
#endif /* FFI_CLOSURES */
#if FFI_GO_CLOSURES
typedef struct {
void *tramp;
ffi_cif *cif;
void (*fun)(ffi_cif*,void*,void**,void*);
} ffi_go_closure;
FFI_API ffi_status ffi_prep_go_closure (ffi_go_closure*, ffi_cif *,
void (*fun)(ffi_cif*,void*,void**,void*));
FFI_API void ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue,
void **avalue, void *closure);
#endif /* FFI_GO_CLOSURES */
/* ---- Public interface definition -------------------------------------- */
FFI_API
ffi_status ffi_prep_cif(ffi_cif *cif,
ffi_abi abi,
unsigned int nargs,
ffi_type *rtype,
ffi_type **atypes);
FFI_API
ffi_status ffi_prep_cif_var(ffi_cif *cif,
ffi_abi abi,
unsigned int nfixedargs,
unsigned int ntotalargs,
ffi_type *rtype,
ffi_type **atypes);
FFI_API
void ffi_call(ffi_cif *cif,
void (*fn)(void),
void *rvalue,
void **avalue);
FFI_API
ffi_status ffi_get_struct_offsets (ffi_abi abi, ffi_type *struct_type,
size_t *offsets);
/* Useful for eliminating compiler warnings. */
#define FFI_FN(f) ((void (*)(void))f)
/* ---- Definitions shared with assembly code ---------------------------- */
#endif
#ifdef __cplusplus
}
#endif
#endif
+164
View File
@@ -0,0 +1,164 @@
/* -----------------------------------------------------------------*-C-*-
ffitarget.h - Copyright (c) 2012, 2014, 2018 Anthony Green
Copyright (c) 1996-2003, 2010 Red Hat, Inc.
Copyright (C) 2008 Free Software Foundation, Inc.
Target configuration macros for x86 and x86-64.
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.
----------------------------------------------------------------------- */
#ifndef LIBFFI_TARGET_H
#define LIBFFI_TARGET_H
#ifndef LIBFFI_H
#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
#endif
/* ---- System specific configurations ----------------------------------- */
/* For code common to all platforms on x86 and x86_64. */
#define X86_ANY
#if defined (X86_64) && defined (__i386__)
#undef X86_64
#warning ******************************************************
#warning ********** X86 IS DEFINED ****************************
#warning ******************************************************
#define X86
#endif
#ifdef X86_WIN64
#define FFI_SIZEOF_ARG 8
#define USE_BUILTIN_FFS 0 /* not yet implemented in mingw-64 */
#endif
#define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION
#ifndef _MSC_VER
#define FFI_TARGET_HAS_COMPLEX_TYPE
#endif
/* ---- Generic type definitions ----------------------------------------- */
#ifndef LIBFFI_ASM
#ifdef X86_WIN64
#ifdef _MSC_VER
typedef unsigned __int64 ffi_arg;
typedef __int64 ffi_sarg;
#else
typedef unsigned long long ffi_arg;
typedef long long ffi_sarg;
#endif
#else
#if defined __x86_64__ && defined __ILP32__
#define FFI_SIZEOF_ARG 8
#define FFI_SIZEOF_JAVA_RAW 4
typedef unsigned long long ffi_arg;
typedef long long ffi_sarg;
#else
typedef unsigned long ffi_arg;
typedef signed long ffi_sarg;
#endif
#endif
typedef enum ffi_abi {
#if defined(X86_WIN64)
FFI_FIRST_ABI = 0,
FFI_WIN64, /* sizeof(long double) == 8 - microsoft compilers */
FFI_GNUW64, /* sizeof(long double) == 16 - GNU compilers */
FFI_LAST_ABI,
#ifdef __GNUC__
FFI_DEFAULT_ABI = FFI_GNUW64
#else
FFI_DEFAULT_ABI = FFI_WIN64
#endif
#elif defined(X86_64) || (defined (__x86_64__) && defined (X86_DARWIN))
FFI_FIRST_ABI = 1,
FFI_UNIX64,
FFI_WIN64,
FFI_EFI64 = FFI_WIN64,
FFI_GNUW64,
FFI_LAST_ABI,
FFI_DEFAULT_ABI = FFI_UNIX64
#elif defined(X86_WIN32)
FFI_FIRST_ABI = 0,
FFI_SYSV = 1,
FFI_STDCALL = 2,
FFI_THISCALL = 3,
FFI_FASTCALL = 4,
FFI_MS_CDECL = 5,
FFI_PASCAL = 6,
FFI_REGISTER = 7,
FFI_LAST_ABI,
FFI_DEFAULT_ABI = FFI_MS_CDECL
#else
FFI_FIRST_ABI = 0,
FFI_SYSV = 1,
FFI_THISCALL = 3,
FFI_FASTCALL = 4,
FFI_STDCALL = 5,
FFI_PASCAL = 6,
FFI_REGISTER = 7,
FFI_MS_CDECL = 8,
FFI_LAST_ABI,
FFI_DEFAULT_ABI = FFI_SYSV
#endif
} ffi_abi;
#endif
/* ---- Definitions for closures ----------------------------------------- */
#define FFI_CLOSURES 1
#define FFI_GO_CLOSURES 1
#define FFI_TYPE_SMALL_STRUCT_1B (FFI_TYPE_LAST + 1)
#define FFI_TYPE_SMALL_STRUCT_2B (FFI_TYPE_LAST + 2)
#define FFI_TYPE_SMALL_STRUCT_4B (FFI_TYPE_LAST + 3)
#define FFI_TYPE_MS_STRUCT (FFI_TYPE_LAST + 4)
#if defined (X86_64) || defined(X86_WIN64) \
|| (defined (__x86_64__) && defined (X86_DARWIN))
/* 4 bytes of ENDBR64 + 7 bytes of LEA + 6 bytes of JMP + 7 bytes of NOP
+ 8 bytes of pointer. */
# define FFI_TRAMPOLINE_SIZE 32
# define FFI_NATIVE_RAW_API 0
#else
/* 4 bytes of ENDBR32 + 5 bytes of MOV + 5 bytes of JMP + 2 unused
bytes. */
# define FFI_TRAMPOLINE_SIZE 16
# define FFI_NATIVE_RAW_API 1 /* x86 has native raw api support */
#endif
#if !defined(GENERATE_LIBFFI_MAP) && defined(__CET__)
# include <cet.h>
# if (__CET__ & 1) != 0
# define ENDBR_PRESENT
# endif
# define _CET_NOTRACK notrack
#else
# define _CET_ENDBR
# define _CET_NOTRACK
#endif
#endif
@@ -0,0 +1,59 @@
/*
* fontconfig/fontconfig/fcfreetype.h
*
* Copyright © 2001 Keith Packard
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of the author(s) not be used in
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. The authors make no
* representations about the suitability of this software for any purpose. It
* is provided "as is" without express or implied warranty.
*
* THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _FCFREETYPE_H_
#define _FCFREETYPE_H_
#include <ft2build.h>
#include FT_FREETYPE_H
#ifndef FcPublic
#define FcPublic
#endif
_FCFUNCPROTOBEGIN
FcPublic FT_UInt
FcFreeTypeCharIndex (FT_Face face, FcChar32 ucs4);
FcPublic FcCharSet *
FcFreeTypeCharSetAndSpacing (FT_Face face, FcBlanks *blanks, int *spacing);
FcPublic FcCharSet *
FcFreeTypeCharSet (FT_Face face, FcBlanks *blanks);
FcPublic FcResult
FcPatternGetFTFace (const FcPattern *p, const char *object, int n, FT_Face *f);
FcPublic FcBool
FcPatternAddFTFace (FcPattern *p, const char *object, const FT_Face f);
FcPublic FcPattern *
FcFreeTypeQueryFace (const FT_Face face,
const FcChar8 *file,
unsigned int id,
FcBlanks *blanks);
_FCFUNCPROTOEND
#endif
@@ -0,0 +1,134 @@
/*
* fontconfig/fontconfig/fcprivate.h
*
* Copyright © 2001 Keith Packard
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of the author(s) not be used in
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. The authors make no
* representations about the suitability of this software for any purpose. It
* is provided "as is" without express or implied warranty.
*
* THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _FCPRIVATE_H_
#define _FCPRIVATE_H_
/*
* I tried this with functions that took va_list* arguments
* but portability concerns made me change these functions
* into macros (sigh).
*/
#define FcPatternVapBuild(result, orig, va) \
{ \
FcPattern *__p__ = (orig); \
const char *__o__; \
FcValue __v__; \
\
if (!__p__) \
{ \
__p__ = FcPatternCreate (); \
if (!__p__) \
goto _FcPatternVapBuild_bail0; \
} \
for (;;) \
{ \
__o__ = va_arg (va, const char *); \
if (!__o__) \
break; \
__v__.type = va_arg (va, int); \
switch (__v__.type) { \
case FcTypeUnknown: \
case FcTypeVoid: \
goto _FcPatternVapBuild_bail1; \
case FcTypeInteger: \
__v__.u.i = va_arg (va, int); \
break; \
case FcTypeDouble: \
__v__.u.d = va_arg (va, double); \
break; \
case FcTypeString: \
__v__.u.s = va_arg (va, const FcChar8 *); \
break; \
case FcTypeBool: \
__v__.u.b = va_arg (va, FcBool); \
break; \
case FcTypeMatrix: \
__v__.u.m = va_arg (va, const FcMatrix *); \
break; \
case FcTypeCharSet: \
__v__.u.c = va_arg (va, const FcCharSet *); \
break; \
case FcTypeFTFace: \
__v__.u.f = va_arg (va, FT_Face); \
break; \
case FcTypeLangSet: \
__v__.u.l = va_arg (va, const FcLangSet *); \
break; \
case FcTypeRange: \
__v__.u.r = va_arg (va, const FcRange *); \
break; \
} \
if (!FcPatternAdd (__p__, __o__, __v__, FcTrue)) \
goto _FcPatternVapBuild_bail1; \
} \
result = __p__; \
goto _FcPatternVapBuild_return; \
\
_FcPatternVapBuild_bail1: \
if (!orig) \
FcPatternDestroy (__p__); \
_FcPatternVapBuild_bail0: \
result = (void*)0; \
\
_FcPatternVapBuild_return: \
; \
}
#define FcObjectSetVapBuild(__ret__, __first__, __va__) \
{ \
FcObjectSet *__os__; \
const char *__ob__; \
\
__ret__ = 0; \
__os__ = FcObjectSetCreate (); \
if (!__os__) \
goto _FcObjectSetVapBuild_bail0; \
__ob__ = __first__; \
while (__ob__) \
{ \
if (!FcObjectSetAdd (__os__, __ob__)) \
goto _FcObjectSetVapBuild_bail1; \
__ob__ = va_arg (__va__, const char *); \
} \
__ret__ = __os__; \
\
_FcObjectSetVapBuild_bail1: \
if (!__ret__ && __os__) \
FcObjectSetDestroy (__os__); \
_FcObjectSetVapBuild_bail0: \
; \
}
#ifndef FC_ATTRIBUTE_VISIBILITY_HIDDEN
#define FC_ATTRIBUTE_VISIBILITY_HIDDEN __attribute((visibility("hidden")))
#endif
#ifndef FC_ATTRIBUTE_VISIBILITY_EXPORT
#define FC_ATTRIBUTE_VISIBILITY_EXPORT __attribute((visibility("default")))
#endif
#endif /* _FCPRIVATE_H_ */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,51 @@
/****************************************************************************
*
* ftconfig.h
*
* ANSI-specific configuration file (specification only).
*
* Copyright (C) 1996-2023 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
/**************************************************************************
*
* This header file contains a number of macro definitions that are used by
* the rest of the engine. Most of the macros here are automatically
* determined at compile time, and you should not need to change it to port
* FreeType, except to compile the library with a non-ANSI compiler.
*
* Note however that if some specific modifications are needed, we advise
* you to place a modified copy in your build directory.
*
* The build directory is usually `builds/<system>`, and contains
* system-specific files that are always included first when building the
* library.
*
* This ANSI version should stay in `include/config/`.
*
*/
#ifndef FTCONFIG_H_
#define FTCONFIG_H_
#include <ft2build.h>
#include FT_CONFIG_OPTIONS_H
#include FT_CONFIG_STANDARD_LIBRARY_H
#include <freetype/config/integer-types.h>
#include <freetype/config/public-macros.h>
#include <freetype/config/mac-support.h>
#endif /* FTCONFIG_H_ */
/* END */
@@ -0,0 +1,836 @@
/****************************************************************************
*
* ftheader.h
*
* Build macros of the FreeType 2 library.
*
* Copyright (C) 1996-2023 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#ifndef FTHEADER_H_
#define FTHEADER_H_
/*@***********************************************************************/
/* */
/* <Macro> */
/* FT_BEGIN_HEADER */
/* */
/* <Description> */
/* This macro is used in association with @FT_END_HEADER in header */
/* files to ensure that the declarations within are properly */
/* encapsulated in an `extern "C" { .. }` block when included from a */
/* C++ compiler. */
/* */
#ifndef FT_BEGIN_HEADER
# ifdef __cplusplus
# define FT_BEGIN_HEADER extern "C" {
# else
# define FT_BEGIN_HEADER /* nothing */
# endif
#endif
/*@***********************************************************************/
/* */
/* <Macro> */
/* FT_END_HEADER */
/* */
/* <Description> */
/* This macro is used in association with @FT_BEGIN_HEADER in header */
/* files to ensure that the declarations within are properly */
/* encapsulated in an `extern "C" { .. }` block when included from a */
/* C++ compiler. */
/* */
#ifndef FT_END_HEADER
# ifdef __cplusplus
# define FT_END_HEADER }
# else
# define FT_END_HEADER /* nothing */
# endif
#endif
/**************************************************************************
*
* Aliases for the FreeType 2 public and configuration files.
*
*/
/**************************************************************************
*
* @section:
* header_file_macros
*
* @title:
* Header File Macros
*
* @abstract:
* Macro definitions used to `#include` specific header files.
*
* @description:
* In addition to the normal scheme of including header files like
*
* ```
* #include <freetype/freetype.h>
* #include <freetype/ftmm.h>
* #include <freetype/ftglyph.h>
* ```
*
* it is possible to used named macros instead. They can be used
* directly in `#include` statements as in
*
* ```
* #include FT_FREETYPE_H
* #include FT_MULTIPLE_MASTERS_H
* #include FT_GLYPH_H
* ```
*
* These macros were introduced to overcome the infamous 8.3~naming rule
* required by DOS (and `FT_MULTIPLE_MASTERS_H` is a lot more meaningful
* than `ftmm.h`).
*
*/
/* configuration files */
/**************************************************************************
*
* @macro:
* FT_CONFIG_CONFIG_H
*
* @description:
* A macro used in `#include` statements to name the file containing
* FreeType~2 configuration data.
*
*/
#ifndef FT_CONFIG_CONFIG_H
#define FT_CONFIG_CONFIG_H <freetype/config/ftconfig.h>
#endif
/**************************************************************************
*
* @macro:
* FT_CONFIG_STANDARD_LIBRARY_H
*
* @description:
* A macro used in `#include` statements to name the file containing
* FreeType~2 interface to the standard C library functions.
*
*/
#ifndef FT_CONFIG_STANDARD_LIBRARY_H
#define FT_CONFIG_STANDARD_LIBRARY_H <freetype/config/ftstdlib.h>
#endif
/**************************************************************************
*
* @macro:
* FT_CONFIG_OPTIONS_H
*
* @description:
* A macro used in `#include` statements to name the file containing
* FreeType~2 project-specific configuration options.
*
*/
#ifndef FT_CONFIG_OPTIONS_H
#define FT_CONFIG_OPTIONS_H <freetype/config/ftoption.h>
#endif
/**************************************************************************
*
* @macro:
* FT_CONFIG_MODULES_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* list of FreeType~2 modules that are statically linked to new library
* instances in @FT_Init_FreeType.
*
*/
#ifndef FT_CONFIG_MODULES_H
#define FT_CONFIG_MODULES_H <freetype/config/ftmodule.h>
#endif
/* */
/* public headers */
/**************************************************************************
*
* @macro:
* FT_FREETYPE_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* base FreeType~2 API.
*
*/
#define FT_FREETYPE_H <freetype/freetype.h>
/**************************************************************************
*
* @macro:
* FT_ERRORS_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* list of FreeType~2 error codes (and messages).
*
* It is included by @FT_FREETYPE_H.
*
*/
#define FT_ERRORS_H <freetype/fterrors.h>
/**************************************************************************
*
* @macro:
* FT_MODULE_ERRORS_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* list of FreeType~2 module error offsets (and messages).
*
*/
#define FT_MODULE_ERRORS_H <freetype/ftmoderr.h>
/**************************************************************************
*
* @macro:
* FT_SYSTEM_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* FreeType~2 interface to low-level operations (i.e., memory management
* and stream i/o).
*
* It is included by @FT_FREETYPE_H.
*
*/
#define FT_SYSTEM_H <freetype/ftsystem.h>
/**************************************************************************
*
* @macro:
* FT_IMAGE_H
*
* @description:
* A macro used in `#include` statements to name the file containing type
* definitions related to glyph images (i.e., bitmaps, outlines,
* scan-converter parameters).
*
* It is included by @FT_FREETYPE_H.
*
*/
#define FT_IMAGE_H <freetype/ftimage.h>
/**************************************************************************
*
* @macro:
* FT_TYPES_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* basic data types defined by FreeType~2.
*
* It is included by @FT_FREETYPE_H.
*
*/
#define FT_TYPES_H <freetype/fttypes.h>
/**************************************************************************
*
* @macro:
* FT_LIST_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* list management API of FreeType~2.
*
* (Most applications will never need to include this file.)
*
*/
#define FT_LIST_H <freetype/ftlist.h>
/**************************************************************************
*
* @macro:
* FT_OUTLINE_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* scalable outline management API of FreeType~2.
*
*/
#define FT_OUTLINE_H <freetype/ftoutln.h>
/**************************************************************************
*
* @macro:
* FT_SIZES_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* API which manages multiple @FT_Size objects per face.
*
*/
#define FT_SIZES_H <freetype/ftsizes.h>
/**************************************************************************
*
* @macro:
* FT_MODULE_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* module management API of FreeType~2.
*
*/
#define FT_MODULE_H <freetype/ftmodapi.h>
/**************************************************************************
*
* @macro:
* FT_RENDER_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* renderer module management API of FreeType~2.
*
*/
#define FT_RENDER_H <freetype/ftrender.h>
/**************************************************************************
*
* @macro:
* FT_DRIVER_H
*
* @description:
* A macro used in `#include` statements to name the file containing
* structures and macros related to the driver modules.
*
*/
#define FT_DRIVER_H <freetype/ftdriver.h>
/**************************************************************************
*
* @macro:
* FT_AUTOHINTER_H
*
* @description:
* A macro used in `#include` statements to name the file containing
* structures and macros related to the auto-hinting module.
*
* Deprecated since version~2.9; use @FT_DRIVER_H instead.
*
*/
#define FT_AUTOHINTER_H FT_DRIVER_H
/**************************************************************************
*
* @macro:
* FT_CFF_DRIVER_H
*
* @description:
* A macro used in `#include` statements to name the file containing
* structures and macros related to the CFF driver module.
*
* Deprecated since version~2.9; use @FT_DRIVER_H instead.
*
*/
#define FT_CFF_DRIVER_H FT_DRIVER_H
/**************************************************************************
*
* @macro:
* FT_TRUETYPE_DRIVER_H
*
* @description:
* A macro used in `#include` statements to name the file containing
* structures and macros related to the TrueType driver module.
*
* Deprecated since version~2.9; use @FT_DRIVER_H instead.
*
*/
#define FT_TRUETYPE_DRIVER_H FT_DRIVER_H
/**************************************************************************
*
* @macro:
* FT_PCF_DRIVER_H
*
* @description:
* A macro used in `#include` statements to name the file containing
* structures and macros related to the PCF driver module.
*
* Deprecated since version~2.9; use @FT_DRIVER_H instead.
*
*/
#define FT_PCF_DRIVER_H FT_DRIVER_H
/**************************************************************************
*
* @macro:
* FT_TYPE1_TABLES_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* types and API specific to the Type~1 format.
*
*/
#define FT_TYPE1_TABLES_H <freetype/t1tables.h>
/**************************************************************************
*
* @macro:
* FT_TRUETYPE_IDS_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* enumeration values which identify name strings, languages, encodings,
* etc. This file really contains a _large_ set of constant macro
* definitions, taken from the TrueType and OpenType specifications.
*
*/
#define FT_TRUETYPE_IDS_H <freetype/ttnameid.h>
/**************************************************************************
*
* @macro:
* FT_TRUETYPE_TABLES_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* types and API specific to the TrueType (as well as OpenType) format.
*
*/
#define FT_TRUETYPE_TABLES_H <freetype/tttables.h>
/**************************************************************************
*
* @macro:
* FT_TRUETYPE_TAGS_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* definitions of TrueType four-byte 'tags' which identify blocks in
* SFNT-based font formats (i.e., TrueType and OpenType).
*
*/
#define FT_TRUETYPE_TAGS_H <freetype/tttags.h>
/**************************************************************************
*
* @macro:
* FT_BDF_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* definitions of an API which accesses BDF-specific strings from a face.
*
*/
#define FT_BDF_H <freetype/ftbdf.h>
/**************************************************************************
*
* @macro:
* FT_CID_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* definitions of an API which access CID font information from a face.
*
*/
#define FT_CID_H <freetype/ftcid.h>
/**************************************************************************
*
* @macro:
* FT_GZIP_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* definitions of an API which supports gzip-compressed files.
*
*/
#define FT_GZIP_H <freetype/ftgzip.h>
/**************************************************************************
*
* @macro:
* FT_LZW_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* definitions of an API which supports LZW-compressed files.
*
*/
#define FT_LZW_H <freetype/ftlzw.h>
/**************************************************************************
*
* @macro:
* FT_BZIP2_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* definitions of an API which supports bzip2-compressed files.
*
*/
#define FT_BZIP2_H <freetype/ftbzip2.h>
/**************************************************************************
*
* @macro:
* FT_WINFONTS_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* definitions of an API which supports Windows FNT files.
*
*/
#define FT_WINFONTS_H <freetype/ftwinfnt.h>
/**************************************************************************
*
* @macro:
* FT_GLYPH_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* API of the optional glyph management component.
*
*/
#define FT_GLYPH_H <freetype/ftglyph.h>
/**************************************************************************
*
* @macro:
* FT_BITMAP_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* API of the optional bitmap conversion component.
*
*/
#define FT_BITMAP_H <freetype/ftbitmap.h>
/**************************************************************************
*
* @macro:
* FT_BBOX_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* API of the optional exact bounding box computation routines.
*
*/
#define FT_BBOX_H <freetype/ftbbox.h>
/**************************************************************************
*
* @macro:
* FT_CACHE_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* API of the optional FreeType~2 cache sub-system.
*
*/
#define FT_CACHE_H <freetype/ftcache.h>
/**************************************************************************
*
* @macro:
* FT_MAC_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* Macintosh-specific FreeType~2 API. The latter is used to access fonts
* embedded in resource forks.
*
* This header file must be explicitly included by client applications
* compiled on the Mac (note that the base API still works though).
*
*/
#define FT_MAC_H <freetype/ftmac.h>
/**************************************************************************
*
* @macro:
* FT_MULTIPLE_MASTERS_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* optional multiple-masters management API of FreeType~2.
*
*/
#define FT_MULTIPLE_MASTERS_H <freetype/ftmm.h>
/**************************************************************************
*
* @macro:
* FT_SFNT_NAMES_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* optional FreeType~2 API which accesses embedded 'name' strings in
* SFNT-based font formats (i.e., TrueType and OpenType).
*
*/
#define FT_SFNT_NAMES_H <freetype/ftsnames.h>
/**************************************************************************
*
* @macro:
* FT_OPENTYPE_VALIDATE_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* optional FreeType~2 API which validates OpenType tables ('BASE',
* 'GDEF', 'GPOS', 'GSUB', 'JSTF').
*
*/
#define FT_OPENTYPE_VALIDATE_H <freetype/ftotval.h>
/**************************************************************************
*
* @macro:
* FT_GX_VALIDATE_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* optional FreeType~2 API which validates TrueTypeGX/AAT tables ('feat',
* 'mort', 'morx', 'bsln', 'just', 'kern', 'opbd', 'trak', 'prop').
*
*/
#define FT_GX_VALIDATE_H <freetype/ftgxval.h>
/**************************************************************************
*
* @macro:
* FT_PFR_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* FreeType~2 API which accesses PFR-specific data.
*
*/
#define FT_PFR_H <freetype/ftpfr.h>
/**************************************************************************
*
* @macro:
* FT_STROKER_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* FreeType~2 API which provides functions to stroke outline paths.
*/
#define FT_STROKER_H <freetype/ftstroke.h>
/**************************************************************************
*
* @macro:
* FT_SYNTHESIS_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* FreeType~2 API which performs artificial obliquing and emboldening.
*/
#define FT_SYNTHESIS_H <freetype/ftsynth.h>
/**************************************************************************
*
* @macro:
* FT_FONT_FORMATS_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* FreeType~2 API which provides functions specific to font formats.
*/
#define FT_FONT_FORMATS_H <freetype/ftfntfmt.h>
/* deprecated */
#define FT_XFREE86_H FT_FONT_FORMATS_H
/**************************************************************************
*
* @macro:
* FT_TRIGONOMETRY_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* FreeType~2 API which performs trigonometric computations (e.g.,
* cosines and arc tangents).
*/
#define FT_TRIGONOMETRY_H <freetype/fttrigon.h>
/**************************************************************************
*
* @macro:
* FT_LCD_FILTER_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* FreeType~2 API which performs color filtering for subpixel rendering.
*/
#define FT_LCD_FILTER_H <freetype/ftlcdfil.h>
/**************************************************************************
*
* @macro:
* FT_INCREMENTAL_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* FreeType~2 API which performs incremental glyph loading.
*/
#define FT_INCREMENTAL_H <freetype/ftincrem.h>
/**************************************************************************
*
* @macro:
* FT_GASP_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* FreeType~2 API which returns entries from the TrueType GASP table.
*/
#define FT_GASP_H <freetype/ftgasp.h>
/**************************************************************************
*
* @macro:
* FT_ADVANCES_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* FreeType~2 API which returns individual and ranged glyph advances.
*/
#define FT_ADVANCES_H <freetype/ftadvanc.h>
/**************************************************************************
*
* @macro:
* FT_COLOR_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* FreeType~2 API which handles the OpenType 'CPAL' table.
*/
#define FT_COLOR_H <freetype/ftcolor.h>
/**************************************************************************
*
* @macro:
* FT_OTSVG_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* FreeType~2 API which handles the OpenType 'SVG~' glyphs.
*/
#define FT_OTSVG_H <freetype/otsvg.h>
/* */
/* These header files don't need to be included by the user. */
#define FT_ERROR_DEFINITIONS_H <freetype/fterrdef.h>
#define FT_PARAMETER_TAGS_H <freetype/ftparams.h>
/* Deprecated macros. */
#define FT_UNPATENTED_HINTING_H <freetype/ftparams.h>
#define FT_TRUETYPE_UNPATENTED_H <freetype/ftparams.h>
/* `FT_CACHE_H` is the only header file needed for the cache subsystem. */
#define FT_CACHE_IMAGE_H FT_CACHE_H
#define FT_CACHE_SMALL_BITMAPS_H FT_CACHE_H
#define FT_CACHE_CHARMAP_H FT_CACHE_H
/* The internals of the cache sub-system are no longer exposed. We */
/* default to `FT_CACHE_H` at the moment just in case, but we know */
/* of no rogue client that uses them. */
/* */
#define FT_CACHE_MANAGER_H FT_CACHE_H
#define FT_CACHE_INTERNAL_MRU_H FT_CACHE_H
#define FT_CACHE_INTERNAL_MANAGER_H FT_CACHE_H
#define FT_CACHE_INTERNAL_CACHE_H FT_CACHE_H
#define FT_CACHE_INTERNAL_GLYPH_H FT_CACHE_H
#define FT_CACHE_INTERNAL_IMAGE_H FT_CACHE_H
#define FT_CACHE_INTERNAL_SBITS_H FT_CACHE_H
/* TODO(david): Move this section below to a different header */
#ifdef FT2_BUILD_LIBRARY
#if defined( _MSC_VER ) /* Visual C++ (and Intel C++) */
/* We disable the warning `conditional expression is constant' here */
/* in order to compile cleanly with the maximum level of warnings. */
/* In particular, the warning complains about stuff like `while(0)' */
/* which is very useful in macro definitions. There is no benefit */
/* in having it enabled. */
#pragma warning( disable : 4127 )
#endif /* _MSC_VER */
#endif /* FT2_BUILD_LIBRARY */
#endif /* FTHEADER_H_ */
/* END */
@@ -0,0 +1,21 @@
/* This is a generated file. */
FT_USE_MODULE( FT_Driver_ClassRec, tt_driver_class )
FT_USE_MODULE( FT_Driver_ClassRec, t1_driver_class )
FT_USE_MODULE( FT_Driver_ClassRec, cff_driver_class )
FT_USE_MODULE( FT_Driver_ClassRec, t1cid_driver_class )
FT_USE_MODULE( FT_Driver_ClassRec, pfr_driver_class )
FT_USE_MODULE( FT_Driver_ClassRec, t42_driver_class )
FT_USE_MODULE( FT_Driver_ClassRec, winfnt_driver_class )
FT_USE_MODULE( FT_Driver_ClassRec, pcf_driver_class )
FT_USE_MODULE( FT_Driver_ClassRec, bdf_driver_class )
FT_USE_MODULE( FT_Module_Class, sfnt_module_class )
FT_USE_MODULE( FT_Module_Class, autofit_module_class )
FT_USE_MODULE( FT_Module_Class, pshinter_module_class )
FT_USE_MODULE( FT_Renderer_Class, ft_smooth_renderer_class )
FT_USE_MODULE( FT_Renderer_Class, ft_raster1_renderer_class )
FT_USE_MODULE( FT_Renderer_Class, ft_svg_renderer_class )
FT_USE_MODULE( FT_Renderer_Class, ft_sdf_renderer_class )
FT_USE_MODULE( FT_Renderer_Class, ft_bitmap_sdf_renderer_class )
FT_USE_MODULE( FT_Module_Class, psaux_module_class )
FT_USE_MODULE( FT_Module_Class, psnames_module_class )
/* EOF */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,185 @@
/****************************************************************************
*
* ftstdlib.h
*
* ANSI-specific library and header configuration file (specification
* only).
*
* Copyright (C) 2002-2023 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
/**************************************************************************
*
* This file is used to group all `#includes` to the ANSI~C library that
* FreeType normally requires. It also defines macros to rename the
* standard functions within the FreeType source code.
*
* Load a file which defines `FTSTDLIB_H_` before this one to override it.
*
*/
#ifndef FTSTDLIB_H_
#define FTSTDLIB_H_
#include <stddef.h>
#define ft_ptrdiff_t ptrdiff_t
/**************************************************************************
*
* integer limits
*
* `UINT_MAX` and `ULONG_MAX` are used to automatically compute the size of
* `int` and `long` in bytes at compile-time. So far, this works for all
* platforms the library has been tested on. We also check `ULLONG_MAX`
* to see whether we can use 64-bit `long long` later on.
*
* Note that on the extremely rare platforms that do not provide integer
* types that are _exactly_ 16 and 32~bits wide (e.g., some old Crays where
* `int` is 36~bits), we do not make any guarantee about the correct
* behaviour of FreeType~2 with all fonts.
*
* In these cases, `ftconfig.h` will refuse to compile anyway with a
* message like 'couldn't find 32-bit type' or something similar.
*
*/
#include <limits.h>
#define FT_CHAR_BIT CHAR_BIT
#define FT_USHORT_MAX USHRT_MAX
#define FT_INT_MAX INT_MAX
#define FT_INT_MIN INT_MIN
#define FT_UINT_MAX UINT_MAX
#define FT_LONG_MIN LONG_MIN
#define FT_LONG_MAX LONG_MAX
#define FT_ULONG_MAX ULONG_MAX
#ifdef LLONG_MAX
#define FT_LLONG_MAX LLONG_MAX
#endif
#ifdef LLONG_MIN
#define FT_LLONG_MIN LLONG_MIN
#endif
#ifdef ULLONG_MAX
#define FT_ULLONG_MAX ULLONG_MAX
#endif
/**************************************************************************
*
* character and string processing
*
*/
#include <string.h>
#define ft_memchr memchr
#define ft_memcmp memcmp
#define ft_memcpy memcpy
#define ft_memmove memmove
#define ft_memset memset
#define ft_strcat strcat
#define ft_strcmp strcmp
#define ft_strcpy strcpy
#define ft_strlen strlen
#define ft_strncmp strncmp
#define ft_strncpy strncpy
#define ft_strrchr strrchr
#define ft_strstr strstr
/**************************************************************************
*
* file handling
*
*/
#include <stdio.h>
#define FT_FILE FILE
#define ft_fclose fclose
#define ft_fopen fopen
#define ft_fread fread
#define ft_fseek fseek
#define ft_ftell ftell
#define ft_snprintf snprintf
/**************************************************************************
*
* sorting
*
*/
#include <stdlib.h>
#define ft_qsort qsort
/**************************************************************************
*
* memory allocation
*
*/
#define ft_scalloc calloc
#define ft_sfree free
#define ft_smalloc malloc
#define ft_srealloc realloc
/**************************************************************************
*
* miscellaneous
*
*/
#define ft_strtol strtol
#define ft_getenv getenv
/**************************************************************************
*
* execution control
*
*/
#include <setjmp.h>
#define ft_jmp_buf jmp_buf /* note: this cannot be a typedef since */
/* `jmp_buf` is defined as a macro */
/* on certain platforms */
#define ft_longjmp longjmp
#define ft_setjmp( b ) setjmp( *(ft_jmp_buf*) &(b) ) /* same thing here */
/* The following is only used for debugging purposes, i.e., if */
/* `FT_DEBUG_LEVEL_ERROR` or `FT_DEBUG_LEVEL_TRACE` are defined. */
#include <stdarg.h>
#endif /* FTSTDLIB_H_ */
/* END */
@@ -0,0 +1,250 @@
/****************************************************************************
*
* config/integer-types.h
*
* FreeType integer types definitions.
*
* Copyright (C) 1996-2023 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#ifndef FREETYPE_CONFIG_INTEGER_TYPES_H_
#define FREETYPE_CONFIG_INTEGER_TYPES_H_
/* There are systems (like the Texas Instruments 'C54x) where a `char` */
/* has 16~bits. ANSI~C says that `sizeof(char)` is always~1. Since an */
/* `int` has 16~bits also for this system, `sizeof(int)` gives~1 which */
/* is probably unexpected. */
/* */
/* `CHAR_BIT` (defined in `limits.h`) gives the number of bits in a */
/* `char` type. */
#ifndef FT_CHAR_BIT
#define FT_CHAR_BIT CHAR_BIT
#endif
#ifndef FT_SIZEOF_INT
/* The size of an `int` type. */
#if FT_UINT_MAX == 0xFFFFUL
#define FT_SIZEOF_INT ( 16 / FT_CHAR_BIT )
#elif FT_UINT_MAX == 0xFFFFFFFFUL
#define FT_SIZEOF_INT ( 32 / FT_CHAR_BIT )
#elif FT_UINT_MAX > 0xFFFFFFFFUL && FT_UINT_MAX == 0xFFFFFFFFFFFFFFFFUL
#define FT_SIZEOF_INT ( 64 / FT_CHAR_BIT )
#else
#error "Unsupported size of `int' type!"
#endif
#endif /* !defined(FT_SIZEOF_INT) */
#ifndef FT_SIZEOF_LONG
/* The size of a `long` type. A five-byte `long` (as used e.g. on the */
/* DM642) is recognized but avoided. */
#if FT_ULONG_MAX == 0xFFFFFFFFUL
#define FT_SIZEOF_LONG ( 32 / FT_CHAR_BIT )
#elif FT_ULONG_MAX > 0xFFFFFFFFUL && FT_ULONG_MAX == 0xFFFFFFFFFFUL
#define FT_SIZEOF_LONG ( 32 / FT_CHAR_BIT )
#elif FT_ULONG_MAX > 0xFFFFFFFFUL && FT_ULONG_MAX == 0xFFFFFFFFFFFFFFFFUL
#define FT_SIZEOF_LONG ( 64 / FT_CHAR_BIT )
#else
#error "Unsupported size of `long' type!"
#endif
#endif /* !defined(FT_SIZEOF_LONG) */
#ifndef FT_SIZEOF_LONG_LONG
/* The size of a `long long` type if available */
#if defined( FT_ULLONG_MAX ) && FT_ULLONG_MAX >= 0xFFFFFFFFFFFFFFFFULL
#define FT_SIZEOF_LONG_LONG ( 64 / FT_CHAR_BIT )
#else
#define FT_SIZEOF_LONG_LONG 0
#endif
#endif /* !defined(FT_SIZEOF_LONG_LONG) */
/**************************************************************************
*
* @section:
* basic_types
*
*/
/**************************************************************************
*
* @type:
* FT_Int16
*
* @description:
* A typedef for a 16bit signed integer type.
*/
typedef signed short FT_Int16;
/**************************************************************************
*
* @type:
* FT_UInt16
*
* @description:
* A typedef for a 16bit unsigned integer type.
*/
typedef unsigned short FT_UInt16;
/* */
/* this #if 0 ... #endif clause is for documentation purposes */
#if 0
/**************************************************************************
*
* @type:
* FT_Int32
*
* @description:
* A typedef for a 32bit signed integer type. The size depends on the
* configuration.
*/
typedef signed XXX FT_Int32;
/**************************************************************************
*
* @type:
* FT_UInt32
*
* A typedef for a 32bit unsigned integer type. The size depends on the
* configuration.
*/
typedef unsigned XXX FT_UInt32;
/**************************************************************************
*
* @type:
* FT_Int64
*
* A typedef for a 64bit signed integer type. The size depends on the
* configuration. Only defined if there is real 64bit support;
* otherwise, it gets emulated with a structure (if necessary).
*/
typedef signed XXX FT_Int64;
/**************************************************************************
*
* @type:
* FT_UInt64
*
* A typedef for a 64bit unsigned integer type. The size depends on the
* configuration. Only defined if there is real 64bit support;
* otherwise, it gets emulated with a structure (if necessary).
*/
typedef unsigned XXX FT_UInt64;
/* */
#endif
#if FT_SIZEOF_INT == ( 32 / FT_CHAR_BIT )
typedef signed int FT_Int32;
typedef unsigned int FT_UInt32;
#elif FT_SIZEOF_LONG == ( 32 / FT_CHAR_BIT )
typedef signed long FT_Int32;
typedef unsigned long FT_UInt32;
#else
#error "no 32bit type found -- please check your configuration files"
#endif
/* look up an integer type that is at least 32~bits */
#if FT_SIZEOF_INT >= ( 32 / FT_CHAR_BIT )
typedef int FT_Fast;
typedef unsigned int FT_UFast;
#elif FT_SIZEOF_LONG >= ( 32 / FT_CHAR_BIT )
typedef long FT_Fast;
typedef unsigned long FT_UFast;
#endif
/* determine whether we have a 64-bit integer type */
#if FT_SIZEOF_LONG == ( 64 / FT_CHAR_BIT )
#define FT_INT64 long
#define FT_UINT64 unsigned long
#elif FT_SIZEOF_LONG_LONG >= ( 64 / FT_CHAR_BIT )
#define FT_INT64 long long int
#define FT_UINT64 unsigned long long int
/**************************************************************************
*
* A 64-bit data type may create compilation problems if you compile in
* strict ANSI mode. To avoid them, we disable other 64-bit data types if
* `__STDC__` is defined. You can however ignore this rule by defining the
* `FT_CONFIG_OPTION_FORCE_INT64` configuration macro.
*/
#elif !defined( __STDC__ ) || defined( FT_CONFIG_OPTION_FORCE_INT64 )
#if defined( _MSC_VER ) && _MSC_VER >= 900 /* Visual C++ (and Intel C++) */
/* this compiler provides the `__int64` type */
#define FT_INT64 __int64
#define FT_UINT64 unsigned __int64
#elif defined( __BORLANDC__ ) /* Borland C++ */
/* XXXX: We should probably check the value of `__BORLANDC__` in order */
/* to test the compiler version. */
/* this compiler provides the `__int64` type */
#define FT_INT64 __int64
#define FT_UINT64 unsigned __int64
#elif defined( __WATCOMC__ ) && __WATCOMC__ >= 1100 /* Watcom C++ */
#define FT_INT64 long long int
#define FT_UINT64 unsigned long long int
#elif defined( __MWERKS__ ) /* Metrowerks CodeWarrior */
#define FT_INT64 long long int
#define FT_UINT64 unsigned long long int
#elif defined( __GNUC__ )
/* GCC provides the `long long` type */
#define FT_INT64 long long int
#define FT_UINT64 unsigned long long int
#endif /* !__STDC__ */
#endif /* FT_SIZEOF_LONG == (64 / FT_CHAR_BIT) */
#ifdef FT_INT64
typedef FT_INT64 FT_Int64;
typedef FT_UINT64 FT_UInt64;
#endif
#endif /* FREETYPE_CONFIG_INTEGER_TYPES_H_ */
@@ -0,0 +1,49 @@
/****************************************************************************
*
* config/mac-support.h
*
* Mac/OS X support configuration header.
*
* Copyright (C) 1996-2023 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#ifndef FREETYPE_CONFIG_MAC_SUPPORT_H_
#define FREETYPE_CONFIG_MAC_SUPPORT_H_
/**************************************************************************
*
* Mac support
*
* This is the only necessary change, so it is defined here instead
* providing a new configuration file.
*/
#if defined( __APPLE__ ) || ( defined( __MWERKS__ ) && defined( macintosh ) )
/* No Carbon frameworks for 64bit 10.4.x. */
/* `AvailabilityMacros.h` is available since Mac OS X 10.2, */
/* so guess the system version by maximum errno before inclusion. */
#include <errno.h>
#ifdef ECANCELED /* defined since 10.2 */
#include "AvailabilityMacros.h"
#endif
#if defined( __LP64__ ) && \
( MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 )
#undef FT_MACINTOSH
#endif
#elif defined( __SC__ ) || defined( __MRC__ )
/* Classic MacOS compilers */
#include "ConditionalMacros.h"
#if TARGET_OS_MAC
#define FT_MACINTOSH 1
#endif
#endif /* Mac support */
#endif /* FREETYPE_CONFIG_MAC_SUPPORT_H_ */
@@ -0,0 +1,138 @@
/****************************************************************************
*
* config/public-macros.h
*
* Define a set of compiler macros used in public FreeType headers.
*
* Copyright (C) 2020-2023 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
/*
* The definitions in this file are used by the public FreeType headers
* and thus should be considered part of the public API.
*
* Other compiler-specific macro definitions that are not exposed by the
* FreeType API should go into
* `include/freetype/internal/compiler-macros.h` instead.
*/
#ifndef FREETYPE_CONFIG_PUBLIC_MACROS_H_
#define FREETYPE_CONFIG_PUBLIC_MACROS_H_
/*
* `FT_BEGIN_HEADER` and `FT_END_HEADER` might have already been defined
* by `freetype/config/ftheader.h`, but we don't want to include this
* header here, so redefine the macros here only when needed. Their
* definition is very stable, so keeping them in sync with the ones in the
* header should not be a maintenance issue.
*/
#ifndef FT_BEGIN_HEADER
#ifdef __cplusplus
#define FT_BEGIN_HEADER extern "C" {
#else
#define FT_BEGIN_HEADER /* empty */
#endif
#endif /* FT_BEGIN_HEADER */
#ifndef FT_END_HEADER
#ifdef __cplusplus
#define FT_END_HEADER }
#else
#define FT_END_HEADER /* empty */
#endif
#endif /* FT_END_HEADER */
FT_BEGIN_HEADER
/*
* Mark a function declaration as public. This ensures it will be
* properly exported to client code. Place this before a function
* declaration.
*
* NOTE: This macro should be considered an internal implementation
* detail, and not part of the FreeType API. It is only defined here
* because it is needed by `FT_EXPORT`.
*/
/* Visual C, mingw */
#if defined( _WIN32 )
#if defined( FT2_BUILD_LIBRARY ) && defined( DLL_EXPORT )
#define FT_PUBLIC_FUNCTION_ATTRIBUTE __declspec( dllexport )
#elif defined( DLL_IMPORT )
#define FT_PUBLIC_FUNCTION_ATTRIBUTE __declspec( dllimport )
#endif
/* gcc, clang */
#elif ( defined( __GNUC__ ) && __GNUC__ >= 4 ) || defined( __clang__ )
#define FT_PUBLIC_FUNCTION_ATTRIBUTE \
__attribute__(( visibility( "default" ) ))
/* Sun */
#elif defined( __SUNPRO_C ) && __SUNPRO_C >= 0x550
#define FT_PUBLIC_FUNCTION_ATTRIBUTE __global
#endif
#ifndef FT_PUBLIC_FUNCTION_ATTRIBUTE
#define FT_PUBLIC_FUNCTION_ATTRIBUTE /* empty */
#endif
/*
* Define a public FreeType API function. This ensures it is properly
* exported or imported at build time. The macro parameter is the
* function's return type as in:
*
* FT_EXPORT( FT_Bool )
* FT_Object_Method( FT_Object obj,
* ... );
*
* NOTE: This requires that all `FT_EXPORT` uses are inside
* `FT_BEGIN_HEADER ... FT_END_HEADER` blocks. This guarantees that the
* functions are exported with C linkage, even when the header is included
* by a C++ source file.
*/
#define FT_EXPORT( x ) FT_PUBLIC_FUNCTION_ATTRIBUTE extern x
/*
* `FT_UNUSED` indicates that a given parameter is not used -- this is
* only used to get rid of unpleasant compiler warnings.
*
* Technically, this was not meant to be part of the public API, but some
* third-party code depends on it.
*/
#ifndef FT_UNUSED
#define FT_UNUSED( arg ) ( (arg) = (arg) )
#endif
/*
* Support for casts in both C and C++.
*/
#ifdef __cplusplus
#define FT_STATIC_CAST( type, var ) static_cast<type>(var)
#define FT_REINTERPRET_CAST( type, var ) reinterpret_cast<type>(var)
#define FT_STATIC_BYTE_CAST( type, var ) \
static_cast<type>( static_cast<unsigned char>( var ) )
#else
#define FT_STATIC_CAST( type, var ) (type)(var)
#define FT_REINTERPRET_CAST( type, var ) (type)(var)
#define FT_STATIC_BYTE_CAST( type, var ) (type)(unsigned char)(var)
#endif
FT_END_HEADER
#endif /* FREETYPE_CONFIG_PUBLIC_MACROS_H_ */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,188 @@
/****************************************************************************
*
* ftadvanc.h
*
* Quick computation of advance widths (specification only).
*
* Copyright (C) 2008-2023 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#ifndef FTADVANC_H_
#define FTADVANC_H_
#include <freetype/freetype.h>
#ifdef FREETYPE_H
#error "freetype.h of FreeType 1 has been loaded!"
#error "Please fix the directory search order for header files"
#error "so that freetype.h of FreeType 2 is found first."
#endif
FT_BEGIN_HEADER
/**************************************************************************
*
* @section:
* quick_advance
*
* @title:
* Quick retrieval of advance values
*
* @abstract:
* Retrieve horizontal and vertical advance values without processing
* glyph outlines, if possible.
*
* @description:
* This section contains functions to quickly extract advance values
* without handling glyph outlines, if possible.
*
* @order:
* FT_Get_Advance
* FT_Get_Advances
*
*/
/**************************************************************************
*
* @enum:
* FT_ADVANCE_FLAG_FAST_ONLY
*
* @description:
* A bit-flag to be OR-ed with the `flags` parameter of the
* @FT_Get_Advance and @FT_Get_Advances functions.
*
* If set, it indicates that you want these functions to fail if the
* corresponding hinting mode or font driver doesn't allow for very quick
* advance computation.
*
* Typically, glyphs that are either unscaled, unhinted, bitmapped, or
* light-hinted can have their advance width computed very quickly.
*
* Normal and bytecode hinted modes that require loading, scaling, and
* hinting of the glyph outline, are extremely slow by comparison.
*/
#define FT_ADVANCE_FLAG_FAST_ONLY 0x20000000L
/**************************************************************************
*
* @function:
* FT_Get_Advance
*
* @description:
* Retrieve the advance value of a given glyph outline in an @FT_Face.
*
* @input:
* face ::
* The source @FT_Face handle.
*
* gindex ::
* The glyph index.
*
* load_flags ::
* A set of bit flags similar to those used when calling
* @FT_Load_Glyph, used to determine what kind of advances you need.
*
* @output:
* padvance ::
* The advance value. If scaling is performed (based on the value of
* `load_flags`), the advance value is in 16.16 format. Otherwise, it
* is in font units.
*
* If @FT_LOAD_VERTICAL_LAYOUT is set, this is the vertical advance
* corresponding to a vertical layout. Otherwise, it is the horizontal
* advance in a horizontal layout.
*
* @return:
* FreeType error code. 0 means success.
*
* @note:
* This function may fail if you use @FT_ADVANCE_FLAG_FAST_ONLY and if
* the corresponding font backend doesn't have a quick way to retrieve
* the advances.
*
* A scaled advance is returned in 16.16 format but isn't transformed by
* the affine transformation specified by @FT_Set_Transform.
*/
FT_EXPORT( FT_Error )
FT_Get_Advance( FT_Face face,
FT_UInt gindex,
FT_Int32 load_flags,
FT_Fixed *padvance );
/**************************************************************************
*
* @function:
* FT_Get_Advances
*
* @description:
* Retrieve the advance values of several glyph outlines in an @FT_Face.
*
* @input:
* face ::
* The source @FT_Face handle.
*
* start ::
* The first glyph index.
*
* count ::
* The number of advance values you want to retrieve.
*
* load_flags ::
* A set of bit flags similar to those used when calling
* @FT_Load_Glyph.
*
* @output:
* padvance ::
* The advance values. This array, to be provided by the caller, must
* contain at least `count` elements.
*
* If scaling is performed (based on the value of `load_flags`), the
* advance values are in 16.16 format. Otherwise, they are in font
* units.
*
* If @FT_LOAD_VERTICAL_LAYOUT is set, these are the vertical advances
* corresponding to a vertical layout. Otherwise, they are the
* horizontal advances in a horizontal layout.
*
* @return:
* FreeType error code. 0 means success.
*
* @note:
* This function may fail if you use @FT_ADVANCE_FLAG_FAST_ONLY and if
* the corresponding font backend doesn't have a quick way to retrieve
* the advances.
*
* Scaled advances are returned in 16.16 format but aren't transformed by
* the affine transformation specified by @FT_Set_Transform.
*/
FT_EXPORT( FT_Error )
FT_Get_Advances( FT_Face face,
FT_UInt start,
FT_UInt count,
FT_Int32 load_flags,
FT_Fixed *padvances );
/* */
FT_END_HEADER
#endif /* FTADVANC_H_ */
/* END */
@@ -0,0 +1,101 @@
/****************************************************************************
*
* ftbbox.h
*
* FreeType exact bbox computation (specification).
*
* Copyright (C) 1996-2023 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
/**************************************************************************
*
* This component has a _single_ role: to compute exact outline bounding
* boxes.
*
* It is separated from the rest of the engine for various technical
* reasons. It may well be integrated in 'ftoutln' later.
*
*/
#ifndef FTBBOX_H_
#define FTBBOX_H_
#include <freetype/freetype.h>
#ifdef FREETYPE_H
#error "freetype.h of FreeType 1 has been loaded!"
#error "Please fix the directory search order for header files"
#error "so that freetype.h of FreeType 2 is found first."
#endif
FT_BEGIN_HEADER
/**************************************************************************
*
* @section:
* outline_processing
*
*/
/**************************************************************************
*
* @function:
* FT_Outline_Get_BBox
*
* @description:
* Compute the exact bounding box of an outline. This is slower than
* computing the control box. However, it uses an advanced algorithm
* that returns _very_ quickly when the two boxes coincide. Otherwise,
* the outline Bezier arcs are traversed to extract their extrema.
*
* @input:
* outline ::
* A pointer to the source outline.
*
* @output:
* abbox ::
* The outline's exact bounding box.
*
* @return:
* FreeType error code. 0~means success.
*
* @note:
* If the font is tricky and the glyph has been loaded with
* @FT_LOAD_NO_SCALE, the resulting BBox is meaningless. To get
* reasonable values for the BBox it is necessary to load the glyph at a
* large ppem value (so that the hinting instructions can properly shift
* and scale the subglyphs), then extracting the BBox, which can be
* eventually converted back to font units.
*/
FT_EXPORT( FT_Error )
FT_Outline_Get_BBox( FT_Outline* outline,
FT_BBox *abbox );
/* */
FT_END_HEADER
#endif /* FTBBOX_H_ */
/* END */
/* Local Variables: */
/* coding: utf-8 */
/* End: */
@@ -0,0 +1,212 @@
/****************************************************************************
*
* ftbdf.h
*
* FreeType API for accessing BDF-specific strings (specification).
*
* Copyright (C) 2002-2023 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#ifndef FTBDF_H_
#define FTBDF_H_
#include <freetype/freetype.h>
#ifdef FREETYPE_H
#error "freetype.h of FreeType 1 has been loaded!"
#error "Please fix the directory search order for header files"
#error "so that freetype.h of FreeType 2 is found first."
#endif
FT_BEGIN_HEADER
/**************************************************************************
*
* @section:
* bdf_fonts
*
* @title:
* BDF and PCF Files
*
* @abstract:
* BDF and PCF specific API.
*
* @description:
* This section contains the declaration of functions specific to BDF and
* PCF fonts.
*
*/
/**************************************************************************
*
* @enum:
* BDF_PropertyType
*
* @description:
* A list of BDF property types.
*
* @values:
* BDF_PROPERTY_TYPE_NONE ::
* Value~0 is used to indicate a missing property.
*
* BDF_PROPERTY_TYPE_ATOM ::
* Property is a string atom.
*
* BDF_PROPERTY_TYPE_INTEGER ::
* Property is a 32-bit signed integer.
*
* BDF_PROPERTY_TYPE_CARDINAL ::
* Property is a 32-bit unsigned integer.
*/
typedef enum BDF_PropertyType_
{
BDF_PROPERTY_TYPE_NONE = 0,
BDF_PROPERTY_TYPE_ATOM = 1,
BDF_PROPERTY_TYPE_INTEGER = 2,
BDF_PROPERTY_TYPE_CARDINAL = 3
} BDF_PropertyType;
/**************************************************************************
*
* @type:
* BDF_Property
*
* @description:
* A handle to a @BDF_PropertyRec structure to model a given BDF/PCF
* property.
*/
typedef struct BDF_PropertyRec_* BDF_Property;
/**************************************************************************
*
* @struct:
* BDF_PropertyRec
*
* @description:
* This structure models a given BDF/PCF property.
*
* @fields:
* type ::
* The property type.
*
* u.atom ::
* The atom string, if type is @BDF_PROPERTY_TYPE_ATOM. May be
* `NULL`, indicating an empty string.
*
* u.integer ::
* A signed integer, if type is @BDF_PROPERTY_TYPE_INTEGER.
*
* u.cardinal ::
* An unsigned integer, if type is @BDF_PROPERTY_TYPE_CARDINAL.
*/
typedef struct BDF_PropertyRec_
{
BDF_PropertyType type;
union {
const char* atom;
FT_Int32 integer;
FT_UInt32 cardinal;
} u;
} BDF_PropertyRec;
/**************************************************************************
*
* @function:
* FT_Get_BDF_Charset_ID
*
* @description:
* Retrieve a BDF font character set identity, according to the BDF
* specification.
*
* @input:
* face ::
* A handle to the input face.
*
* @output:
* acharset_encoding ::
* Charset encoding, as a C~string, owned by the face.
*
* acharset_registry ::
* Charset registry, as a C~string, owned by the face.
*
* @return:
* FreeType error code. 0~means success.
*
* @note:
* This function only works with BDF faces, returning an error otherwise.
*/
FT_EXPORT( FT_Error )
FT_Get_BDF_Charset_ID( FT_Face face,
const char* *acharset_encoding,
const char* *acharset_registry );
/**************************************************************************
*
* @function:
* FT_Get_BDF_Property
*
* @description:
* Retrieve a BDF property from a BDF or PCF font file.
*
* @input:
* face ::
* A handle to the input face.
*
* name ::
* The property name.
*
* @output:
* aproperty ::
* The property.
*
* @return:
* FreeType error code. 0~means success.
*
* @note:
* This function works with BDF _and_ PCF fonts. It returns an error
* otherwise. It also returns an error if the property is not in the
* font.
*
* A 'property' is a either key-value pair within the STARTPROPERTIES
* ... ENDPROPERTIES block of a BDF font or a key-value pair from the
* `info->props` array within a `FontRec` structure of a PCF font.
*
* Integer properties are always stored as 'signed' within PCF fonts;
* consequently, @BDF_PROPERTY_TYPE_CARDINAL is a possible return value
* for BDF fonts only.
*
* In case of error, `aproperty->type` is always set to
* @BDF_PROPERTY_TYPE_NONE.
*/
FT_EXPORT( FT_Error )
FT_Get_BDF_Property( FT_Face face,
const char* prop_name,
BDF_PropertyRec *aproperty );
/* */
FT_END_HEADER
#endif /* FTBDF_H_ */
/* END */
@@ -0,0 +1,329 @@
/****************************************************************************
*
* ftbitmap.h
*
* FreeType utility functions for bitmaps (specification).
*
* Copyright (C) 2004-2023 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#ifndef FTBITMAP_H_
#define FTBITMAP_H_
#include <freetype/freetype.h>
#include <freetype/ftcolor.h>
#ifdef FREETYPE_H
#error "freetype.h of FreeType 1 has been loaded!"
#error "Please fix the directory search order for header files"
#error "so that freetype.h of FreeType 2 is found first."
#endif
FT_BEGIN_HEADER
/**************************************************************************
*
* @section:
* bitmap_handling
*
* @title:
* Bitmap Handling
*
* @abstract:
* Handling FT_Bitmap objects.
*
* @description:
* This section contains functions for handling @FT_Bitmap objects,
* automatically adjusting the target's bitmap buffer size as needed.
*
* Note that none of the functions changes the bitmap's 'flow' (as
* indicated by the sign of the `pitch` field in @FT_Bitmap).
*
* To set the flow, assign an appropriate positive or negative value to
* the `pitch` field of the target @FT_Bitmap object after calling
* @FT_Bitmap_Init but before calling any of the other functions
* described here.
*/
/**************************************************************************
*
* @function:
* FT_Bitmap_Init
*
* @description:
* Initialize a pointer to an @FT_Bitmap structure.
*
* @inout:
* abitmap ::
* A pointer to the bitmap structure.
*
* @note:
* A deprecated name for the same function is `FT_Bitmap_New`.
*/
FT_EXPORT( void )
FT_Bitmap_Init( FT_Bitmap *abitmap );
/* deprecated */
FT_EXPORT( void )
FT_Bitmap_New( FT_Bitmap *abitmap );
/**************************************************************************
*
* @function:
* FT_Bitmap_Copy
*
* @description:
* Copy a bitmap into another one.
*
* @input:
* library ::
* A handle to a library object.
*
* source ::
* A handle to the source bitmap.
*
* @output:
* target ::
* A handle to the target bitmap.
*
* @return:
* FreeType error code. 0~means success.
*
* @note:
* `source->buffer` and `target->buffer` must neither be equal nor
* overlap.
*/
FT_EXPORT( FT_Error )
FT_Bitmap_Copy( FT_Library library,
const FT_Bitmap *source,
FT_Bitmap *target );
/**************************************************************************
*
* @function:
* FT_Bitmap_Embolden
*
* @description:
* Embolden a bitmap. The new bitmap will be about `xStrength` pixels
* wider and `yStrength` pixels higher. The left and bottom borders are
* kept unchanged.
*
* @input:
* library ::
* A handle to a library object.
*
* xStrength ::
* How strong the glyph is emboldened horizontally. Expressed in 26.6
* pixel format.
*
* yStrength ::
* How strong the glyph is emboldened vertically. Expressed in 26.6
* pixel format.
*
* @inout:
* bitmap ::
* A handle to the target bitmap.
*
* @return:
* FreeType error code. 0~means success.
*
* @note:
* The current implementation restricts `xStrength` to be less than or
* equal to~8 if bitmap is of pixel_mode @FT_PIXEL_MODE_MONO.
*
* If you want to embolden the bitmap owned by a @FT_GlyphSlotRec, you
* should call @FT_GlyphSlot_Own_Bitmap on the slot first.
*
* Bitmaps in @FT_PIXEL_MODE_GRAY2 and @FT_PIXEL_MODE_GRAY@ format are
* converted to @FT_PIXEL_MODE_GRAY format (i.e., 8bpp).
*/
FT_EXPORT( FT_Error )
FT_Bitmap_Embolden( FT_Library library,
FT_Bitmap* bitmap,
FT_Pos xStrength,
FT_Pos yStrength );
/**************************************************************************
*
* @function:
* FT_Bitmap_Convert
*
* @description:
* Convert a bitmap object with depth 1bpp, 2bpp, 4bpp, 8bpp or 32bpp to
* a bitmap object with depth 8bpp, making the number of used bytes per
* line (a.k.a. the 'pitch') a multiple of `alignment`.
*
* @input:
* library ::
* A handle to a library object.
*
* source ::
* The source bitmap.
*
* alignment ::
* The pitch of the bitmap is a multiple of this argument. Common
* values are 1, 2, or 4.
*
* @output:
* target ::
* The target bitmap.
*
* @return:
* FreeType error code. 0~means success.
*
* @note:
* It is possible to call @FT_Bitmap_Convert multiple times without
* calling @FT_Bitmap_Done (the memory is simply reallocated).
*
* Use @FT_Bitmap_Done to finally remove the bitmap object.
*
* The `library` argument is taken to have access to FreeType's memory
* handling functions.
*
* `source->buffer` and `target->buffer` must neither be equal nor
* overlap.
*/
FT_EXPORT( FT_Error )
FT_Bitmap_Convert( FT_Library library,
const FT_Bitmap *source,
FT_Bitmap *target,
FT_Int alignment );
/**************************************************************************
*
* @function:
* FT_Bitmap_Blend
*
* @description:
* Blend a bitmap onto another bitmap, using a given color.
*
* @input:
* library ::
* A handle to a library object.
*
* source ::
* The source bitmap, which can have any @FT_Pixel_Mode format.
*
* source_offset ::
* The offset vector to the upper left corner of the source bitmap in
* 26.6 pixel format. It should represent an integer offset; the
* function will set the lowest six bits to zero to enforce that.
*
* color ::
* The color used to draw `source` onto `target`.
*
* @inout:
* target ::
* A handle to an `FT_Bitmap` object. It should be either initialized
* as empty with a call to @FT_Bitmap_Init, or it should be of type
* @FT_PIXEL_MODE_BGRA.
*
* atarget_offset ::
* The offset vector to the upper left corner of the target bitmap in
* 26.6 pixel format. It should represent an integer offset; the
* function will set the lowest six bits to zero to enforce that.
*
* @return:
* FreeType error code. 0~means success.
*
* @note:
* This function doesn't perform clipping.
*
* The bitmap in `target` gets allocated or reallocated as needed; the
* vector `atarget_offset` is updated accordingly.
*
* In case of allocation or reallocation, the bitmap's pitch is set to
* `4 * width`. Both `source` and `target` must have the same bitmap
* flow (as indicated by the sign of the `pitch` field).
*
* `source->buffer` and `target->buffer` must neither be equal nor
* overlap.
*
* @since:
* 2.10
*/
FT_EXPORT( FT_Error )
FT_Bitmap_Blend( FT_Library library,
const FT_Bitmap* source,
const FT_Vector source_offset,
FT_Bitmap* target,
FT_Vector *atarget_offset,
FT_Color color );
/**************************************************************************
*
* @function:
* FT_GlyphSlot_Own_Bitmap
*
* @description:
* Make sure that a glyph slot owns `slot->bitmap`.
*
* @input:
* slot ::
* The glyph slot.
*
* @return:
* FreeType error code. 0~means success.
*
* @note:
* This function is to be used in combination with @FT_Bitmap_Embolden.
*/
FT_EXPORT( FT_Error )
FT_GlyphSlot_Own_Bitmap( FT_GlyphSlot slot );
/**************************************************************************
*
* @function:
* FT_Bitmap_Done
*
* @description:
* Destroy a bitmap object initialized with @FT_Bitmap_Init.
*
* @input:
* library ::
* A handle to a library object.
*
* bitmap ::
* The bitmap object to be freed.
*
* @return:
* FreeType error code. 0~means success.
*
* @note:
* The `library` argument is taken to have access to FreeType's memory
* handling functions.
*/
FT_EXPORT( FT_Error )
FT_Bitmap_Done( FT_Library library,
FT_Bitmap *bitmap );
/* */
FT_END_HEADER
#endif /* FTBITMAP_H_ */
/* END */
@@ -0,0 +1,102 @@
/****************************************************************************
*
* ftbzip2.h
*
* Bzip2-compressed stream support.
*
* Copyright (C) 2010-2023 by
* Joel Klinghed.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#ifndef FTBZIP2_H_
#define FTBZIP2_H_
#include <freetype/freetype.h>
#ifdef FREETYPE_H
#error "freetype.h of FreeType 1 has been loaded!"
#error "Please fix the directory search order for header files"
#error "so that freetype.h of FreeType 2 is found first."
#endif
FT_BEGIN_HEADER
/**************************************************************************
*
* @section:
* bzip2
*
* @title:
* BZIP2 Streams
*
* @abstract:
* Using bzip2-compressed font files.
*
* @description:
* In certain builds of the library, bzip2 compression recognition is
* automatically handled when calling @FT_New_Face or @FT_Open_Face.
* This means that if no font driver is capable of handling the raw
* compressed file, the library will try to open a bzip2 compressed
* stream from it and re-open the face with it.
*
* The stream implementation is very basic and resets the decompression
* process each time seeking backwards is needed within the stream,
* which significantly undermines the performance.
*
* This section contains the declaration of Bzip2-specific functions.
*
*/
/**************************************************************************
*
* @function:
* FT_Stream_OpenBzip2
*
* @description:
* Open a new stream to parse bzip2-compressed font files. This is
* mainly used to support the compressed `*.pcf.bz2` fonts that come with
* XFree86.
*
* @input:
* stream ::
* The target embedding stream.
*
* source ::
* The source stream.
*
* @return:
* FreeType error code. 0~means success.
*
* @note:
* The source stream must be opened _before_ calling this function.
*
* Calling the internal function `FT_Stream_Close` on the new stream will
* **not** call `FT_Stream_Close` on the source stream. None of the
* stream objects will be released to the heap.
*
* This function may return `FT_Err_Unimplemented_Feature` if your build
* of FreeType was not compiled with bzip2 support.
*/
FT_EXPORT( FT_Error )
FT_Stream_OpenBzip2( FT_Stream stream,
FT_Stream source );
/* */
FT_END_HEADER
#endif /* FTBZIP2_H_ */
/* END */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,168 @@
/****************************************************************************
*
* This file defines the structure of the FreeType reference.
* It is used by the python script that generates the HTML files.
*
*/
/**************************************************************************
*
* @chapter:
* general_remarks
*
* @title:
* General Remarks
*
* @sections:
* preamble
* header_inclusion
* user_allocation
*
*/
/**************************************************************************
*
* @chapter:
* core_api
*
* @title:
* Core API
*
* @sections:
* basic_types
* library_setup
* face_creation
* font_testing_macros
* sizing_and_scaling
* glyph_retrieval
* character_mapping
* information_retrieval
* other_api_data
*
*/
/**************************************************************************
*
* @chapter:
* extended_api
*
* @title:
* Extended API
*
* @sections:
* glyph_variants
* color_management
* layer_management
* glyph_management
* mac_specific
* sizes_management
* header_file_macros
*
*/
/**************************************************************************
*
* @chapter:
* format_specific
*
* @title:
* Format-Specific API
*
* @sections:
* multiple_masters
* truetype_tables
* type1_tables
* sfnt_names
* bdf_fonts
* cid_fonts
* pfr_fonts
* winfnt_fonts
* svg_fonts
* font_formats
* gasp_table
*
*/
/**************************************************************************
*
* @chapter:
* module_specific
*
* @title:
* Controlling FreeType Modules
*
* @sections:
* auto_hinter
* cff_driver
* t1_cid_driver
* tt_driver
* pcf_driver
* ot_svg_driver
* properties
* parameter_tags
* lcd_rendering
*
*/
/**************************************************************************
*
* @chapter:
* cache_subsystem
*
* @title:
* Cache Sub-System
*
* @sections:
* cache_subsystem
*
*/
/**************************************************************************
*
* @chapter:
* support_api
*
* @title:
* Support API
*
* @sections:
* computations
* list_processing
* outline_processing
* quick_advance
* bitmap_handling
* raster
* glyph_stroker
* system_interface
* module_management
* gzip
* lzw
* bzip2
* debugging_apis
*
*/
/**************************************************************************
*
* @chapter:
* error_codes
*
* @title:
* Error Codes
*
* @sections:
* error_enumerations
* error_code_values
*
*/
/* END */
@@ -0,0 +1,167 @@
/****************************************************************************
*
* ftcid.h
*
* FreeType API for accessing CID font information (specification).
*
* Copyright (C) 2007-2023 by
* Dereg Clegg and Michael Toftdal.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#ifndef FTCID_H_
#define FTCID_H_
#include <freetype/freetype.h>
#ifdef FREETYPE_H
#error "freetype.h of FreeType 1 has been loaded!"
#error "Please fix the directory search order for header files"
#error "so that freetype.h of FreeType 2 is found first."
#endif
FT_BEGIN_HEADER
/**************************************************************************
*
* @section:
* cid_fonts
*
* @title:
* CID Fonts
*
* @abstract:
* CID-keyed font-specific API.
*
* @description:
* This section contains the declaration of CID-keyed font-specific
* functions.
*
*/
/**************************************************************************
*
* @function:
* FT_Get_CID_Registry_Ordering_Supplement
*
* @description:
* Retrieve the Registry/Ordering/Supplement triple (also known as the
* "R/O/S") from a CID-keyed font.
*
* @input:
* face ::
* A handle to the input face.
*
* @output:
* registry ::
* The registry, as a C~string, owned by the face.
*
* ordering ::
* The ordering, as a C~string, owned by the face.
*
* supplement ::
* The supplement.
*
* @return:
* FreeType error code. 0~means success.
*
* @note:
* This function only works with CID faces, returning an error
* otherwise.
*
* @since:
* 2.3.6
*/
FT_EXPORT( FT_Error )
FT_Get_CID_Registry_Ordering_Supplement( FT_Face face,
const char* *registry,
const char* *ordering,
FT_Int *supplement );
/**************************************************************************
*
* @function:
* FT_Get_CID_Is_Internally_CID_Keyed
*
* @description:
* Retrieve the type of the input face, CID keyed or not. In contrast
* to the @FT_IS_CID_KEYED macro this function returns successfully also
* for CID-keyed fonts in an SFNT wrapper.
*
* @input:
* face ::
* A handle to the input face.
*
* @output:
* is_cid ::
* The type of the face as an @FT_Bool.
*
* @return:
* FreeType error code. 0~means success.
*
* @note:
* This function only works with CID faces and OpenType fonts, returning
* an error otherwise.
*
* @since:
* 2.3.9
*/
FT_EXPORT( FT_Error )
FT_Get_CID_Is_Internally_CID_Keyed( FT_Face face,
FT_Bool *is_cid );
/**************************************************************************
*
* @function:
* FT_Get_CID_From_Glyph_Index
*
* @description:
* Retrieve the CID of the input glyph index.
*
* @input:
* face ::
* A handle to the input face.
*
* glyph_index ::
* The input glyph index.
*
* @output:
* cid ::
* The CID as an @FT_UInt.
*
* @return:
* FreeType error code. 0~means success.
*
* @note:
* This function only works with CID faces and OpenType fonts, returning
* an error otherwise.
*
* @since:
* 2.3.9
*/
FT_EXPORT( FT_Error )
FT_Get_CID_From_Glyph_Index( FT_Face face,
FT_UInt glyph_index,
FT_UInt *cid );
/* */
FT_END_HEADER
#endif /* FTCID_H_ */
/* END */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,283 @@
/****************************************************************************
*
* fterrdef.h
*
* FreeType error codes (specification).
*
* Copyright (C) 2002-2023 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
/**************************************************************************
*
* @section:
* error_code_values
*
* @title:
* Error Code Values
*
* @abstract:
* All possible error codes returned by FreeType functions.
*
* @description:
* The list below is taken verbatim from the file `fterrdef.h` (loaded
* automatically by including `FT_FREETYPE_H`). The first argument of the
* `FT_ERROR_DEF_` macro is the error label; by default, the prefix
* `FT_Err_` gets added so that you get error names like
* `FT_Err_Cannot_Open_Resource`. The second argument is the error code,
* and the last argument an error string, which is not used by FreeType.
*
* Within your application you should **only** use error names and
* **never** its numeric values! The latter might (and actually do)
* change in forthcoming FreeType versions.
*
* Macro `FT_NOERRORDEF_` defines `FT_Err_Ok`, which is always zero. See
* the 'Error Enumerations' subsection how to automatically generate a
* list of error strings.
*
*/
/**************************************************************************
*
* @enum:
* FT_Err_XXX
*
*/
/* generic errors */
FT_NOERRORDEF_( Ok, 0x00,
"no error" )
FT_ERRORDEF_( Cannot_Open_Resource, 0x01,
"cannot open resource" )
FT_ERRORDEF_( Unknown_File_Format, 0x02,
"unknown file format" )
FT_ERRORDEF_( Invalid_File_Format, 0x03,
"broken file" )
FT_ERRORDEF_( Invalid_Version, 0x04,
"invalid FreeType version" )
FT_ERRORDEF_( Lower_Module_Version, 0x05,
"module version is too low" )
FT_ERRORDEF_( Invalid_Argument, 0x06,
"invalid argument" )
FT_ERRORDEF_( Unimplemented_Feature, 0x07,
"unimplemented feature" )
FT_ERRORDEF_( Invalid_Table, 0x08,
"broken table" )
FT_ERRORDEF_( Invalid_Offset, 0x09,
"broken offset within table" )
FT_ERRORDEF_( Array_Too_Large, 0x0A,
"array allocation size too large" )
FT_ERRORDEF_( Missing_Module, 0x0B,
"missing module" )
FT_ERRORDEF_( Missing_Property, 0x0C,
"missing property" )
/* glyph/character errors */
FT_ERRORDEF_( Invalid_Glyph_Index, 0x10,
"invalid glyph index" )
FT_ERRORDEF_( Invalid_Character_Code, 0x11,
"invalid character code" )
FT_ERRORDEF_( Invalid_Glyph_Format, 0x12,
"unsupported glyph image format" )
FT_ERRORDEF_( Cannot_Render_Glyph, 0x13,
"cannot render this glyph format" )
FT_ERRORDEF_( Invalid_Outline, 0x14,
"invalid outline" )
FT_ERRORDEF_( Invalid_Composite, 0x15,
"invalid composite glyph" )
FT_ERRORDEF_( Too_Many_Hints, 0x16,
"too many hints" )
FT_ERRORDEF_( Invalid_Pixel_Size, 0x17,
"invalid pixel size" )
FT_ERRORDEF_( Invalid_SVG_Document, 0x18,
"invalid SVG document" )
/* handle errors */
FT_ERRORDEF_( Invalid_Handle, 0x20,
"invalid object handle" )
FT_ERRORDEF_( Invalid_Library_Handle, 0x21,
"invalid library handle" )
FT_ERRORDEF_( Invalid_Driver_Handle, 0x22,
"invalid module handle" )
FT_ERRORDEF_( Invalid_Face_Handle, 0x23,
"invalid face handle" )
FT_ERRORDEF_( Invalid_Size_Handle, 0x24,
"invalid size handle" )
FT_ERRORDEF_( Invalid_Slot_Handle, 0x25,
"invalid glyph slot handle" )
FT_ERRORDEF_( Invalid_CharMap_Handle, 0x26,
"invalid charmap handle" )
FT_ERRORDEF_( Invalid_Cache_Handle, 0x27,
"invalid cache manager handle" )
FT_ERRORDEF_( Invalid_Stream_Handle, 0x28,
"invalid stream handle" )
/* driver errors */
FT_ERRORDEF_( Too_Many_Drivers, 0x30,
"too many modules" )
FT_ERRORDEF_( Too_Many_Extensions, 0x31,
"too many extensions" )
/* memory errors */
FT_ERRORDEF_( Out_Of_Memory, 0x40,
"out of memory" )
FT_ERRORDEF_( Unlisted_Object, 0x41,
"unlisted object" )
/* stream errors */
FT_ERRORDEF_( Cannot_Open_Stream, 0x51,
"cannot open stream" )
FT_ERRORDEF_( Invalid_Stream_Seek, 0x52,
"invalid stream seek" )
FT_ERRORDEF_( Invalid_Stream_Skip, 0x53,
"invalid stream skip" )
FT_ERRORDEF_( Invalid_Stream_Read, 0x54,
"invalid stream read" )
FT_ERRORDEF_( Invalid_Stream_Operation, 0x55,
"invalid stream operation" )
FT_ERRORDEF_( Invalid_Frame_Operation, 0x56,
"invalid frame operation" )
FT_ERRORDEF_( Nested_Frame_Access, 0x57,
"nested frame access" )
FT_ERRORDEF_( Invalid_Frame_Read, 0x58,
"invalid frame read" )
/* raster errors */
FT_ERRORDEF_( Raster_Uninitialized, 0x60,
"raster uninitialized" )
FT_ERRORDEF_( Raster_Corrupted, 0x61,
"raster corrupted" )
FT_ERRORDEF_( Raster_Overflow, 0x62,
"raster overflow" )
FT_ERRORDEF_( Raster_Negative_Height, 0x63,
"negative height while rastering" )
/* cache errors */
FT_ERRORDEF_( Too_Many_Caches, 0x70,
"too many registered caches" )
/* TrueType and SFNT errors */
FT_ERRORDEF_( Invalid_Opcode, 0x80,
"invalid opcode" )
FT_ERRORDEF_( Too_Few_Arguments, 0x81,
"too few arguments" )
FT_ERRORDEF_( Stack_Overflow, 0x82,
"stack overflow" )
FT_ERRORDEF_( Code_Overflow, 0x83,
"code overflow" )
FT_ERRORDEF_( Bad_Argument, 0x84,
"bad argument" )
FT_ERRORDEF_( Divide_By_Zero, 0x85,
"division by zero" )
FT_ERRORDEF_( Invalid_Reference, 0x86,
"invalid reference" )
FT_ERRORDEF_( Debug_OpCode, 0x87,
"found debug opcode" )
FT_ERRORDEF_( ENDF_In_Exec_Stream, 0x88,
"found ENDF opcode in execution stream" )
FT_ERRORDEF_( Nested_DEFS, 0x89,
"nested DEFS" )
FT_ERRORDEF_( Invalid_CodeRange, 0x8A,
"invalid code range" )
FT_ERRORDEF_( Execution_Too_Long, 0x8B,
"execution context too long" )
FT_ERRORDEF_( Too_Many_Function_Defs, 0x8C,
"too many function definitions" )
FT_ERRORDEF_( Too_Many_Instruction_Defs, 0x8D,
"too many instruction definitions" )
FT_ERRORDEF_( Table_Missing, 0x8E,
"SFNT font table missing" )
FT_ERRORDEF_( Horiz_Header_Missing, 0x8F,
"horizontal header (hhea) table missing" )
FT_ERRORDEF_( Locations_Missing, 0x90,
"locations (loca) table missing" )
FT_ERRORDEF_( Name_Table_Missing, 0x91,
"name table missing" )
FT_ERRORDEF_( CMap_Table_Missing, 0x92,
"character map (cmap) table missing" )
FT_ERRORDEF_( Hmtx_Table_Missing, 0x93,
"horizontal metrics (hmtx) table missing" )
FT_ERRORDEF_( Post_Table_Missing, 0x94,
"PostScript (post) table missing" )
FT_ERRORDEF_( Invalid_Horiz_Metrics, 0x95,
"invalid horizontal metrics" )
FT_ERRORDEF_( Invalid_CharMap_Format, 0x96,
"invalid character map (cmap) format" )
FT_ERRORDEF_( Invalid_PPem, 0x97,
"invalid ppem value" )
FT_ERRORDEF_( Invalid_Vert_Metrics, 0x98,
"invalid vertical metrics" )
FT_ERRORDEF_( Could_Not_Find_Context, 0x99,
"could not find context" )
FT_ERRORDEF_( Invalid_Post_Table_Format, 0x9A,
"invalid PostScript (post) table format" )
FT_ERRORDEF_( Invalid_Post_Table, 0x9B,
"invalid PostScript (post) table" )
FT_ERRORDEF_( DEF_In_Glyf_Bytecode, 0x9C,
"found FDEF or IDEF opcode in glyf bytecode" )
FT_ERRORDEF_( Missing_Bitmap, 0x9D,
"missing bitmap in strike" )
FT_ERRORDEF_( Missing_SVG_Hooks, 0x9E,
"SVG hooks have not been set" )
/* CFF, CID, and Type 1 errors */
FT_ERRORDEF_( Syntax_Error, 0xA0,
"opcode syntax error" )
FT_ERRORDEF_( Stack_Underflow, 0xA1,
"argument stack underflow" )
FT_ERRORDEF_( Ignore, 0xA2,
"ignore" )
FT_ERRORDEF_( No_Unicode_Glyph_Name, 0xA3,
"no Unicode glyph name found" )
FT_ERRORDEF_( Glyph_Too_Big, 0xA4,
"glyph too big for hinting" )
/* BDF errors */
FT_ERRORDEF_( Missing_Startfont_Field, 0xB0,
"`STARTFONT' field missing" )
FT_ERRORDEF_( Missing_Font_Field, 0xB1,
"`FONT' field missing" )
FT_ERRORDEF_( Missing_Size_Field, 0xB2,
"`SIZE' field missing" )
FT_ERRORDEF_( Missing_Fontboundingbox_Field, 0xB3,
"`FONTBOUNDINGBOX' field missing" )
FT_ERRORDEF_( Missing_Chars_Field, 0xB4,
"`CHARS' field missing" )
FT_ERRORDEF_( Missing_Startchar_Field, 0xB5,
"`STARTCHAR' field missing" )
FT_ERRORDEF_( Missing_Encoding_Field, 0xB6,
"`ENCODING' field missing" )
FT_ERRORDEF_( Missing_Bbx_Field, 0xB7,
"`BBX' field missing" )
FT_ERRORDEF_( Bbx_Too_Big, 0xB8,
"`BBX' too big" )
FT_ERRORDEF_( Corrupted_Font_Header, 0xB9,
"Font header corrupted or missing fields" )
FT_ERRORDEF_( Corrupted_Font_Glyphs, 0xBA,
"Font glyphs corrupted or missing fields" )
/* */
/* END */
@@ -0,0 +1,296 @@
/****************************************************************************
*
* fterrors.h
*
* FreeType error code handling (specification).
*
* Copyright (C) 1996-2023 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
/**************************************************************************
*
* @section:
* error_enumerations
*
* @title:
* Error Enumerations
*
* @abstract:
* How to handle errors and error strings.
*
* @description:
* The header file `fterrors.h` (which is automatically included by
* `freetype.h`) defines the handling of FreeType's enumeration
* constants. It can also be used to generate error message strings
* with a small macro trick explained below.
*
* **Error Formats**
*
* The configuration macro `FT_CONFIG_OPTION_USE_MODULE_ERRORS` can be
* defined in `ftoption.h` in order to make the higher byte indicate the
* module where the error has happened (this is not compatible with
* standard builds of FreeType~2, however). See the file `ftmoderr.h`
* for more details.
*
* **Error Message Strings**
*
* Error definitions are set up with special macros that allow client
* applications to build a table of error message strings. The strings
* are not included in a normal build of FreeType~2 to save space (most
* client applications do not use them).
*
* To do so, you have to define the following macros before including
* this file.
*
* ```
* FT_ERROR_START_LIST
* ```
*
* This macro is called before anything else to define the start of the
* error list. It is followed by several `FT_ERROR_DEF` calls.
*
* ```
* FT_ERROR_DEF( e, v, s )
* ```
*
* This macro is called to define one single error. 'e' is the error
* code identifier (e.g., `Invalid_Argument`), 'v' is the error's
* numerical value, and 's' is the corresponding error string.
*
* ```
* FT_ERROR_END_LIST
* ```
*
* This macro ends the list.
*
* Additionally, you have to undefine `FTERRORS_H_` before #including
* this file.
*
* Here is a simple example.
*
* ```
* #undef FTERRORS_H_
* #define FT_ERRORDEF( e, v, s ) { e, s },
* #define FT_ERROR_START_LIST {
* #define FT_ERROR_END_LIST { 0, NULL } };
*
* const struct
* {
* int err_code;
* const char* err_msg;
* } ft_errors[] =
*
* #include <freetype/fterrors.h>
* ```
*
* An alternative to using an array is a switch statement.
*
* ```
* #undef FTERRORS_H_
* #define FT_ERROR_START_LIST switch ( error_code ) {
* #define FT_ERRORDEF( e, v, s ) case v: return s;
* #define FT_ERROR_END_LIST }
* ```
*
* If you use `FT_CONFIG_OPTION_USE_MODULE_ERRORS`, `error_code` should
* be replaced with `FT_ERROR_BASE(error_code)` in the last example.
*/
/* */
/* In previous FreeType versions we used `__FTERRORS_H__`. However, */
/* using two successive underscores in a non-system symbol name */
/* violates the C (and C++) standard, so it was changed to the */
/* current form. In spite of this, we have to make */
/* */
/* ``` */
/* #undefine __FTERRORS_H__ */
/* ``` */
/* */
/* work for backward compatibility. */
/* */
#if !( defined( FTERRORS_H_ ) && defined ( __FTERRORS_H__ ) )
#define FTERRORS_H_
#define __FTERRORS_H__
/* include module base error codes */
#include <freetype/ftmoderr.h>
/*******************************************************************/
/*******************************************************************/
/***** *****/
/***** SETUP MACROS *****/
/***** *****/
/*******************************************************************/
/*******************************************************************/
#undef FT_NEED_EXTERN_C
/* FT_ERR_PREFIX is used as a prefix for error identifiers. */
/* By default, we use `FT_Err_`. */
/* */
#ifndef FT_ERR_PREFIX
#define FT_ERR_PREFIX FT_Err_
#endif
/* FT_ERR_BASE is used as the base for module-specific errors. */
/* */
#ifdef FT_CONFIG_OPTION_USE_MODULE_ERRORS
#ifndef FT_ERR_BASE
#define FT_ERR_BASE FT_Mod_Err_Base
#endif
#else
#undef FT_ERR_BASE
#define FT_ERR_BASE 0
#endif /* FT_CONFIG_OPTION_USE_MODULE_ERRORS */
/* If FT_ERRORDEF is not defined, we need to define a simple */
/* enumeration type. */
/* */
#ifndef FT_ERRORDEF
#define FT_INCLUDE_ERR_PROTOS
#define FT_ERRORDEF( e, v, s ) e = v,
#define FT_ERROR_START_LIST enum {
#define FT_ERROR_END_LIST FT_ERR_CAT( FT_ERR_PREFIX, Max ) };
#ifdef __cplusplus
#define FT_NEED_EXTERN_C
extern "C" {
#endif
#endif /* !FT_ERRORDEF */
/* this macro is used to define an error */
#define FT_ERRORDEF_( e, v, s ) \
FT_ERRORDEF( FT_ERR_CAT( FT_ERR_PREFIX, e ), v + FT_ERR_BASE, s )
/* this is only used for <module>_Err_Ok, which must be 0! */
#define FT_NOERRORDEF_( e, v, s ) \
FT_ERRORDEF( FT_ERR_CAT( FT_ERR_PREFIX, e ), v, s )
#ifdef FT_ERROR_START_LIST
FT_ERROR_START_LIST
#endif
/* now include the error codes */
#include <freetype/fterrdef.h>
#ifdef FT_ERROR_END_LIST
FT_ERROR_END_LIST
#endif
/*******************************************************************/
/*******************************************************************/
/***** *****/
/***** SIMPLE CLEANUP *****/
/***** *****/
/*******************************************************************/
/*******************************************************************/
#ifdef FT_NEED_EXTERN_C
}
#endif
#undef FT_ERROR_START_LIST
#undef FT_ERROR_END_LIST
#undef FT_ERRORDEF
#undef FT_ERRORDEF_
#undef FT_NOERRORDEF_
#undef FT_NEED_EXTERN_C
#undef FT_ERR_BASE
/* FT_ERR_PREFIX is needed internally */
#ifndef FT2_BUILD_LIBRARY
#undef FT_ERR_PREFIX
#endif
/* FT_INCLUDE_ERR_PROTOS: Control whether function prototypes should be */
/* included with */
/* */
/* #include <freetype/fterrors.h> */
/* */
/* This is only true where `FT_ERRORDEF` is */
/* undefined. */
/* */
/* FT_ERR_PROTOS_DEFINED: Actual multiple-inclusion protection of */
/* `fterrors.h`. */
#ifdef FT_INCLUDE_ERR_PROTOS
#undef FT_INCLUDE_ERR_PROTOS
#ifndef FT_ERR_PROTOS_DEFINED
#define FT_ERR_PROTOS_DEFINED
FT_BEGIN_HEADER
/**************************************************************************
*
* @function:
* FT_Error_String
*
* @description:
* Retrieve the description of a valid FreeType error code.
*
* @input:
* error_code ::
* A valid FreeType error code.
*
* @return:
* A C~string or `NULL`, if any error occurred.
*
* @note:
* FreeType has to be compiled with `FT_CONFIG_OPTION_ERROR_STRINGS` or
* `FT_DEBUG_LEVEL_ERROR` to get meaningful descriptions.
* 'error_string' will be `NULL` otherwise.
*
* Module identification will be ignored:
*
* ```c
* strcmp( FT_Error_String( FT_Err_Unknown_File_Format ),
* FT_Error_String( BDF_Err_Unknown_File_Format ) ) == 0;
* ```
*/
FT_EXPORT( const char* )
FT_Error_String( FT_Error error_code );
/* */
FT_END_HEADER
#endif /* FT_ERR_PROTOS_DEFINED */
#endif /* FT_INCLUDE_ERR_PROTOS */
#endif /* !(FTERRORS_H_ && __FTERRORS_H__) */
/* END */
@@ -0,0 +1,93 @@
/****************************************************************************
*
* ftfntfmt.h
*
* Support functions for font formats.
*
* Copyright (C) 2002-2023 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#ifndef FTFNTFMT_H_
#define FTFNTFMT_H_
#include <freetype/freetype.h>
#ifdef FREETYPE_H
#error "freetype.h of FreeType 1 has been loaded!"
#error "Please fix the directory search order for header files"
#error "so that freetype.h of FreeType 2 is found first."
#endif
FT_BEGIN_HEADER
/**************************************************************************
*
* @section:
* font_formats
*
* @title:
* Font Formats
*
* @abstract:
* Getting the font format.
*
* @description:
* The single function in this section can be used to get the font format.
* Note that this information is not needed normally; however, there are
* special cases (like in PDF devices) where it is important to
* differentiate, in spite of FreeType's uniform API.
*
*/
/**************************************************************************
*
* @function:
* FT_Get_Font_Format
*
* @description:
* Return a string describing the format of a given face. Possible values
* are 'TrueType', 'Type~1', 'BDF', 'PCF', 'Type~42', 'CID~Type~1', 'CFF',
* 'PFR', and 'Windows~FNT'.
*
* The return value is suitable to be used as an X11 FONT_PROPERTY.
*
* @input:
* face ::
* Input face handle.
*
* @return:
* Font format string. `NULL` in case of error.
*
* @note:
* A deprecated name for the same function is `FT_Get_X11_Font_Format`.
*/
FT_EXPORT( const char* )
FT_Get_Font_Format( FT_Face face );
/* deprecated */
FT_EXPORT( const char* )
FT_Get_X11_Font_Format( FT_Face face );
/* */
FT_END_HEADER
#endif /* FTFNTFMT_H_ */
/* END */
@@ -0,0 +1,143 @@
/****************************************************************************
*
* ftgasp.h
*
* Access of TrueType's 'gasp' table (specification).
*
* Copyright (C) 2007-2023 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
#ifndef FTGASP_H_
#define FTGASP_H_
#include <freetype/freetype.h>
#ifdef FREETYPE_H
#error "freetype.h of FreeType 1 has been loaded!"
#error "Please fix the directory search order for header files"
#error "so that freetype.h of FreeType 2 is found first."
#endif
FT_BEGIN_HEADER
/**************************************************************************
*
* @section:
* gasp_table
*
* @title:
* Gasp Table
*
* @abstract:
* Retrieving TrueType 'gasp' table entries.
*
* @description:
* The function @FT_Get_Gasp can be used to query a TrueType or OpenType
* font for specific entries in its 'gasp' table, if any. This is mainly
* useful when implementing native TrueType hinting with the bytecode
* interpreter to duplicate the Windows text rendering results.
*/
/**************************************************************************
*
* @enum:
* FT_GASP_XXX
*
* @description:
* A list of values and/or bit-flags returned by the @FT_Get_Gasp
* function.
*
* @values:
* FT_GASP_NO_TABLE ::
* This special value means that there is no GASP table in this face.
* It is up to the client to decide what to do.
*
* FT_GASP_DO_GRIDFIT ::
* Grid-fitting and hinting should be performed at the specified ppem.
* This **really** means TrueType bytecode interpretation. If this bit
* is not set, no hinting gets applied.
*
* FT_GASP_DO_GRAY ::
* Anti-aliased rendering should be performed at the specified ppem.
* If not set, do monochrome rendering.
*
* FT_GASP_SYMMETRIC_SMOOTHING ::
* If set, smoothing along multiple axes must be used with ClearType.
*
* FT_GASP_SYMMETRIC_GRIDFIT ::
* Grid-fitting must be used with ClearType's symmetric smoothing.
*
* @note:
* The bit-flags `FT_GASP_DO_GRIDFIT` and `FT_GASP_DO_GRAY` are to be
* used for standard font rasterization only. Independently of that,
* `FT_GASP_SYMMETRIC_SMOOTHING` and `FT_GASP_SYMMETRIC_GRIDFIT` are to
* be used if ClearType is enabled (and `FT_GASP_DO_GRIDFIT` and
* `FT_GASP_DO_GRAY` are consequently ignored).
*
* 'ClearType' is Microsoft's implementation of LCD rendering, partly
* protected by patents.
*
* @since:
* 2.3.0
*/
#define FT_GASP_NO_TABLE -1
#define FT_GASP_DO_GRIDFIT 0x01
#define FT_GASP_DO_GRAY 0x02
#define FT_GASP_SYMMETRIC_GRIDFIT 0x04
#define FT_GASP_SYMMETRIC_SMOOTHING 0x08
/**************************************************************************
*
* @function:
* FT_Get_Gasp
*
* @description:
* For a TrueType or OpenType font file, return the rasterizer behaviour
* flags from the font's 'gasp' table corresponding to a given character
* pixel size.
*
* @input:
* face ::
* The source face handle.
*
* ppem ::
* The vertical character pixel size.
*
* @return:
* Bit flags (see @FT_GASP_XXX), or @FT_GASP_NO_TABLE if there is no
* 'gasp' table in the face.
*
* @note:
* If you want to use the MM functionality of OpenType variation fonts
* (i.e., using @FT_Set_Var_Design_Coordinates and friends), call this
* function **after** setting an instance since the return values can
* change.
*
* @since:
* 2.3.0
*/
FT_EXPORT( FT_Int )
FT_Get_Gasp( FT_Face face,
FT_UInt ppem );
/* */
FT_END_HEADER
#endif /* FTGASP_H_ */
/* END */
@@ -0,0 +1,750 @@
/****************************************************************************
*
* ftglyph.h
*
* FreeType convenience functions to handle glyphs (specification).
*
* Copyright (C) 1996-2023 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
* modified, and distributed under the terms of the FreeType project
* license, LICENSE.TXT. By continuing to use, modify, or distribute
* this file you indicate that you have read the license and
* understand and accept it fully.
*
*/
/**************************************************************************
*
* This file contains the definition of several convenience functions that
* can be used by client applications to easily retrieve glyph bitmaps and
* outlines from a given face.
*
* These functions should be optional if you are writing a font server or
* text layout engine on top of FreeType. However, they are pretty handy
* for many other simple uses of the library.
*
*/
#ifndef FTGLYPH_H_
#define FTGLYPH_H_
#include <freetype/freetype.h>
#ifdef FREETYPE_H
#error "freetype.h of FreeType 1 has been loaded!"
#error "Please fix the directory search order for header files"
#error "so that freetype.h of FreeType 2 is found first."
#endif
FT_BEGIN_HEADER
/**************************************************************************
*
* @section:
* glyph_management
*
* @title:
* Glyph Management
*
* @abstract:
* Generic interface to manage individual glyph data.
*
* @description:
* This section contains definitions used to manage glyph data through
* generic @FT_Glyph objects. Each of them can contain a bitmap,
* a vector outline, or even images in other formats. These objects are
* detached from @FT_Face, contrary to @FT_GlyphSlot.
*
*/
/* forward declaration to a private type */
typedef struct FT_Glyph_Class_ FT_Glyph_Class;
/**************************************************************************
*
* @type:
* FT_Glyph
*
* @description:
* Handle to an object used to model generic glyph images. It is a
* pointer to the @FT_GlyphRec structure and can contain a glyph bitmap
* or pointer.
*
* @note:
* Glyph objects are not owned by the library. You must thus release
* them manually (through @FT_Done_Glyph) _before_ calling
* @FT_Done_FreeType.
*/
typedef struct FT_GlyphRec_* FT_Glyph;
/**************************************************************************
*
* @struct:
* FT_GlyphRec
*
* @description:
* The root glyph structure contains a given glyph image plus its advance
* width in 16.16 fixed-point format.
*
* @fields:
* library ::
* A handle to the FreeType library object.
*
* clazz ::
* A pointer to the glyph's class. Private.
*
* format ::
* The format of the glyph's image.
*
* advance ::
* A 16.16 vector that gives the glyph's advance width.
*/
typedef struct FT_GlyphRec_
{
FT_Library library;
const FT_Glyph_Class* clazz;
FT_Glyph_Format format;
FT_Vector advance;
} FT_GlyphRec;
/**************************************************************************
*
* @type:
* FT_BitmapGlyph
*
* @description:
* A handle to an object used to model a bitmap glyph image. This is a
* 'sub-class' of @FT_Glyph, and a pointer to @FT_BitmapGlyphRec.
*/
typedef struct FT_BitmapGlyphRec_* FT_BitmapGlyph;
/**************************************************************************
*
* @struct:
* FT_BitmapGlyphRec
*
* @description:
* A structure used for bitmap glyph images. This really is a
* 'sub-class' of @FT_GlyphRec.
*
* @fields:
* root ::
* The root fields of @FT_Glyph.
*
* left ::
* The left-side bearing, i.e., the horizontal distance from the
* current pen position to the left border of the glyph bitmap.
*
* top ::
* The top-side bearing, i.e., the vertical distance from the current
* pen position to the top border of the glyph bitmap. This distance
* is positive for upwards~y!
*
* bitmap ::
* A descriptor for the bitmap.
*
* @note:
* You can typecast an @FT_Glyph to @FT_BitmapGlyph if you have
* `glyph->format == FT_GLYPH_FORMAT_BITMAP`. This lets you access the
* bitmap's contents easily.
*
* The corresponding pixel buffer is always owned by @FT_BitmapGlyph and
* is thus created and destroyed with it.
*/
typedef struct FT_BitmapGlyphRec_
{
FT_GlyphRec root;
FT_Int left;
FT_Int top;
FT_Bitmap bitmap;
} FT_BitmapGlyphRec;
/**************************************************************************
*
* @type:
* FT_OutlineGlyph
*
* @description:
* A handle to an object used to model an outline glyph image. This is a
* 'sub-class' of @FT_Glyph, and a pointer to @FT_OutlineGlyphRec.
*/
typedef struct FT_OutlineGlyphRec_* FT_OutlineGlyph;
/**************************************************************************
*
* @struct:
* FT_OutlineGlyphRec
*
* @description:
* A structure used for outline (vectorial) glyph images. This really is
* a 'sub-class' of @FT_GlyphRec.
*
* @fields:
* root ::
* The root @FT_Glyph fields.
*
* outline ::
* A descriptor for the outline.
*
* @note:
* You can typecast an @FT_Glyph to @FT_OutlineGlyph if you have
* `glyph->format == FT_GLYPH_FORMAT_OUTLINE`. This lets you access the
* outline's content easily.
*
* As the outline is extracted from a glyph slot, its coordinates are
* expressed normally in 26.6 pixels, unless the flag @FT_LOAD_NO_SCALE
* was used in @FT_Load_Glyph or @FT_Load_Char.
*
* The outline's tables are always owned by the object and are destroyed
* with it.
*/
typedef struct FT_OutlineGlyphRec_
{
FT_GlyphRec root;
FT_Outline outline;
} FT_OutlineGlyphRec;
/**************************************************************************
*
* @type:
* FT_SvgGlyph
*
* @description:
* A handle to an object used to model an SVG glyph. This is a
* 'sub-class' of @FT_Glyph, and a pointer to @FT_SvgGlyphRec.
*
* @since:
* 2.12
*/
typedef struct FT_SvgGlyphRec_* FT_SvgGlyph;
/**************************************************************************
*
* @struct:
* FT_SvgGlyphRec
*
* @description:
* A structure used for OT-SVG glyphs. This is a 'sub-class' of
* @FT_GlyphRec.
*
* @fields:
* root ::
* The root @FT_GlyphRec fields.
*
* svg_document ::
* A pointer to the SVG document.
*
* svg_document_length ::
* The length of `svg_document`.
*
* glyph_index ::
* The index of the glyph to be rendered.
*
* metrics ::
* A metrics object storing the size information.
*
* units_per_EM ::
* The size of the EM square.
*
* start_glyph_id ::
* The first glyph ID in the glyph range covered by this document.
*
* end_glyph_id ::
* The last glyph ID in the glyph range covered by this document.
*
* transform ::
* A 2x2 transformation matrix to apply to the glyph while rendering
* it.
*
* delta ::
* Translation to apply to the glyph while rendering.
*
* @note:
* The Glyph Management API requires @FT_Glyph or its 'sub-class' to have
* all the information needed to completely define the glyph's rendering.
* Outline-based glyphs can directly apply transformations to the outline
* but this is not possible for an SVG document that hasn't been parsed.
* Therefore, the transformation is stored along with the document. In
* the absence of a 'ViewBox' or 'Width'/'Height' attribute, the size of
* the ViewPort should be assumed to be 'units_per_EM'.
*/
typedef struct FT_SvgGlyphRec_
{
FT_GlyphRec root;
FT_Byte* svg_document;
FT_ULong svg_document_length;
FT_UInt glyph_index;
FT_Size_Metrics metrics;
FT_UShort units_per_EM;
FT_UShort start_glyph_id;
FT_UShort end_glyph_id;
FT_Matrix transform;
FT_Vector delta;
} FT_SvgGlyphRec;
/**************************************************************************
*
* @function:
* FT_New_Glyph
*
* @description:
* A function used to create a new empty glyph image. Note that the
* created @FT_Glyph object must be released with @FT_Done_Glyph.
*
* @input:
* library ::
* A handle to the FreeType library object.
*
* format ::
* The format of the glyph's image.
*
* @output:
* aglyph ::
* A handle to the glyph object.
*
* @return:
* FreeType error code. 0~means success.
*
* @since:
* 2.10
*/
FT_EXPORT( FT_Error )
FT_New_Glyph( FT_Library library,
FT_Glyph_Format format,
FT_Glyph *aglyph );
/**************************************************************************
*
* @function:
* FT_Get_Glyph
*
* @description:
* A function used to extract a glyph image from a slot. Note that the
* created @FT_Glyph object must be released with @FT_Done_Glyph.
*
* @input:
* slot ::
* A handle to the source glyph slot.
*
* @output:
* aglyph ::
* A handle to the glyph object. `NULL` in case of error.
*
* @return:
* FreeType error code. 0~means success.
*
* @note:
* Because `*aglyph->advance.x` and `*aglyph->advance.y` are 16.16
* fixed-point numbers, `slot->advance.x` and `slot->advance.y` (which
* are in 26.6 fixed-point format) must be in the range ]-32768;32768[.
*/
FT_EXPORT( FT_Error )
FT_Get_Glyph( FT_GlyphSlot slot,
FT_Glyph *aglyph );
/**************************************************************************
*
* @function:
* FT_Glyph_Copy
*
* @description:
* A function used to copy a glyph image. Note that the created
* @FT_Glyph object must be released with @FT_Done_Glyph.
*
* @input:
* source ::
* A handle to the source glyph object.
*
* @output:
* target ::
* A handle to the target glyph object. `NULL` in case of error.
*
* @return:
* FreeType error code. 0~means success.
*/
FT_EXPORT( FT_Error )
FT_Glyph_Copy( FT_Glyph source,
FT_Glyph *target );
/**************************************************************************
*
* @function:
* FT_Glyph_Transform
*
* @description:
* Transform a glyph image if its format is scalable.
*
* @inout:
* glyph ::
* A handle to the target glyph object.
*
* @input:
* matrix ::
* A pointer to a 2x2 matrix to apply.
*
* delta ::
* A pointer to a 2d vector to apply. Coordinates are expressed in
* 1/64 of a pixel.
*
* @return:
* FreeType error code (if not 0, the glyph format is not scalable).
*
* @note:
* The 2x2 transformation matrix is also applied to the glyph's advance
* vector.
*/
FT_EXPORT( FT_Error )
FT_Glyph_Transform( FT_Glyph glyph,
const FT_Matrix* matrix,
const FT_Vector* delta );
/**************************************************************************
*
* @enum:
* FT_Glyph_BBox_Mode
*
* @description:
* The mode how the values of @FT_Glyph_Get_CBox are returned.
*
* @values:
* FT_GLYPH_BBOX_UNSCALED ::
* Return unscaled font units.
*
* FT_GLYPH_BBOX_SUBPIXELS ::
* Return unfitted 26.6 coordinates.
*
* FT_GLYPH_BBOX_GRIDFIT ::
* Return grid-fitted 26.6 coordinates.
*
* FT_GLYPH_BBOX_TRUNCATE ::
* Return coordinates in integer pixels.
*
* FT_GLYPH_BBOX_PIXELS ::
* Return grid-fitted pixel coordinates.
*/
typedef enum FT_Glyph_BBox_Mode_
{
FT_GLYPH_BBOX_UNSCALED = 0,
FT_GLYPH_BBOX_SUBPIXELS = 0,
FT_GLYPH_BBOX_GRIDFIT = 1,
FT_GLYPH_BBOX_TRUNCATE = 2,
FT_GLYPH_BBOX_PIXELS = 3
} FT_Glyph_BBox_Mode;
/* these constants are deprecated; use the corresponding */
/* `FT_Glyph_BBox_Mode` values instead */
#define ft_glyph_bbox_unscaled FT_GLYPH_BBOX_UNSCALED
#define ft_glyph_bbox_subpixels FT_GLYPH_BBOX_SUBPIXELS
#define ft_glyph_bbox_gridfit FT_GLYPH_BBOX_GRIDFIT
#define ft_glyph_bbox_truncate FT_GLYPH_BBOX_TRUNCATE
#define ft_glyph_bbox_pixels FT_GLYPH_BBOX_PIXELS
/**************************************************************************
*
* @function:
* FT_Glyph_Get_CBox
*
* @description:
* Return a glyph's 'control box'. The control box encloses all the
* outline's points, including Bezier control points. Though it
* coincides with the exact bounding box for most glyphs, it can be
* slightly larger in some situations (like when rotating an outline that
* contains Bezier outside arcs).
*
* Computing the control box is very fast, while getting the bounding box
* can take much more time as it needs to walk over all segments and arcs
* in the outline. To get the latter, you can use the 'ftbbox'
* component, which is dedicated to this single task.
*
* @input:
* glyph ::
* A handle to the source glyph object.
*
* mode ::
* The mode that indicates how to interpret the returned bounding box
* values.
*
* @output:
* acbox ::
* The glyph coordinate bounding box. Coordinates are expressed in
* 1/64 of pixels if it is grid-fitted.
*
* @note:
* Coordinates are relative to the glyph origin, using the y~upwards
* convention.
*
* If the glyph has been loaded with @FT_LOAD_NO_SCALE, `bbox_mode` must
* be set to @FT_GLYPH_BBOX_UNSCALED to get unscaled font units in 26.6
* pixel format. The value @FT_GLYPH_BBOX_SUBPIXELS is another name for
* this constant.
*
* If the font is tricky and the glyph has been loaded with
* @FT_LOAD_NO_SCALE, the resulting CBox is meaningless. To get
* reasonable values for the CBox it is necessary to load the glyph at a
* large ppem value (so that the hinting instructions can properly shift
* and scale the subglyphs), then extracting the CBox, which can be
* eventually converted back to font units.
*
* Note that the maximum coordinates are exclusive, which means that one
* can compute the width and height of the glyph image (be it in integer
* or 26.6 pixels) as:
*
* ```
* width = bbox.xMax - bbox.xMin;
* height = bbox.yMax - bbox.yMin;
* ```
*
* Note also that for 26.6 coordinates, if `bbox_mode` is set to
* @FT_GLYPH_BBOX_GRIDFIT, the coordinates will also be grid-fitted,
* which corresponds to:
*
* ```
* bbox.xMin = FLOOR(bbox.xMin);
* bbox.yMin = FLOOR(bbox.yMin);
* bbox.xMax = CEILING(bbox.xMax);
* bbox.yMax = CEILING(bbox.yMax);
* ```
*
* To get the bbox in pixel coordinates, set `bbox_mode` to
* @FT_GLYPH_BBOX_TRUNCATE.
*
* To get the bbox in grid-fitted pixel coordinates, set `bbox_mode` to
* @FT_GLYPH_BBOX_PIXELS.
*/
FT_EXPORT( void )
FT_Glyph_Get_CBox( FT_Glyph glyph,
FT_UInt bbox_mode,
FT_BBox *acbox );
/**************************************************************************
*
* @function:
* FT_Glyph_To_Bitmap
*
* @description:
* Convert a given glyph object to a bitmap glyph object.
*
* @inout:
* the_glyph ::
* A pointer to a handle to the target glyph.
*
* @input:
* render_mode ::
* An enumeration that describes how the data is rendered.
*
* origin ::
* A pointer to a vector used to translate the glyph image before
* rendering. Can be~0 (if no translation). The origin is expressed
* in 26.6 pixels.
*
* destroy ::
* A boolean that indicates that the original glyph image should be
* destroyed by this function. It is never destroyed in case of error.
*
* @return:
* FreeType error code. 0~means success.
*
* @note:
* This function does nothing if the glyph format isn't scalable.
*
* The glyph image is translated with the `origin` vector before
* rendering.
*
* The first parameter is a pointer to an @FT_Glyph handle that will be
* _replaced_ by this function (with newly allocated data). Typically,
* you would do something like the following (omitting error handling).
*
* ```
* FT_Glyph glyph;
* FT_BitmapGlyph glyph_bitmap;
*
*
* // load glyph
* error = FT_Load_Char( face, glyph_index, FT_LOAD_DEFAULT );
*
* // extract glyph image
* error = FT_Get_Glyph( face->glyph, &glyph );
*
* // convert to a bitmap (default render mode + destroying old)
* if ( glyph->format != FT_GLYPH_FORMAT_BITMAP )
* {
* error = FT_Glyph_To_Bitmap( &glyph, FT_RENDER_MODE_NORMAL,
* 0, 1 );
* if ( error ) // `glyph' unchanged
* ...
* }
*
* // access bitmap content by typecasting
* glyph_bitmap = (FT_BitmapGlyph)glyph;
*
* // do funny stuff with it, like blitting/drawing
* ...
*
* // discard glyph image (bitmap or not)
* FT_Done_Glyph( glyph );
* ```
*
* Here is another example, again without error handling.
*
* ```
* FT_Glyph glyphs[MAX_GLYPHS]
*
*
* ...
*
* for ( idx = 0; i < MAX_GLYPHS; i++ )
* error = FT_Load_Glyph( face, idx, FT_LOAD_DEFAULT ) ||
* FT_Get_Glyph ( face->glyph, &glyphs[idx] );
*
* ...
*
* for ( idx = 0; i < MAX_GLYPHS; i++ )
* {
* FT_Glyph bitmap = glyphs[idx];
*
*
* ...
*
* // after this call, `bitmap' no longer points into
* // the `glyphs' array (and the old value isn't destroyed)
* FT_Glyph_To_Bitmap( &bitmap, FT_RENDER_MODE_MONO, 0, 0 );
*
* ...
*
* FT_Done_Glyph( bitmap );
* }
*
* ...
*
* for ( idx = 0; i < MAX_GLYPHS; i++ )
* FT_Done_Glyph( glyphs[idx] );
* ```
*/
FT_EXPORT( FT_Error )
FT_Glyph_To_Bitmap( FT_Glyph* the_glyph,
FT_Render_Mode render_mode,
const FT_Vector* origin,
FT_Bool destroy );
/**************************************************************************
*
* @function:
* FT_Done_Glyph
*
* @description:
* Destroy a given glyph.
*
* @input:
* glyph ::
* A handle to the target glyph object. Can be `NULL`.
*/
FT_EXPORT( void )
FT_Done_Glyph( FT_Glyph glyph );
/* */
/* other helpful functions */
/**************************************************************************
*
* @section:
* computations
*
*/
/**************************************************************************
*
* @function:
* FT_Matrix_Multiply
*
* @description:
* Perform the matrix operation `b = a*b`.
*
* @input:
* a ::
* A pointer to matrix `a`.
*
* @inout:
* b ::
* A pointer to matrix `b`.
*
* @note:
* The result is undefined if either `a` or `b` is zero.
*
* Since the function uses wrap-around arithmetic, results become
* meaningless if the arguments are very large.
*/
FT_EXPORT( void )
FT_Matrix_Multiply( const FT_Matrix* a,
FT_Matrix* b );
/**************************************************************************
*
* @function:
* FT_Matrix_Invert
*
* @description:
* Invert a 2x2 matrix. Return an error if it can't be inverted.
*
* @inout:
* matrix ::
* A pointer to the target matrix. Remains untouched in case of error.
*
* @return:
* FreeType error code. 0~means success.
*/
FT_EXPORT( FT_Error )
FT_Matrix_Invert( FT_Matrix* matrix );
/* */
FT_END_HEADER
#endif /* FTGLYPH_H_ */
/* END */
/* Local Variables: */
/* coding: utf-8 */
/* End: */

Some files were not shown because too many files have changed in this diff Show More