roxify 1.6.5 → 1.6.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "roxify",
3
- "version": "1.6.5",
3
+ "version": "1.6.7",
4
4
  "type": "module",
5
5
  "description": "Ultra-lightweight PNG steganography with native Rust acceleration. Encode binary data into PNG images with zstd compression.",
6
6
  "main": "dist/index.js",
@@ -25,17 +25,19 @@
25
25
  "prebuild:pkg": "node scripts/copy-cli-binary.js",
26
26
  "build:native": "cargo build --release --lib",
27
27
  "build:native:linux": "cargo build --release --lib --target x86_64-unknown-linux-gnu",
28
+ "build:native:macos-x64": "cargo build --release --lib --target x86_64-apple-darwin",
29
+ "build:native:macos-arm": "cargo build --release --lib --target aarch64-apple-darwin",
28
30
  "build:native:windows": "cargo build --release --lib --target x86_64-pc-windows-msvc",
29
31
  "build:cli": "cargo build --release --bin roxify_native && cp target/release/roxify_native dist/roxify-cli",
30
32
  "build:cli:windows": "cargo build --release --bin roxify_native --target x86_64-pc-windows-gnu && node scripts/copy-cli-binary.js",
31
33
  "build:all": "npm run build:native && npm run build && npm run build:cli",
32
34
  "build:cross": "node scripts/build-all-platforms.js && npm run build && npm run build:cli",
33
35
  "build:native:fast": "cargo build -p roxify_native --release --lib --no-default-features",
34
- "build:native:quick-release": "cross-env FAST_RELEASE=1 cargo build --profile fastdev -p roxify_native --lib --no-default-features",
35
- "build:native:super-fast": "cross-env USE_SYSTEM_ZSTD=1 FAST_RELEASE=1 cargo build --profile fastdev -p roxify_native --lib --no-default-features -j 1",
36
- "build:native:low-cpu": "cross-env LOW_CPU=1 USE_SYSTEM_ZSTD=1 FAST_RELEASE=1 MAX_JOBS=1 node scripts/build-native-targets.cjs",
36
+ "build:native:quick-release": "FAST_RELEASE=1 cargo build --profile fastdev -p roxify_native --lib --no-default-features",
37
+ "build:native:super-fast": "USE_SYSTEM_ZSTD=1 FAST_RELEASE=1 cargo build --profile fastdev -p roxify_native --lib --no-default-features -j 1",
38
+ "build:native:low-cpu": "LOW_CPU=1 USE_SYSTEM_ZSTD=1 FAST_RELEASE=1 MAX_JOBS=1 node scripts/build-native-targets.cjs",
37
39
  "build:native:targets": "node scripts/build-native-targets.cjs",
38
- "build:native:targets:fast": "cross-env FAST_RELEASE=1 node scripts/build-native-targets.cjs",
40
+ "build:native:targets:fast": "FAST_RELEASE=1 node scripts/build-native-targets.cjs",
39
41
  "build:pkg": "npm run build && npx pkg . --target node18-win-x64 --output dist/rox.exe --compress Brotli --public",
40
42
  "postbuild:native": "node scripts/copy-native.js",
41
43
  "clean:targets": "node scripts/clean-artifacts.js",
@@ -83,7 +85,6 @@
83
85
  "license": "MIT",
84
86
  "devDependencies": {
85
87
  "@types/node": "^22.0.0",
86
- "cross-env": "^7.0.3",
87
88
  "pkg": "^5.8.1",
88
89
  "typescript": "^5.6.0"
89
90
  },
