Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

texture-compressor

Package Overview
Dependencies
Maintainers
1
Versions
31
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

texture-compressor - npm Package Compare versions

Comparing version 0.1.3 to 0.1.7

164

lib/compressWithASTC.js

@@ -9,2 +9,3 @@ // Native

const jimp = require('jimp');
const Promise = require('bluebird');

@@ -42,2 +43,11 @@ // Arguments

// ASTC using Astcenc is unique in the way that it doesn't support KTX
// Astcenc automatically flips the image during processing which has to be accounted for
// When the -flipy flag is passed no preliminary flipping
// of the image is done in order to get the inverse result
// Jimp reads the original file, flips it, Astcenc encodes it and writes it to the filesystem
// The file is read back as a buffer followed by a manual KTX container construction from the buffer
// The result is finally saved to the filesystem
function processAndReturnAsBuffer(toolPath, toolFlags = [], outputPath) {

@@ -49,80 +59,83 @@ return createProcess(toolPath, toolFlags)

function runCompression(image) {
// 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'];
return new Promise((resolve, reject) => {
// 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
// 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', image, // Encode with LDR-linear submode
output,
`${bitrateFlag}`,
'-j', os.cpus().length,
`${qualityFlag}`,
];
// Flag mapping
const flagMapping = [
'-cl', image, // 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');
}
// 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 toolPath = path.join(compressionToolDirectory, 'astcenc');
const toolFlags = flags ? splitFlagAndValue(createFlagsForTool(flags)) : [];
const combinedFlags = [...flagMapping, ...toolFlags];
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;
// 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];
// 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);
}
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
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]);
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}`);
}
fs.writeFile(output, result, 'binary', (error) => {
if (error) {
reject(console.error(error));
} else {
resolve();
console.log(`Succesfully written file to ${output}`);
}
});
});
});
});
}

@@ -167,8 +180,15 @@

} else {
// Compress flipped instead of the direct input
runCompression(`${tempDirectory}/${tempFilename}`);
// Clean up the temporary directory and the temporary image
fsExtra.remove(`${tempDirectory}/${tempFilename}`);
fsExtra.remove(tempDirectory);
// Check if the file exists
fsExtra.exists(`${tempDirectory}/${tempFilename}`, (exists) => {
if (exists) {
// Compress flipped instead of the direct input
runCompression(`${tempDirectory}/${tempFilename}`)
// Ensure final file has been written before removing the temporary file (this may be unnecessary)
.then(() => {
// Clean up the temporary directory and the temporary image
fsExtra.remove(`${tempDirectory}/${tempFilename}`);
fsExtra.remove(tempDirectory);
});
}
});
}

@@ -175,0 +195,0 @@ });

@@ -0,3 +1,5 @@

// Native
const { spawn } = require('child_process');
// Vendor
const { spawn } = require('child_process');
const Promise = require('bluebird');

@@ -4,0 +6,0 @@

{
"name": "texture-compressor",
"version": "0.1.3",
"version": "0.1.7",
"description": "CLI tool for texture compression using ASTC, ETC, PVRTC and S3TC in a KTX container.",

@@ -5,0 +5,0 @@ "main": "index.js",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc