lightdrift-libraw 1.0.0-alpha.2 → 1.0.0-alpha.3

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/README.md CHANGED
@@ -20,6 +20,8 @@ A high-performance Node.js Native Addon for processing RAW image files using the
20
20
  - ✅ **AI-Powered Settings** - 🆕 Automatic quality optimization based on image analysis
21
21
  - ✅ **Memory Operations** - Process images entirely in memory
22
22
  - ✅ **Multiple Output Formats** - PPM, TIFF, JPEG with advanced compression options
23
+ - ✅ **Buffer Creation API** - 🆕 Create image buffers directly in memory (JPEG, PNG, WebP, AVIF, TIFF, PPM, Thumbnails)
24
+ - ✅ **Stream-based Processing** - 🆕 Return data streams instead of writing to files
23
25
  - ✅ **Buffer Support** - Load RAW data from memory buffers
24
26
  - ✅ **Configuration Control** - Gamma, brightness, color space settings
25
27
  - ✅ **High Performance** - Native C++ processing with JavaScript convenience
@@ -55,7 +57,7 @@ LibRaw supports 100+ RAW formats including:
55
57
  npm install lightdrift-libraw
56
58
  ```
57
59
 
58
- **Version 1.0.0-alpha.1** is now available on [npmjs.com](https://www.npmjs.com/package/lightdrift-libraw)! 🎉
60
+ **Version 1.0.0-alpha.3** is now available on [npmjs.com](https://www.npmjs.com/package/lightdrift-libraw)! 🎉
59
61
 
60
62
  ### 🛠️ Build Requirements
61
63
 
@@ -96,7 +98,34 @@ async function processRAW() {
96
98
  // Load RAW file
97
99
  await processor.loadFile("photo.cr2");
98
100
 
99
- // 🆕 NEW: High-Performance JPEG Conversion
101
+ // 🆕 NEW: Buffer Creation API - Create images directly in memory
102
+ // Process the RAW data first
103
+ await processor.processImage();
104
+
105
+ // Create JPEG buffer without writing to file
106
+ const jpegBuffer = await processor.createJPEGBuffer({
107
+ quality: 85,
108
+ width: 1920,
109
+ progressive: true,
110
+ });
111
+
112
+ console.log(`JPEG buffer created: ${jpegBuffer.buffer.length} bytes`);
113
+
114
+ // Create multiple formats in parallel
115
+ const [pngResult, webpResult, thumbResult] = await Promise.all([
116
+ processor.createPNGBuffer({ width: 1200, compressionLevel: 6 }),
117
+ processor.createWebPBuffer({ quality: 80, width: 1200 }),
118
+ processor.createThumbnailJPEGBuffer({ maxSize: 300 }),
119
+ ]);
120
+
121
+ // Use buffers directly (e.g., send via HTTP, store in database, etc.)
122
+ // No temporary files needed!
123
+
124
+ console.log(`PNG: ${pngResult.buffer.length} bytes`);
125
+ console.log(`WebP: ${webpResult.buffer.length} bytes`);
126
+ console.log(`Thumbnail: ${thumbResult.buffer.length} bytes`);
127
+
128
+ // 🆕 NEW: High-Performance JPEG Conversion (Legacy method still available)
100
129
  // Convert RAW to JPEG with advanced options
101
130
  const jpegResult = await processor.convertToJPEG("output.jpg", {
102
131
  quality: 85, // JPEG quality (1-100)
@@ -226,7 +255,228 @@ This wrapper provides comprehensive LibRaw functionality with **50+ methods** ac
226
255
 
227
256
  **All methods are thoroughly tested and production-ready!**
228
257
 
229
- ## 🆕 JPEG Conversion (New Feature)
258
+ ## 🆕 Buffer Creation API (New Feature)
259
+
260
+ ### Direct Memory Buffer Creation
261
+
262
+ Create image buffers directly in memory without writing to files. Perfect for web applications, APIs, and streaming workflows.
263
+
264
+ #### Available Buffer Methods
265
+
266
+ ```javascript
267
+ const processor = new LibRaw();
268
+ await processor.loadFile("photo.cr2");
269
+ await processor.processImage();
270
+
271
+ // Create different format buffers
272
+ const jpegBuffer = await processor.createJPEGBuffer(options);
273
+ const pngBuffer = await processor.createPNGBuffer(options);
274
+ const webpBuffer = await processor.createWebPBuffer(options);
275
+ const avifBuffer = await processor.createAVIFBuffer(options);
276
+ const tiffBuffer = await processor.createTIFFBuffer(options);
277
+ const ppmBuffer = await processor.createPPMBuffer();
278
+
279
+ // Extract thumbnail buffer without full processing
280
+ const processor2 = new LibRaw();
281
+ await processor2.loadFile("photo.cr2");
282
+ const thumbBuffer = await processor2.createThumbnailJPEGBuffer(options);
283
+ ```
284
+
285
+ #### Buffer Creation Options
286
+
287
+ ##### JPEG Buffer Options
288
+
289
+ ```javascript
290
+ {
291
+ quality: 85, // 1-100 (default: 85)
292
+ width: 1200, // Target width
293
+ height: 800, // Target height
294
+ progressive: true, // Progressive JPEG
295
+ fastMode: false, // Speed vs quality trade-off
296
+ effort: 4 // Encoding effort 1-8
297
+ }
298
+ ```
299
+
300
+ ##### PNG Buffer Options
301
+
302
+ ```javascript
303
+ {
304
+ width: 1200, // Target width
305
+ height: 800, // Target height
306
+ compressionLevel: 6, // 0-9 (default: 6)
307
+ fastMode: false // Speed vs size trade-off
308
+ }
309
+ ```
310
+
311
+ ##### WebP Buffer Options
312
+
313
+ ```javascript
314
+ {
315
+ quality: 80, // 1-100 (default: 80)
316
+ width: 1200, // Target width
317
+ height: 800, // Target height
318
+ lossless: false, // Lossless mode
319
+ effort: 4, // Encoding effort 0-6
320
+ fastMode: false // Speed optimization
321
+ }
322
+ ```
323
+
324
+ ##### AVIF Buffer Options
325
+
326
+ ```javascript
327
+ {
328
+ quality: 50, // 1-100 (default: 50)
329
+ width: 1200, // Target width
330
+ height: 800, // Target height
331
+ lossless: false, // Lossless mode
332
+ effort: 4 // Encoding effort 0-9
333
+ }
334
+ ```
335
+
336
+ ##### TIFF Buffer Options
337
+
338
+ ```javascript
339
+ {
340
+ width: 1200, // Target width
341
+ height: 800, // Target height
342
+ compression: 'lzw', // 'none', 'lzw', 'zip'
343
+ predictor: 'horizontal' // Compression predictor
344
+ }
345
+ ```
346
+
347
+ ##### Thumbnail Buffer Options
348
+
349
+ ```javascript
350
+ {
351
+ maxSize: 300, // Maximum dimension
352
+ quality: 85, // JPEG quality 1-100
353
+ fastMode: false // Speed optimization
354
+ }
355
+ ```
356
+
357
+ #### Usage Examples
358
+
359
+ ##### Web API Response
360
+
361
+ ```javascript
362
+ app.get("/api/photo/:id/thumbnail", async (req, res) => {
363
+ const processor = new LibRaw();
364
+ try {
365
+ await processor.loadFile(`photos/${req.params.id}.cr2`);
366
+
367
+ const result = await processor.createThumbnailJPEGBuffer({
368
+ maxSize: 300,
369
+ quality: 85,
370
+ });
371
+
372
+ res.set({
373
+ "Content-Type": "image/jpeg",
374
+ "Content-Length": result.buffer.length,
375
+ "Cache-Control": "public, max-age=86400",
376
+ });
377
+
378
+ res.send(result.buffer);
379
+ } finally {
380
+ await processor.close();
381
+ }
382
+ });
383
+ ```
384
+
385
+ ##### Multiple Format Generation
386
+
387
+ ```javascript
388
+ async function generateFormats(rawFile, outputDir) {
389
+ const processor = new LibRaw();
390
+ await processor.loadFile(rawFile);
391
+ await processor.processImage();
392
+
393
+ // Generate all formats in parallel
394
+ const [jpeg, png, webp, avif] = await Promise.all([
395
+ processor.createJPEGBuffer({ quality: 85, width: 1920 }),
396
+ processor.createPNGBuffer({ width: 1200, compressionLevel: 6 }),
397
+ processor.createWebPBuffer({ quality: 80, width: 1920 }),
398
+ processor.createAVIFBuffer({ quality: 50, width: 1200 }),
399
+ ]);
400
+
401
+ // Save or process buffers as needed
402
+ fs.writeFileSync(`${outputDir}/image.jpg`, jpeg.buffer);
403
+ fs.writeFileSync(`${outputDir}/image.png`, png.buffer);
404
+ fs.writeFileSync(`${outputDir}/image.webp`, webp.buffer);
405
+ fs.writeFileSync(`${outputDir}/image.avif`, avif.buffer);
406
+
407
+ await processor.close();
408
+ }
409
+ ```
410
+
411
+ ##### Streaming Upload
412
+
413
+ ```javascript
414
+ async function uploadToCloud(rawFile) {
415
+ const processor = new LibRaw();
416
+ await processor.loadFile(rawFile);
417
+ await processor.processImage();
418
+
419
+ const webpResult = await processor.createWebPBuffer({
420
+ quality: 80,
421
+ width: 1600,
422
+ });
423
+
424
+ // Upload buffer directly to cloud storage
425
+ const uploadResult = await cloudStorage.upload(webpResult.buffer, {
426
+ contentType: "image/webp",
427
+ fileName: "processed-image.webp",
428
+ });
429
+
430
+ await processor.close();
431
+ return uploadResult;
432
+ }
433
+ ```
434
+
435
+ #### Buffer Result Structure
436
+
437
+ All buffer creation methods return a consistent result structure:
438
+
439
+ ```javascript
440
+ {
441
+ success: true,
442
+ buffer: Buffer, // The created image buffer
443
+ metadata: {
444
+ format: "JPEG", // Output format
445
+ outputDimensions: { // Final image dimensions
446
+ width: 1920,
447
+ height: 1280
448
+ },
449
+ fileSize: {
450
+ original: 50331648, // Original processed image size
451
+ compressed: 245760, // Buffer size
452
+ compressionRatio: "204.8" // Compression ratio
453
+ },
454
+ processing: {
455
+ timeMs: "45.23", // Processing time
456
+ throughputMBps: "15.4" // Processing throughput
457
+ },
458
+ options: { // Applied options
459
+ quality: 85,
460
+ width: 1920,
461
+ // ... other options
462
+ }
463
+ }
464
+ }
465
+ ```
466
+
467
+ #### Performance Characteristics
468
+
469
+ | Format | Typical Size (1920px) | Creation Time | Compression Ratio |
470
+ | ---------- | --------------------- | ------------- | ----------------- |
471
+ | JPEG | 80-400KB | 200-500ms | 50-200x |
472
+ | PNG | 1-4MB | 400-800ms | 12-50x |
473
+ | WebP | 50-300KB | 100-300ms | 60-300x |
474
+ | AVIF | 30-150KB | 300-800ms | 100-500x |
475
+ | TIFF (LZW) | 2-8MB | 100-200ms | 6-25x |
476
+ | PPM | 11-45MB | 50-100ms | 1x (uncompressed) |
477
+ | Thumbnail | 5-50KB | 50-150ms | 200-1000x |
478
+
479
+ ## 🆕 JPEG Conversion (Enhanced Feature)
230
480
 
231
481
  ### High-Performance RAW to JPEG Conversion
232
482
 
@@ -698,6 +948,9 @@ npm run test:quick
698
948
  # Comprehensive API coverage test
699
949
  npm run test:comprehensive
700
950
 
951
+ # New buffer creation methods test
952
+ npm run test:buffer-creation
953
+
701
954
  # Individual test suites
702
955
  npm run test:image-processing # Image conversion and processing
703
956
  npm run test:format-conversion # Output formats and color spaces
@@ -717,6 +970,9 @@ npm run test:performance
717
970
  # Test all supported formats
718
971
  npm run test:formats
719
972
 
973
+ # Buffer creation test suites
974
+ npm run test:buffer-creation # Comprehensive buffer method testing
975
+
720
976
  # Test with your own RAW file
721
977
  npm test path/to/your/photo.cr2
722
978
  ```