Binary file
@@ -1 +0,0 @@
1
- export declare const TEST_EMIT = 42;
@@ -1 +0,0 @@
1
- export const TEST_EMIT = 42;
@@ -1,25 +0,0 @@
1
- export interface CompressionStats {
2
- originalSize: number;
3
- compressedSize: number;
4
- ratio: number;
5
- entropyBits: number;
6
- blocksCount: number;
7
- estimatedThroughput: number;
8
- }
9
- export interface GpuInfo {
10
- available: boolean;
11
- adapterInfo?: string;
12
- }
13
- export declare class HybridCompressor {
14
- private gpuAvailable;
15
- constructor();
16
- compress(data: Buffer): Promise<Buffer>;
17
- decompress(data: Buffer): Promise<Buffer>;
18
- getStats(data: Buffer): CompressionStats;
19
- getEntropy(data: Buffer): number;
20
- getGpuStatus(): GpuInfo;
21
- isGpuAvailable(): boolean;
22
- }
23
- export declare function compressBuffer(data: Buffer): Promise<Buffer>;
24
- export declare function decompressBuffer(data: Buffer): Promise<Buffer>;
25
- export declare function analyzeCompression(data: Buffer): void;
@@ -1,90 +0,0 @@
1
- import { native } from './utils/native.js';
2
- let check_gpu_status;
3
- let entropy_estimate;
4
- let get_compression_stats;
5
- let hybrid_compress;
6
- let hybrid_decompress;
7
- try {
8
- check_gpu_status = native.check_gpu_status;
9
- entropy_estimate = native.entropy_estimate;
10
- get_compression_stats = native.get_compression_stats;
11
- hybrid_compress = native.hybrid_compress;
12
- hybrid_decompress = native.hybrid_decompress;
13
- }
14
- catch (e) {
15
- console.warn('Warning: Native module not loaded, using stubs');
16
- }
17
- export class HybridCompressor {
18
- constructor() {
19
- const status = check_gpu_status();
20
- this.gpuAvailable = status.available;
21
- if (this.gpuAvailable) {
22
- console.log(`[HybridCompressor] GPU disponible`);
23
- }
24
- else {
25
- console.log(`[HybridCompressor] GPU indisponible, fallback CPU`);
26
- }
27
- }
28
- async compress(data) {
29
- const start = performance.now();
30
- const compressed = hybrid_compress(data);
31
- const elapsed = (performance.now() - start) / 1000;
32
- const throughput = data.length / elapsed / 1e6;
33
- console.log(`[Compression] ${data.length} bytes → ${compressed.length} bytes ` +
34
- `(${((compressed.length / data.length) * 100).toFixed(2)}%) ` +
35
- `en ${elapsed.toFixed(3)}s (${throughput.toFixed(0)} Mo/s)`);
36
- return compressed;
37
- }
38
- async decompress(data) {
39
- const start = performance.now();
40
- const decompressed = hybrid_decompress(data);
41
- const elapsed = (performance.now() - start) / 1000;
42
- console.log(`[Décompression] ${data.length} bytes → ${decompressed.length} bytes ` +
43
- `en ${elapsed.toFixed(3)}s`);
44
- return decompressed;
45
- }
46
- getStats(data) {
47
- const start = performance.now();
48
- const stats = get_compression_stats(data);
49
- const elapsed = (performance.now() - start) / 1000;
50
- const throughput = data.length / elapsed / 1e6;
51
- return {
52
- originalSize: stats.original_size,
53
- compressedSize: stats.compressed_size,
54
- ratio: stats.ratio,
55
- entropyBits: stats.entropy_bits,
56
- blocksCount: stats.blocks_count,
57
- estimatedThroughput: throughput,
58
- };
59
- }
60
- getEntropy(data) {
61
- return entropy_estimate(data);
62
- }
63
- getGpuStatus() {
64
- return check_gpu_status();
65
- }
66
- isGpuAvailable() {
67
- return this.gpuAvailable;
68
- }
69
- }
70
- export async function compressBuffer(data) {
71
- const compressor = new HybridCompressor();
72
- return compressor.compress(data);
73
- }
74
- export async function decompressBuffer(data) {
75
- const compressor = new HybridCompressor();
76
- return compressor.decompress(data);
77
- }
78
- export function analyzeCompression(data) {
79
- const compressor = new HybridCompressor();
80
- console.log('\n=== Analyse de Compression ===');
81
- console.log(`Taille originale: ${(data.length / 1e6).toFixed(2)} Mo`);
82
- console.log(`Entropie: ${compressor.getEntropy(data).toFixed(2)} bits`);
83
- const stats = compressor.getStats(data);
84
- console.log(`\nStats de compression:`);
85
- console.log(` Blocks: ${stats.blocksCount}`);
86
- console.log(` Ratio: ${(stats.ratio * 100).toFixed(2)}%`);
87
- console.log(` Entropie bits: ${stats.entropyBits.toFixed(2)}`);
88
- console.log(` Débit estimé: ${stats.estimatedThroughput.toFixed(0)} Mo/s`);
89
- console.log(`\nGPU Status: ${compressor.isGpuAvailable() ? '✓ Disponible' : '✗ Indisponible'}`);
90
- }
package/dist/minpng.d.ts DELETED
@@ -1,20 +0,0 @@
1
- /**
2
- * Encode a buffer of raw RGB data into a minimal PNG (MinPNG format).
3
- *
4
- * @param rgb - Buffer of RGB data.
5
- * @param width - Image width.
6
- * @param height - Image height.
7
- * @returns Promise resolving to a PNG Buffer.
8
- */
9
- export declare function encodeMinPng(rgb: Buffer, width: number, height: number): Promise<Buffer>;
10
- /**
11
- * Decode a minimal PNG (MinPNG) buffer into raw RGB data and dimensions.
12
- *
13
- * @param pngBuf - Buffer containing a MinPNG image.
14
- * @returns Promise resolving to an object with buf, width, and height, or null if invalid.
15
- */
16
- export declare function decodeMinPng(pngBuf: Buffer): Promise<{
17
- buf: Buffer;
18
- width: number;
19
- height: number;
20
- } | null>;
package/dist/minpng.js DELETED
@@ -1,285 +0,0 @@
1
- import { deflateSync } from 'zlib';
2
- import { native } from './utils/native.js';
3
- let nativeZstdCompress = null;
4
- let nativeZstdDecompress = null;
5
- let nativeEncodePngChunks = null;
6
- try {
7
- if (native?.nativeZstdCompress) {
8
- nativeZstdCompress = native.nativeZstdCompress;
9
- }
10
- if (native?.nativeZstdDecompress) {
11
- nativeZstdDecompress = native.nativeZstdDecompress;
12
- }
13
- if (native?.encodePngChunks) {
14
- nativeEncodePngChunks = native.encodePngChunks;
15
- }
16
- }
17
- catch (e) { }
18
- const PIXEL_MAGIC = Buffer.from('MNPG');
19
- const MARKER_START = [
20
- { r: 255, g: 0, b: 0 },
21
- { r: 0, g: 255, b: 0 },
22
- { r: 0, b: 0, g: 255 },
23
- ];
24
- const MARKER_END = [...MARKER_START].reverse();
25
- function paeth(a, b, c) {
26
- const p = a + b - c;
27
- const pa = Math.abs(p - a);
28
- const pb = Math.abs(p - b);
29
- const pc = Math.abs(p - c);
30
- if (pa <= pb && pa <= pc)
31
- return a;
32
- if (pb <= pc)
33
- return b;
34
- return c;
35
- }
36
- function zigzagOrderIndices(width, height) {
37
- const len = width * height;
38
- const indices = new Int32Array(len);
39
- let i = 0;
40
- for (let y = 0; y < height; y++) {
41
- if (y % 2 === 0) {
42
- for (let x = 0; x < width; x++) {
43
- indices[i++] = y * width + x;
44
- }
45
- }
46
- else {
47
- for (let x = width - 1; x >= 0; x--) {
48
- indices[i++] = y * width + x;
49
- }
50
- }
51
- }
52
- return indices;
53
- }
54
- /**
55
- * Encode a buffer of raw RGB data into a minimal PNG (MinPNG format).
56
- *
57
- * @param rgb - Buffer of RGB data.
58
- * @param width - Image width.
59
- * @param height - Image height.
60
- * @returns Promise resolving to a PNG Buffer.
61
- */
62
- export async function encodeMinPng(rgb, width, height) {
63
- const w = width, h = height;
64
- const idx = (x, y) => (y * w + x) * 3;
65
- const residualR = new Uint8Array(w * h);
66
- const residualG = new Uint8Array(w * h);
67
- const residualB = new Uint8Array(w * h);
68
- for (let y = 0; y < h; y++) {
69
- for (let x = 0; x < w; x++) {
70
- const i = idx(x, y);
71
- const r = rgb[i];
72
- const g = rgb[i + 1];
73
- const b = rgb[i + 2];
74
- const leftI = x > 0 ? idx(x - 1, y) : -1;
75
- const upI = y > 0 ? idx(x, y - 1) : -1;
76
- const upLeftI = x > 0 && y > 0 ? idx(x - 1, y - 1) : -1;
77
- const leftR = leftI >= 0 ? rgb[leftI] : 0;
78
- const upR = upI >= 0 ? rgb[upI] : 0;
79
- const upLeftR = upLeftI >= 0 ? rgb[upLeftI] : 0;
80
- const predR = paeth(leftR, upR, upLeftR);
81
- residualR[y * w + x] = (r - predR + 256) & 0xff;
82
- const leftG = leftI >= 0 ? rgb[leftI + 1] : 0;
83
- const upG = upI >= 0 ? rgb[upI + 1] : 0;
84
- const upLeftG = upLeftI >= 0 ? rgb[upLeftI + 1] : 0;
85
- const predG = paeth(leftG, upG, upLeftG);
86
- residualG[y * w + x] = (g - predG + 256) & 0xff;
87
- const leftB = leftI >= 0 ? rgb[leftI + 2] : 0;
88
- const upB = upI >= 0 ? rgb[upI + 2] : 0;
89
- const upLeftB = upLeftI >= 0 ? rgb[upLeftI + 2] : 0;
90
- const predB = paeth(leftB, upB, upLeftB);
91
- residualB[y * w + x] = (b - predB + 256) & 0xff;
92
- }
93
- }
94
- const indices = zigzagOrderIndices(w, h);
95
- const transformed = new Uint8Array(w * h * 3);
96
- let tIdx = 0;
97
- for (let i = 0; i < indices.length; i++) {
98
- const pos = indices[i];
99
- const g = residualG[pos];
100
- const r = (residualR[pos] - g + 256) & 0xff;
101
- const b = (residualB[pos] - g + 256) & 0xff;
102
- transformed[tIdx++] = g;
103
- transformed[tIdx++] = r;
104
- transformed[tIdx++] = b;
105
- }
106
- const transformedBuf = Buffer.from(transformed);
107
- if (!nativeZstdCompress) {
108
- throw new Error('Native zstd compression not available');
109
- }
110
- const compressed = Buffer.from(nativeZstdCompress(transformedBuf, 19));
111
- const header = Buffer.alloc(4 + 1 + 4 + 4);
112
- PIXEL_MAGIC.copy(header, 0);
113
- header[4] = 1;
114
- header.writeUInt32BE(w, 5);
115
- header.writeUInt32BE(h, 9);
116
- const lenBuf = Buffer.alloc(4);
117
- lenBuf.writeUInt32BE(compressed.length, 0);
118
- const payload = Buffer.concat([header, lenBuf, compressed]);
119
- const markerStartBytes = Buffer.alloc(MARKER_START.length * 3);
120
- for (let i = 0; i < MARKER_START.length; i++) {
121
- markerStartBytes[i * 3] = MARKER_START[i].r;
122
- markerStartBytes[i * 3 + 1] = MARKER_START[i].g;
123
- markerStartBytes[i * 3 + 2] = MARKER_START[i].b;
124
- }
125
- const markerEndBytes = Buffer.alloc(MARKER_END.length * 3);
126
- for (let i = 0; i < MARKER_END.length; i++) {
127
- markerEndBytes[i * 3] = MARKER_END[i].r;
128
- markerEndBytes[i * 3 + 1] = MARKER_END[i].g;
129
- markerEndBytes[i * 3 + 2] = MARKER_END[i].b;
130
- }
131
- const dataWithMarkers = Buffer.concat([
132
- markerStartBytes,
133
- payload,
134
- markerEndBytes,
135
- ]);
136
- const bytesPerPixel = 3;
137
- const nPixels = Math.ceil(dataWithMarkers.length / bytesPerPixel);
138
- const side = Math.max(1, Math.ceil(Math.sqrt(nPixels)));
139
- const widthOut = side;
140
- const heightOut = Math.ceil(nPixels / widthOut);
141
- const rowLen = 1 + widthOut * bytesPerPixel;
142
- const raw = Buffer.alloc(rowLen * heightOut);
143
- for (let y = 0; y < heightOut; y++)
144
- raw[y * rowLen] = 0;
145
- for (let p = 0; p < nPixels; p++) {
146
- const srcIdx = p * 3;
147
- const y = Math.floor(p / widthOut);
148
- const x = p % widthOut;
149
- const dst = y * rowLen + 1 + x * 3;
150
- raw[dst] = srcIdx < dataWithMarkers.length ? dataWithMarkers[srcIdx] : 0;
151
- raw[dst + 1] =
152
- srcIdx + 1 < dataWithMarkers.length ? dataWithMarkers[srcIdx + 1] : 0;
153
- raw[dst + 2] =
154
- srcIdx + 2 < dataWithMarkers.length ? dataWithMarkers[srcIdx + 2] : 0;
155
- }
156
- const idat = deflateSync(raw, { level: 9 });
157
- const ihdr = Buffer.alloc(13);
158
- ihdr.writeUInt32BE(widthOut, 0);
159
- ihdr.writeUInt32BE(heightOut, 4);
160
- ihdr[8] = 8;
161
- ihdr[9] = 2;
162
- ihdr[10] = 0;
163
- ihdr[11] = 0;
164
- ihdr[12] = 0;
165
- const chunks = [
166
- { name: 'IHDR', data: ihdr },
167
- { name: 'IDAT', data: idat },
168
- { name: 'IEND', data: Buffer.alloc(0) },
169
- ];
170
- if (nativeEncodePngChunks) {
171
- return Buffer.from(nativeEncodePngChunks(chunks));
172
- }
173
- const PNG_SIG = Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]);
174
- const output = [PNG_SIG];
175
- for (const chunk of chunks) {
176
- const type = Buffer.from(chunk.name, 'ascii');
177
- const length = Buffer.alloc(4);
178
- length.writeUInt32BE(chunk.data.length, 0);
179
- const crcData = Buffer.concat([type, chunk.data]);
180
- const crc = Buffer.alloc(4);
181
- const crc32fast = native?.nativeCrc32;
182
- const crcVal = crc32fast ? crc32fast(crcData) : 0;
183
- crc.writeUInt32BE(crcVal, 0);
184
- output.push(length, type, chunk.data, crc);
185
- }
186
- return Buffer.concat(output);
187
- }
188
- /**
189
- * Decode a minimal PNG (MinPNG) buffer into raw RGB data and dimensions.
190
- *
191
- * @param pngBuf - Buffer containing a MinPNG image.
192
- * @returns Promise resolving to an object with buf, width, and height, or null if invalid.
193
- */
194
- export async function decodeMinPng(pngBuf) {
195
- const rawData = native.sharpToRaw(pngBuf);
196
- const data = rawData.pixels;
197
- const currentWidth = rawData.width;
198
- const currentHeight = rawData.height;
199
- const rawRGB = Buffer.alloc(currentWidth * currentHeight * 3);
200
- for (let i = 0; i < currentWidth * currentHeight; i++) {
201
- rawRGB[i * 3] = data[i * 3];
202
- rawRGB[i * 3 + 1] = data[i * 3 + 1];
203
- rawRGB[i * 3 + 2] = data[i * 3 + 2];
204
- }
205
- function findMarkerStart(buf) {
206
- for (let i = 0; i <= buf.length - MARKER_START.length * 3; i += 3) {
207
- let ok = true;
208
- for (let m = 0; m < MARKER_START.length; m++) {
209
- const j = i + m * 3;
210
- if (buf[j] !== MARKER_START[m].r ||
211
- buf[j + 1] !== MARKER_START[m].g ||
212
- buf[j + 2] !== MARKER_START[m].b) {
213
- ok = false;
214
- break;
215
- }
216
- }
217
- if (ok)
218
- return i + MARKER_START.length * 3;
219
- }
220
- return -1;
221
- }
222
- const startIdxBytes = findMarkerStart(rawRGB);
223
- if (startIdxBytes === -1)
224
- return null;
225
- const headerStart = startIdxBytes;
226
- if (headerStart + 13 > rawRGB.length)
227
- return null;
228
- if (!rawRGB.subarray(headerStart, headerStart + 4).equals(PIXEL_MAGIC))
229
- return null;
230
- const origW = rawRGB.readUInt32BE(headerStart + 5);
231
- const origH = rawRGB.readUInt32BE(headerStart + 9);
232
- const compressedLen = rawRGB.readUInt32BE(headerStart + 13);
233
- const compStart = headerStart + 17;
234
- if (compStart + compressedLen > rawRGB.length)
235
- return null;
236
- const compressed = rawRGB.subarray(compStart, compStart + compressedLen);
237
- if (!nativeZstdDecompress) {
238
- throw new Error('Native zstd decompression not available');
239
- }
240
- const decompressed = Buffer.from(nativeZstdDecompress(compressed));
241
- const indices = zigzagOrderIndices(origW, origH);
242
- const residualR = new Uint8Array(origW * origH);
243
- const residualG = new Uint8Array(origW * origH);
244
- const residualB = new Uint8Array(origW * origH);
245
- let p = 0;
246
- for (let i = 0; i < indices.length; i++) {
247
- if (p + 3 > decompressed.length)
248
- break;
249
- const g = decompressed[p++];
250
- const rminusg = decompressed[p++];
251
- const bminusg = decompressed[p++];
252
- const pos = indices[i];
253
- residualG[pos] = g;
254
- residualR[pos] = (rminusg + g) & 0xff;
255
- residualB[pos] = (bminusg + g) & 0xff;
256
- }
257
- const out = Buffer.alloc(origW * origH * 3);
258
- for (let y = 0; y < origH; y++) {
259
- for (let x = 0; x < origW; x++) {
260
- const pos = y * origW + x;
261
- const leftPos = x > 0 ? y * origW + (x - 1) : -1;
262
- const upPos = y > 0 ? (y - 1) * origW + x : -1;
263
- const upLeftPos = x > 0 && y > 0 ? (y - 1) * origW + (x - 1) : -1;
264
- const leftR = leftPos >= 0 ? out[leftPos * 3] : 0;
265
- const upR = upPos >= 0 ? out[upPos * 3] : 0;
266
- const upLeftR = upLeftPos >= 0 ? out[upLeftPos * 3] : 0;
267
- const predR = paeth(leftR, upR, upLeftR);
268
- const r = (residualR[pos] + predR) & 0xff;
269
- const leftG = leftPos >= 0 ? out[leftPos * 3 + 1] : 0;
270
- const upG = upPos >= 0 ? out[upPos * 3 + 1] : 0;
271
- const upLeftG = upLeftPos >= 0 ? out[upLeftPos * 3 + 1] : 0;
272
- const predG = paeth(leftG, upG, upLeftG);
273
- const g = (residualG[pos] + predG) & 0xff;
274
- const leftB = leftPos >= 0 ? out[leftPos * 3 + 2] : 0;
275
- const upB = upPos >= 0 ? out[upPos * 3 + 2] : 0;
276
- const upLeftB = upLeftPos >= 0 ? out[upLeftPos * 3 + 2] : 0;
277
- const predB = paeth(leftB, upB, upLeftB);
278
- const b = (residualB[pos] + predB) & 0xff;
279
- out[pos * 3] = r;
280
- out[pos * 3 + 1] = g;
281
- out[pos * 3 + 2] = b;
282
- }
283
- }
284
- return { buf: out, width: origW, height: origH };
285
- }
package/dist/rox.exe DELETED
Binary file
Binary file
Binary file