texture-compressor
Advanced tools
Comparing version 0.0.10 to 0.1.0
// Native | ||
const fs = require('fs'); | ||
const os = require('os'); | ||
const path = require('path'); | ||
// Vendor | ||
const fsExtra = require('fs-extra'); | ||
const jimp = require('jimp'); | ||
// Arguments | ||
@@ -31,7 +36,97 @@ const { | ||
splitFlagAndValue, | ||
getTempDirectory, | ||
getTempFilename, | ||
} = require('./utilities'); | ||
function processAndReturnAsBuffer(toolPath, toolFlags = [], outputPath) { | ||
return createProcess(toolPath, toolFlags) | ||
.then(() => fsExtra.readFile(outputPath)); | ||
} | ||
function runCompression(flippedImage) { | ||
// Bitrate flag (2.0 bbp = 8x8 blocksize) | ||
const bitrateFlag = convertNumberToDecimalString(bitrate); | ||
const blockSizes = ['4x4', '5x4', '5x5', '6x5', '6x6', '8x5', '8x6', '8x8', '10x5', '10x6', '10x8', '10x10', '12x10', '12x12']; | ||
// Quality flag | ||
const qualityOptions = ['-veryfast', '-fast', '-medium', '-thorough', '-exhaustive']; | ||
const qualityPicker = (Math.floor(quality / 2.1)); | ||
const qualityFlag = qualityOptions[qualityPicker]; // One of the five options | ||
// Flag mapping | ||
const flagMapping = [ | ||
'-cl', flippedImage, // Encode with LDR-linear submode | ||
output, | ||
`${bitrateFlag}`, | ||
'-j', os.cpus().length, | ||
`${qualityFlag}`, | ||
]; | ||
// Transparent mapping, tool doesn't accept empty flags | ||
if (transparent) { | ||
flagMapping.push('-alphablend'); | ||
} | ||
const toolPath = path.join(compressionToolDirectory, 'astcenc'); | ||
const toolFlags = flags ? splitFlagAndValue(createFlagsForTool(flags)) : []; | ||
const combinedFlags = [...flagMapping, ...toolFlags]; | ||
// Astcenc does not support writing to KTX by directly so we prepend it with a KTX header | ||
processAndReturnAsBuffer(toolPath, combinedFlags, output) | ||
.then((buffer) => { | ||
// https://github.com/AnalyticalGraphicsInc/gltf-pipeline/blob/a28152503f28be88051de8df85f5f6a350169e8b/lib/compressTexture.js#L436-L485 | ||
const blockWidth = buffer.readUInt8(4); | ||
const blockHeight = buffer.readUInt8(5); | ||
const xsize = [buffer.readUInt8(7), buffer.readUInt8(8), buffer.readUInt8(9)]; | ||
const ysize = [buffer.readUInt8(10), buffer.readUInt8(11), buffer.readUInt8(12)]; | ||
const pixelHeight = xsize[0] + 256 * xsize[1] + 65536 * xsize[2]; | ||
const pixelWidth = ysize[0] + 256 * ysize[1] + 65536 * ysize[2]; | ||
const blockSize = `${blockWidth}x${blockHeight}`; | ||
const glInternalFormat = 0x93B0 + blockSizes.indexOf(blockSize); | ||
const glBaseInternalFormat = 0x1908; // gl.RGBA | ||
const imageData = buffer.slice(16); | ||
const imageSize = imageData.length; | ||
// KTX header | ||
const ktxHeader = Buffer.allocUnsafe(68); | ||
const identifier = [0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A]; | ||
for (let i = 0; i < 12; i++) { | ||
ktxHeader.writeUInt8(identifier[i], i); | ||
} | ||
ktxHeader.writeUInt32LE(0x04030201, 12); // endianness | ||
ktxHeader.writeUInt32LE(0, 16); // glType | ||
ktxHeader.writeUInt32LE(1, 20); // glTypeSize | ||
ktxHeader.writeUInt32LE(0, 24); // glFormat | ||
ktxHeader.writeUInt32LE(glInternalFormat, 28); // glInternalFormat | ||
ktxHeader.writeUInt32LE(glBaseInternalFormat, 32); // glBaseInternalFormat | ||
ktxHeader.writeUInt32LE(pixelWidth, 36); // pixelWidth | ||
ktxHeader.writeUInt32LE(pixelHeight, 40); // pixelHeight | ||
ktxHeader.writeUInt32LE(0, 44); // pixelDepth | ||
ktxHeader.writeUInt32LE(0, 48); // numberOfArrayElements | ||
ktxHeader.writeUInt32LE(1, 52); // numberOfFaces | ||
ktxHeader.writeUInt32LE(1, 56); // numberOfMipmapLevels | ||
ktxHeader.writeUInt32LE(0, 60); // bytesOfKeyValueData | ||
ktxHeader.writeUInt32LE(imageSize, 64); // imageSize | ||
console.log(blockSize, imageSize); | ||
const result = Buffer.concat([ktxHeader, imageData]); | ||
fs.writeFile(output, result, 'binary', (error) => { | ||
if (error) { | ||
console.error(error); | ||
} else { | ||
console.log(`Succesfully written file to ${output}`); | ||
} | ||
}); | ||
}); | ||
} | ||
const compressWithASTC = () => { | ||
const inputFileExtension = getFileExtension(input); | ||
const outputFileExtension = getFileExtension(output); | ||
const tempDirectory = getTempDirectory(); | ||
const tempFilename = getTempFilename(); | ||
@@ -45,31 +140,35 @@ if (!ASTC_SUPPORTED_OUTPUT_TYPES.includes(outputFileExtension)) { | ||
if (ASTC_SUPPORTED_INPUT_TYPES.includes(inputFileExtension)) { | ||
// Bitrate flag (2.0 bbp = 8x8 blocksize) | ||
// 4x4, 5x4, 5x5, 6x5, 6x6, 8x5, 8x6, 8x8, 10x5, 10x6, 10x8, 10x10, 12x10, 12x12 | ||
const bitrateFlag = convertNumberToDecimalString(bitrate); | ||
// File reading necssary for temporary Y flipping because Astcenc flips the image internally | ||
jimp.read(input) | ||
.then((file) => { | ||
// Flip Y (Astcenc flips the image during encoding) | ||
file.flip(false, true); | ||
// Quality flag | ||
const qualityOptions = ['-veryfast', '-fast', '-medium', '-thorough', '-exhaustive']; | ||
const qualityPicker = (Math.floor(quality / 2.1)); | ||
const qualityFlag = qualityOptions[qualityPicker]; // One of the five options | ||
// Write temporary file to a temporary directory | ||
fsExtra.ensureDir(tempDirectory) | ||
.then(() => { | ||
file.getBuffer(jimp.AUTO, (error, buffer) => { | ||
if (error) { | ||
console.error(error); | ||
} | ||
// Flag mapping | ||
const flagMapping = [ | ||
'-cl', input, | ||
output, | ||
`${bitrateFlag}`, | ||
'-j', os.cpus().length, | ||
`${qualityFlag}`, | ||
]; | ||
// Write file out manually as jimp.write doesn't offer a callback after writing | ||
fs.writeFile(`${tempDirectory}/${tempFilename}`, buffer, (error) => { | ||
if (error) { | ||
console.error(error); | ||
} else { | ||
// Compress flipped instead of the direct input | ||
runCompression(`${tempDirectory}/${tempFilename}`); | ||
// Transparent mapping, tool doesn't accept empty flags | ||
if (transparent) { | ||
flagMapping.push('-alphablend'); | ||
} | ||
const toolPath = path.join(compressionToolDirectory, 'astcenc'); | ||
const toolFlags = flags ? splitFlagAndValue(createFlagsForTool(flags)) : []; | ||
const combinedFlags = [...flagMapping, ...toolFlags]; | ||
createProcess(toolPath, combinedFlags); | ||
// Clean up the temporary directory and the temporary image | ||
fsExtra.remove(`${tempDirectory}/${tempFilename}`); | ||
fsExtra.remove(tempDirectory); | ||
} | ||
}); | ||
}); | ||
}); | ||
}) | ||
.catch((error) => { | ||
console.error(error); | ||
}); | ||
} else { | ||
@@ -76,0 +175,0 @@ console.error(`${inputFileExtension} is not supported.`); |
// Native | ||
const os = require('os'); | ||
const path = require('path'); | ||
@@ -49,15 +48,21 @@ | ||
} else if (compression === 'etc2') { | ||
compressionFlag = (transparent) ? 'RGBA8' : 'RGB8'; | ||
compressionFlag = (transparent) ? 'ETC2_RGBA' : 'ETC2_RGB'; | ||
} | ||
// Quality flag | ||
const qualityOptions = ['etcfast', 'etcslow', 'etcfastperceptual', 'etcslowperceptual']; | ||
const qualityPicker = (Math.floor(quality / 2.1)); | ||
const qualityFlag = qualityOptions[qualityPicker]; // One of the five options | ||
// Flag mapping | ||
const flagMapping = [ | ||
input, | ||
'-format', `${compressionFlag}`, | ||
'-effort', `${quality * 10.0}`, | ||
'-jobs', os.cpus().length, | ||
'-output', output, | ||
'-i', input, | ||
'-o', output, | ||
'-f', `${compressionFlag}`, | ||
'-q', `${qualityFlag}`, | ||
'-square', '+', | ||
'-pot', '+', | ||
]; | ||
const toolPath = path.join(compressionToolDirectory, 'EtcTool'); | ||
const toolPath = path.join(compressionToolDirectory, 'PVRTexToolCLI'); | ||
const toolFlags = flags ? splitFlagAndValue(createFlagsForTool(flags)) : []; | ||
@@ -64,0 +69,0 @@ |
@@ -46,11 +46,11 @@ // Native | ||
if (transparent) { | ||
if (bitrate === 2) { | ||
if (parseFloat(bitrate) === 2) { | ||
compressionFlag = 'PVRTC1_2'; | ||
} else if (bitrate === 4) { | ||
} else if (parseFloat(bitrate) === 4) { | ||
compressionFlag = 'PVRTC1_4'; | ||
} | ||
} else if (!transparent) { | ||
if (bitrate === 2) { | ||
if (parseFloat(bitrate) === 2) { | ||
compressionFlag = 'PVRTC1_2_RGB'; | ||
} else if (bitrate === 4) { | ||
} else if (parseFloat(bitrate) === 4) { | ||
compressionFlag = 'PVRTC1_4_RGB'; | ||
@@ -57,0 +57,0 @@ } |
@@ -47,10 +47,3 @@ // Native | ||
if (compression === 'dxt1') { | ||
if (transparent && outputFileExtension === '.crn') { | ||
console.log('Crunch compressor does not support DXT1 with alpha, the alpha channel will be ignored.'); | ||
compressionFlag = '-DXT1'; | ||
} else if (transparent) { | ||
compressionFlag = '-DXT1A'; | ||
} else { | ||
compressionFlag = '-DXT1'; | ||
} | ||
compressionFlag = transparent ? '-DXT1A' : '-DXT1'; | ||
} else if (compression === 'dxt3') { | ||
@@ -63,13 +56,6 @@ compressionFlag = '-DXT3'; | ||
// Quality flag | ||
let CRNQualityFlag; | ||
let DXTQualityFlag; | ||
const qualityOptions = ['superfast', 'fast', 'normal', 'better', 'uber']; | ||
const qualityPicker = (Math.floor(quality / 2.1)); | ||
const DXTQualityFlag = qualityOptions[qualityPicker]; // One of the five options | ||
if (outputFileExtension === '.crn') { | ||
CRNQualityFlag = quality * 25.5; // [0 - 255] | ||
} else { | ||
const qualityOptions = ['superfast', 'fast', 'normal', 'better', 'uber']; | ||
const qualityPicker = (Math.floor(quality / 2.1)); | ||
DXTQualityFlag = qualityOptions[qualityPicker]; // One of the five options | ||
} | ||
// Flag mapping | ||
@@ -79,5 +65,5 @@ const flagMapping = [ | ||
'-out', output, | ||
'-fileformat', 'ktx', | ||
`${compressionFlag}`, | ||
CRNQualityFlag === Number ? '-quality' : '-dxtQuality', | ||
CRNQualityFlag === Number ? `${CRNQualityFlag}` : `${DXTQualityFlag}`, | ||
`${DXTQualityFlag}`, | ||
'-helperThreads', os.cpus().length, | ||
@@ -84,0 +70,0 @@ '-mipMode', 'None', |
@@ -9,17 +9,17 @@ const constants = { | ||
ASTC_SUPPORTED_INPUT_TYPES: ['.jpeg', '.jpg', '.png', '.bmp', '.gif'], | ||
ASTC_SUPPORTED_OUTPUT_TYPES: ['.dds'], | ||
ASTC_SUPPORTED_OUTPUT_TYPES: ['.ktx'], | ||
ETC_COMPRESSION_TYPES: ['etc1', 'etc2'], | ||
ETC_SUPPORTED_INPUT_TYPES: ['.png'], | ||
ETC_SUPPORTED_OUTPUT_TYPES: ['.dds'], | ||
ETC_SUPPORTED_INPUT_TYPES: ['.jpeg', '.jpg', '.png', '.bmp'], | ||
ETC_SUPPORTED_OUTPUT_TYPES: ['.ktx'], | ||
PVR_COMPRESSION_TYPES: ['pvrtc1'], | ||
PVR_SUPPORTED_INPUT_TYPES: ['.jpeg', '.jpg', '.png', '.bmp'], | ||
PVR_SUPPORTED_OUTPUT_TYPES: ['.dds', '.pvr'], | ||
PVR_SUPPORTED_OUTPUT_TYPES: ['.ktx'], | ||
S3TC_COMPRESSION_TYPES: ['dxt1', 'dxt3', 'dxt5'], | ||
S3TC_SUPPORTED_INPUT_TYPES: ['.jpeg', '.jpg', '.png', '.bmp', '.gif'], | ||
S3TC_SUPPORTED_OUTPUT_TYPES: ['.dds', '.crn'], | ||
S3TC_SUPPORTED_OUTPUT_TYPES: ['.ktx'], | ||
}; | ||
module.exports = constants; |
// Vendor | ||
const { | ||
spawn, | ||
} = require('child_process'); | ||
const { spawn } = require('child_process'); | ||
const Promise = require('bluebird'); | ||
@@ -6,0 +4,0 @@ |
@@ -7,2 +7,3 @@ // Native | ||
const imageSize = require('image-size'); | ||
const uuid = require('uuid'); | ||
@@ -32,4 +33,14 @@ const utilities = { | ||
splitFlagAndValue: flags => [].concat(...flags.map(flag => flag.split(' '))), | ||
getTempFilename() { | ||
return uuid.v4(); | ||
}, | ||
getTempDirectory() { | ||
const tempDirectory = os.tmpdir(); | ||
const randomId = uuid.v4(); | ||
return path.join(tempDirectory, randomId); | ||
}, | ||
}; | ||
module.exports = utilities; |
{ | ||
"name": "texture-compressor", | ||
"version": "0.0.10", | ||
"description": "CLI tool for texture compression using ASTC, ETC, PVRTC and S3TC in DDS or PVR containers.", | ||
"version": "0.1.0", | ||
"description": "CLI tool for texture compression using ASTC, ETC, PVRTC and S3TC in a KTX container.", | ||
"main": "index.js", | ||
"scripts": { | ||
"start": "http-server --cors -s -o", | ||
"lint": "eslint lib/**/*.js", | ||
@@ -18,3 +19,6 @@ "deploy": "npm version patch && npm publish && git push origin" | ||
"bluebird": "^3.5.1", | ||
"image-size": "^0.6.1" | ||
"fs-extra": "^5.0.0", | ||
"image-size": "^0.6.1", | ||
"jimp": "^0.2.28", | ||
"uuid": "^3.2.1" | ||
}, | ||
@@ -24,8 +28,5 @@ "devDependencies": { | ||
"eslint-config-airbnb-base": "^12.1.0", | ||
"eslint-plugin-import": "^2.8.0" | ||
"eslint-plugin-import": "^2.8.0", | ||
"http-server": "^0.11.1" | ||
}, | ||
"directories": { | ||
"doc": "docs", | ||
"lib": "lib" | ||
}, | ||
"repository": { | ||
@@ -32,0 +33,0 @@ "type": "git", |
@@ -7,3 +7,3 @@ # Texture compressor | ||
CLI tool for texture compression using ASTC, ETC, PVRTC and S3TC in DDS or PVR containers. | ||
CLI tool for texture compression using ASTC, ETC, PVRTC and S3TC in a KTX container. | ||
@@ -18,13 +18,65 @@ Easily compress for all hardware using sensible defaults but with the option to pass any custom flag directly to the tool. | ||
## Live demo | ||
[Live demo](https://timvanscherpenzeel.github.io/texture-compressor/) | ||
## Docs | ||
The source code of the `KTX loader` is available on in [docs/main.js](https://github.com/TimvanScherpenzeel/texture-compressor/blob/master/docs/main.js) in the `docs` folder. | ||
## Support table | ||
| Device | OS | OS version | Browser | Browser version | ASTC | ETC | ETC1 | S3TC | PVRTC | | ||
| ------------------------| ------- | ---------- | ------------- | --------------- | ---- | --- | ---- | ---- | ----- | | ||
| Apple iPad 5th | iOS | 11.0.3 | Mobile Safari | 11.0 | | | | | X | | ||
| Apple iPad Air 2 | iOS | 8.4 | Mobile Safari | 8.0 | | | | | X | | ||
| Apple iPad Mini 3 | iOS | 8.1.2 | Mobile Safari | 8.0 | | | | | X | | ||
| Apple iPad Pro | iOS | 11.2.1 | Mobile Safari | 11.0 | | | | | X | | ||
| Apple iPhone 5S | iOS | 8.1.3 | Mobile Safari | 8.0 | | | | | X | | ||
| Apple iPhone 6 Plus | iOS | 8.1 | Mobile Safari | 8.0 | | | | | X | | ||
| Apple iPhone 6 | iOS | 8.1.3 | Mobile Safari | 8.0 | | | | | X | | ||
| Apple iPhone 6S Plus | iOS | 9.0.1 | Mobile Safari | 9.0 | | | | | X | | ||
| Apple iPhone 6S | iOS | 9.1 | Mobile Safari | 9.0 | | | | | X | | ||
| Apple iPhone 7 | iOS | 10.3.1 | Mobile Safari | 10.0 | | | | | X | | ||
| Apple iPhone 8 | iOS | 11.0 | Mobile Safari | 11.0 | | | | | X | | ||
| Apple iPhone 8 | iOS | 11.0 | Mobile Safari | 11.0 | | | | | X | | ||
| Apple iPhone SE | iOS | 11.2.1 | Mobile Safari | 11.0 | | | | | X | | ||
| Apple iPhone X | iOS | 11.2 | Mobile Safari | 11.0 | | | | | X | | ||
| Google Nexus 5X | Android | 7.0 | Chrome | 63.0.3239.111 | X | | X | | | | ||
| Google Nexus 6P | Android | 7.0 | Chrome | 63.0.3239.111 | X | | X | | | | ||
| Google Pixel 2 | Android | 8.0.0 | Chrome | 63.0.3239.111 | X | | X | | | | ||
| Google Pixel 2 | Android | 8.0.0 | Firefox | 51.0 | | X | X | | | | ||
| Google Pixel | Android | 7.1 | Chrome | 63.0.3239.111 | X | | X | | | | ||
| Google Pixel | Android | 8.0.0 | Chrome | 63.0.3239.111 | X | | X | | | | ||
| Google Pixel | Android | 8.0.0 | Firefox | 51.0 | | X | X | | | | ||
| LG G5 | Android | 6.0.1 | Chrome | 63.0.3239.111 | X | | X | | | | ||
| MacOS High Sierra | Mac OS | 10.13.3 | Chrome | 65.0.3325.181 | | | | X | | | ||
| MacOS High Sierra | Mac OS | 10.13 | Firefox | 59.0 | | | | X | | | ||
| MacOS High Sierra | Mac OS | 10.13.3 | Safari | 11.0.3 | | | | X | | | ||
| Motorola Moto X 2nd Gen | Android | 6.0 | Chrome | 63.0.3239.111 | | | X | | | | ||
| Samsung S6 | Android | 5.0.2 | Chrome | 63.0.3239.111 | X | | X | | | | ||
| Samsung S7 | Android | 6.0.1 | Chrome | 63.0.3239.111 | X | | X | | | | ||
| Samsung S7 | Android | 6.0.1 | Firefox | 51.0 | | X | X | | | | ||
| Samsung S8 | Android | 7.0 | Chrome | 63.0.3239.111 | X | | X | | | | ||
| Samsung S8 | Android | 7.0 | Firefox | 51.0 | | X | X | | | | ||
| Samsung S8+ | Android | 7.0 | Chrome | 63.0.3239.111 | X | | X | | | | ||
| Samsung S8+ | Android | 7.0 | Firefox | 51.0 | | X | X | | | | ||
| Windows 10 | Windows | 10 | Chrome | 65.0.3325.146 | | | X | X | | | ||
| Windows 10 | Windows | 10 | Edge | 14.14393 | | | | X | | | ||
| Windows 10 | Windows | 10 | Edge | 15.15063 | | | | X | | | ||
| Windows 10 | Windows | 10 | Edge | 16.16299 | | | | X | | | ||
| Windows 10 | Windows | 10 | Firefox | 59.0 | | | | X | | | ||
| Windows 10 | Windows | 10 | IE | 11.0 | | | | X | | | ||
| Windows 7 | Windows | 7 | IE | 10.0 | | | | | | | ||
| Windows 7 | Windows | 7 | IE | 11.0 | | | | X | | | ||
| Windows 8 | Windows | 8 | IE | 10.0 | | | | | | | ||
## Example | ||
### ASTC | ||
```sh | ||
# ASTC - Supported by all iOS devices with an A8 processor or higher (iPhone 6+) | ||
# Astcenc - https://github.com/ARM-software/astc-encoder | ||
# DDS container | ||
# Extension - https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_astc/ | ||
$ node ./bin/texture-compressor -i ./example/example.png -o ./example/example-astc.dds -m astc -c astc | ||
$ node ./bin/texture-compressor -i ./docs/example/example.png -o ./docs/example/example-astc.ktx -m astc -c astc | ||
``` | ||
@@ -35,8 +87,8 @@ | ||
```sh | ||
# ETC1 & ETC2 - Supported by most Android devices | ||
# Etc2comp - https://github.com/google/etc2comp | ||
# DDS container | ||
# PVRTexTool - https://community.imgtec.com/developers/powervr/tools/pvrtextool/ | ||
# Extension - https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_etc/ | ||
$ node ./bin/texture-compressor -i ./example/example.png -o ./example/example-etc1.dds -m etc -c etc1 | ||
$ node ./bin/texture-compressor -i ./docs/example/example.png -o ./docs/example/example-etc1.ktx -m etc -c etc1 | ||
$ node ./bin/texture-compressor -i ./docs/example/example.png -o ./docs/example/example-etc2.ktx -m etc -c etc2 | ||
``` | ||
@@ -47,8 +99,6 @@ | ||
```sh | ||
# PVRTC1 - Supported by all iOS devices and some Android devices | ||
# PVRTexTool - https://community.imgtec.com/developers/powervr/tools/pvrtextool/ | ||
# PVR container | ||
# Extension - http://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_pvrtc/ | ||
$ node ./bin/texture-compressor -i ./example/example.png -o ./example/example-pvrtc1.pvr -m pvr -c pvrtc1 | ||
$ node ./bin/texture-compressor -i ./docs/example/example.png -o ./docs/example/example-pvrtc1.ktx -m pvr -c pvrtc1 | ||
``` | ||
@@ -59,8 +109,10 @@ | ||
```sh | ||
# DXT1 & DXT3 & DXT5 - Supported by all desktop devices and some Android devices | ||
# Crunch - https://code.google.com/archive/p/crunch/ | ||
# CRN & DDS container | ||
# Extension - http://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_s3tc/ | ||
$ node ./bin/texture-compressor -i ./example/example.png -o ./example/example-dxt5.dds -m s3tc -c dxt5 | ||
$ node ./bin/texture-compressor -i ./docs/example/example.png -o ./docs/example/example-dxt1.ktx -m s3tc -c dxt1 | ||
$ node ./bin/texture-compressor -i ./docs/example/example.png -o ./docs/example/example-dxt3.ktx -m s3tc -c dxt3 | ||
$ node ./bin/texture-compressor -i ./docs/example/example.png -o ./docs/example/example-dxt5.ktx -m s3tc -c dxt5 | ||
``` | ||
@@ -72,4 +124,4 @@ | ||
-c, --compression ['astc', 'etc1', 'etc2', 'pvrtc1', 'dxt1', 'dxt3', 'dxt5'] [required] | ||
-i, --input [example: ./example/example.png] [required] | ||
-o, --output [example: ./example/example.dds] [required] | ||
-i, --input [example: ./docs/example/example.png] [required] | ||
-o, --output [example: ./docs/example/example.ktx] [required] | ||
-m, --method ['astc', 'etc', 'pvr', 's3tc'] [required] | ||
@@ -98,4 +150,3 @@ | ||
- [astcenc](https://raw.githubusercontent.com/ARM-software/astc-encoder/master/license.txt) | ||
- [EtcTool](https://raw.githubusercontent.com/google/etc2comp/master/LICENSE) | ||
- [PVRTexToolCLI](https://community.imgtec.com/developers/powervr/sdk-end-user-licence-agreement/) | ||
- [crunch](https://raw.githubusercontent.com/Unvanquished/crunch/master/license.txt) |
Native code
Supply chain riskContains native code (e.g., compiled binaries or shared libraries). Including native code can obscure malicious behavior.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 2 instances in 1 package
Native code
Supply chain riskContains native code (e.g., compiled binaries or shared libraries). Including native code can obscure malicious behavior.
Found 1 instance in 1 package
53
1315
146
34633879
6
4
123206
2
36
+ Addedfs-extra@^5.0.0
+ Addedjimp@^0.2.28
+ Addeduuid@^3.2.1
+ Addedajv@6.12.6(transitive)
+ Addedasn1@0.2.6(transitive)
+ Addedassert-plus@1.0.0(transitive)
+ Addedasynckit@0.4.0(transitive)
+ Addedaws-sign2@0.7.0(transitive)
+ Addedaws4@1.13.2(transitive)
+ Addedbcrypt-pbkdf@1.0.2(transitive)
+ Addedbignumber.js@2.4.0(transitive)
+ Addedbmp-js@0.0.3(transitive)
+ Addedbuffer-equal@0.0.1(transitive)
+ Addedcaseless@0.12.0(transitive)
+ Addedcentra@2.7.0(transitive)
+ Addedcombined-stream@1.0.8(transitive)
+ Addedcore-util-is@1.0.2(transitive)
+ Addeddashdash@1.14.1(transitive)
+ Addeddelayed-stream@1.0.0(transitive)
+ Addeddom-walk@0.1.2(transitive)
+ Addedecc-jsbn@0.1.2(transitive)
+ Addedes6-promise@3.3.1(transitive)
+ Addedexif-parser@0.1.12(transitive)
+ Addedextend@3.0.2(transitive)
+ Addedextsprintf@1.3.0(transitive)
+ Addedfast-deep-equal@3.1.3(transitive)
+ Addedfast-json-stable-stringify@2.1.0(transitive)
+ Addedfile-type@3.9.0(transitive)
+ Addedfollow-redirects@1.15.9(transitive)
+ Addedforever-agent@0.6.1(transitive)
+ Addedform-data@2.3.3(transitive)
+ Addedfs-extra@5.0.0(transitive)
+ Addedgetpass@0.1.7(transitive)
+ Addedglobal@4.4.0(transitive)
+ Addedgraceful-fs@4.2.11(transitive)
+ Addedhar-schema@2.0.0(transitive)
+ Addedhar-validator@5.1.5(transitive)
+ Addedhttp-signature@1.2.0(transitive)
+ Addedip-regex@1.0.3(transitive)
+ Addedis-function@1.0.2(transitive)
+ Addedis-typedarray@1.0.0(transitive)
+ Addedisstream@0.1.2(transitive)
+ Addedjimp@0.2.28(transitive)
+ Addedjpeg-js@0.2.0(transitive)
+ Addedjsbn@0.1.1(transitive)
+ Addedjson-schema@0.4.0(transitive)
+ Addedjson-schema-traverse@0.4.1(transitive)
+ Addedjson-stringify-safe@5.0.1(transitive)
+ Addedjsonfile@4.0.0(transitive)
+ Addedjsprim@1.4.2(transitive)
+ Addedload-bmfont@1.4.2(transitive)
+ Addedmime@1.6.0(transitive)
+ Addedmime-db@1.52.0(transitive)
+ Addedmime-types@2.1.35(transitive)
+ Addedmin-document@2.19.0(transitive)
+ Addedminimist@0.0.8(transitive)
+ Addedmkdirp@0.5.1(transitive)
+ Addedoauth-sign@0.9.0(transitive)
+ Addedparse-bmfont-ascii@1.0.6(transitive)
+ Addedparse-bmfont-binary@1.0.6(transitive)
+ Addedparse-bmfont-xml@1.1.6(transitive)
+ Addedparse-headers@2.0.5(transitive)
+ Addedperformance-now@2.1.0(transitive)
+ Addedphin@3.7.1(transitive)
+ Addedpixelmatch@4.0.2(transitive)
+ Addedpngjs@3.4.0(transitive)
+ Addedprocess@0.11.10(transitive)
+ Addedpsl@1.15.0(transitive)
+ Addedpunycode@2.3.1(transitive)
+ Addedqs@6.5.3(transitive)
+ Addedread-chunk@1.0.1(transitive)
+ Addedrequest@2.88.2(transitive)
+ Addedsafe-buffer@5.2.1(transitive)
+ Addedsafer-buffer@2.1.2(transitive)
+ Addedsax@1.4.1(transitive)
+ Addedsshpk@1.18.0(transitive)
+ Addedstream-to@0.2.2(transitive)
+ Addedstream-to-buffer@0.1.0(transitive)
+ Addedtinycolor2@1.6.0(transitive)
+ Addedtough-cookie@2.5.0(transitive)
+ Addedtunnel-agent@0.6.0(transitive)
+ Addedtweetnacl@0.14.5(transitive)
+ Addeduniversalify@0.1.2(transitive)
+ Addeduri-js@4.4.1(transitive)
+ Addedurl-regex@3.2.0(transitive)
+ Addeduuid@3.4.0(transitive)
+ Addedverror@1.10.0(transitive)
+ Addedxhr@2.6.0(transitive)
+ Addedxml-parse-from-string@1.0.1(transitive)
+ Addedxml2js@0.5.0(transitive)
+ Addedxmlbuilder@11.0.1(transitive)
+ Addedxtend@4.0.2(transitive)