@@ -727,12 +983,14 @@ The test suites provide comprehensive validation across:
727
983
 
728
984
  - ✅ **21 RAW files tested** (Canon CR3, Nikon NEF, Sony ARW, Fujifilm RAF, Panasonic RW2, Leica DNG)
729
985
  - ✅ **100% thumbnail extraction success rate**
986
+ - ✅ **100% buffer creation success rate** (7 new buffer methods)
730
987
  - ✅ **6 camera brands validated** (Canon, Nikon, Sony, Fujifilm, Panasonic, Leica)
731
- - ✅ **Multiple output formats tested** (PPM, TIFF, JPEG thumbnails)
988
+ - ✅ **Multiple output formats tested** (PPM, TIFF, JPEG, PNG, WebP, AVIF buffers)
732
989
  - ✅ **Color space conversion** (sRGB, Adobe RGB, Wide Gamut, ProPhoto, XYZ)
733
990
  - ✅ **Bit depth variations** (8-bit, 16-bit processing)
734
- - ✅ **Memory operations** (buffer management, image copying)
735
- - ✅ **Error handling** (invalid files, corrupted data)
991
+ - ✅ **Memory operations** (buffer management, image copying, direct buffer creation)
992
+ - ✅ **Error handling** (invalid files, corrupted data, parameter validation)
993
+ - ✅ **Performance benchmarking** (buffer creation speed and compression ratios)
736
994
 
737
995
  ## Thumbnail Extraction
738
996
 
@@ -984,8 +1242,8 @@ npm run build # Rebuilds and copies DLL
984
1242
 
985
1243
  **✅ Published to NPM Registry!**
986
1244
 
987
- - **Package**: [`lightdrift-libraw@1.0.0-alpha.1`](https://www.npmjs.com/package/lightdrift-libraw)
988
- - **Published**: August 23, 2025
1245
+ - **Package**: [`lightdrift-libraw@1.0.0-alpha.3`](https://www.npmjs.com/package/lightdrift-libraw)
1246
+ - **Published**: August 30, 2025
989
1247
  - **Total Files**: 487 files (4.0 MB package, 18.1 MB unpacked)
990
1248
  - **Registry**: [npmjs.com](https://www.npmjs.com/package/lightdrift-libraw)
991
1249
 
package/lib/index.d.ts CHANGED
@@ -197,6 +197,103 @@ declare module 'libraw' {
197
197
  reasoning: string;
198
198
  }
199
199
 
200
+ export interface LibRawBufferResult {
201
+ /** Buffer creation success status */
202
+ success: boolean;
203
+ /** Raw binary data buffer */
204
+ buffer: Buffer;
205
+ /** Buffer metadata */
206
+ metadata: {
207
+ /** Original image dimensions */
208
+ originalDimensions?: {
209
+ width: number;
210
+ height: number;
211
+ };
212
+ /** Output image dimensions */
213
+ outputDimensions?: {
214
+ width: number;
215
+ height: number;
216
+ };
217
+ /** Processed dimensions */
218
+ dimensions?: {
219
+ width: number;
220
+ height: number;
221
+ };
222
+ /** File size information */
223
+ fileSize: {
224
+ original?: number;
225
+ compressed: number;
226
+ compressionRatio?: string;
227
+ };
228
+ /** Processing performance */
229
+ processing: {
230
+ timeMs: string;
231
+ throughputMBps?: string;
232
+ fromCache?: boolean;
233
+ };
234
+ /** Format-specific options */
235
+ jpegOptions?: object;
236
+ pngOptions?: object;
237
+ tiffOptions?: object;
238
+ webpOptions?: object;
239
+ avifOptions?: object;
240
+ /** Format type */
241
+ format?: string;
242
+ };
243
+ }
244
+
245
+ export interface LibRawImageConversionOptions {
246
+ /** Target width (maintains aspect ratio if height not specified) */
247
+ width?: number;
248
+ /** Target height (maintains aspect ratio if width not specified) */
249
+ height?: number;
250
+ /** Output color space */
251
+ colorSpace?: 'srgb' | 'rec2020' | 'p3' | 'cmyk';
252
+ /** Enable fast mode for better performance */
253
+ fastMode?: boolean;
254
+ }
255
+
256
+ export interface LibRawPNGOptions extends LibRawImageConversionOptions {
257
+ /** PNG compression level (0-9) */
258
+ compressionLevel?: number;
259
+ /** Use progressive PNG */
260
+ progressive?: boolean;
261
+ }
262
+
263
+ export interface LibRawTIFFOptions extends LibRawImageConversionOptions {
264
+ /** TIFF compression type */
265
+ compression?: 'none' | 'lzw' | 'jpeg' | 'zip';
266
+ /** JPEG quality when using JPEG compression */
267
+ quality?: number;
268
+ /** Create pyramidal TIFF */
269
+ pyramid?: boolean;
270
+ }
271
+
272
+ export interface LibRawWebPOptions extends LibRawImageConversionOptions {
273
+ /** WebP quality (1-100) */
274
+ quality?: number;
275
+ /** Use lossless WebP */
276
+ lossless?: boolean;
277
+ /** Encoding effort (0-6) */
278
+ effort?: number;
279
+ }
280
+
281
+ export interface LibRawAVIFOptions extends LibRawImageConversionOptions {
282
+ /** AVIF quality (1-100) */
283
+ quality?: number;
284
+ /** Use lossless AVIF */
285
+ lossless?: boolean;
286
+ /** Encoding effort (0-9) */
287
+ effort?: number;
288
+ }
289
+
290
+ export interface LibRawThumbnailJPEGOptions {
291
+ /** JPEG quality (1-100) */
292
+ quality?: number;
293
+ /** Maximum dimension size */
294
+ maxSize?: number;
295
+ }
296
+
200
297
  export interface LibRawJPEGResult {
201
298
  /** Conversion success status */
202
299
  success: boolean;
@@ -416,6 +513,48 @@ declare module 'libraw' {
416
513
  */
417
514
  errorCount(): Promise<number>;
418
515
 
516
+ // ============== MEMORY STREAM OPERATIONS (NEW FEATURE) ==============
517
+ /**
518
+ * Create processed image as JPEG buffer in memory
519
+ * @param options JPEG conversion options
520
+ */
521
+ createJPEGBuffer(options?: LibRawJPEGOptions): Promise<LibRawBufferResult>;
522
+
523
+ /**
524
+ * Create processed image as PNG buffer in memory
525
+ * @param options PNG conversion options
526
+ */
527
+ createPNGBuffer(options?: LibRawPNGOptions): Promise<LibRawBufferResult>;
528
+
529
+ /**
530
+ * Create processed image as TIFF buffer in memory
531
+ * @param options TIFF conversion options
532
+ */
533
+ createTIFFBuffer(options?: LibRawTIFFOptions): Promise<LibRawBufferResult>;
534
+
535
+ /**
536
+ * Create processed image as WebP buffer in memory
537
+ * @param options WebP conversion options
538
+ */
539
+ createWebPBuffer(options?: LibRawWebPOptions): Promise<LibRawBufferResult>;
540
+
541
+ /**
542
+ * Create processed image as AVIF buffer in memory
543
+ * @param options AVIF conversion options
544
+ */
545
+ createAVIFBuffer(options?: LibRawAVIFOptions): Promise<LibRawBufferResult>;
546
+
547
+ /**
548
+ * Create raw PPM buffer from processed image data
549
+ */
550
+ createPPMBuffer(): Promise<LibRawBufferResult>;
551
+
552
+ /**
553
+ * Create thumbnail as JPEG buffer in memory
554
+ * @param options JPEG options for thumbnail
555
+ */
556
+ createThumbnailJPEGBuffer(options?: LibRawThumbnailJPEGOptions): Promise<LibRawBufferResult>;
557
+
419
558
  // ============== JPEG CONVERSION (NEW FEATURE) ==============
420
559
  /**
421
560
  * Convert RAW to JPEG with advanced options