imagemagick-native
Advanced tools
| var test = require('tap').test | ||
| , imagemagick = require('..') | ||
| , debug = 1 | ||
| ; | ||
| console.log("image magick's version is: " + imagemagick.version()); | ||
| var versions = imagemagick.version().split("."); | ||
| function saveToFileIfDebug (buffer, file) { | ||
| if (debug) { | ||
| require('fs').writeFileSync( file, buffer, 'binary' ); | ||
| console.log( "wrote file: "+file ); | ||
| } | ||
| } | ||
| test( 'taller default', function (t) { | ||
| var buffer = imagemagick.convert({ | ||
| srcData: require('fs').readFileSync( "test.png" ), // 58x66 | ||
| width: 100, | ||
| height: 100, | ||
| resizeStyle: 'aspectfill', | ||
| quality: 80, | ||
| format: 'PNG', | ||
| debug: debug | ||
| }); | ||
| t.equal( Buffer.isBuffer(buffer), true, 'buffer is Buffer' ); | ||
| saveToFileIfDebug( buffer, "out.gravity-default.png" ); | ||
| t.end(); | ||
| }); | ||
| [ "Center", | ||
| "East", | ||
| "West", | ||
| "North", | ||
| "South", | ||
| "NorthEast", | ||
| "NorthWest", | ||
| "SouthEast", | ||
| "SouthWest", | ||
| "None", | ||
| ].forEach( function (gravity) { | ||
| test( 'taller ' + gravity, function (t) { | ||
| var buffer = imagemagick.convert({ | ||
| srcData: require('fs').readFileSync( "test.png" ), // 58x66 | ||
| width: 100, | ||
| height: 100, | ||
| resizeStyle: 'aspectfill', | ||
| gravity: gravity, | ||
| quality: 80, | ||
| format: 'PNG', | ||
| debug: debug | ||
| }); | ||
| t.equal( Buffer.isBuffer(buffer), true, 'buffer is Buffer' ); | ||
| saveToFileIfDebug( buffer, "out.gravity-"+gravity+".png" ); | ||
| t.end(); | ||
| }); | ||
| test( 'wide ' + gravity, function (t) { | ||
| var buffer = imagemagick.convert({ | ||
| srcData: require('fs').readFileSync( "test.wide.png" ), // 58x66 | ||
| width: 100, | ||
| height: 100, | ||
| resizeStyle: 'aspectfill', | ||
| gravity: gravity, | ||
| quality: 80, | ||
| format: 'PNG', | ||
| debug: debug | ||
| }); | ||
| t.equal( Buffer.isBuffer(buffer), true, 'buffer is Buffer' ); | ||
| saveToFileIfDebug( buffer, "out.wide.gravity-"+gravity+".png" ); | ||
| t.end(); | ||
| }); | ||
| } ); |
+1
-1
@@ -10,3 +10,3 @@ { | ||
| ], | ||
| "version": "1.5.0", | ||
| "version": "1.6.0", | ||
| "license": "MIT", | ||
@@ -13,0 +13,0 @@ "repository": { |
+132
-116
| # node-imagemagick-native | ||
| [Imagemagick](http://www.imagemagick.org/)'s [Magick++](http://www.imagemagick.org/Magick++/) binding for [Node](http://nodejs.org/). | ||
| [ImageMagick](http://www.imagemagick.org/)'s [Magick++](http://www.imagemagick.org/Magick++/) binding for [Node](http://nodejs.org/). | ||
@@ -15,2 +15,7 @@ Features | ||
| * [Examples](#examples) | ||
| * [Convert formats](#example-convert) (PNG to JPEG) | ||
| * [Blur](#example-blur) | ||
| * [Resize](#example-resize) | ||
| * [Rotate, flip, and mirror](#example-rotate-flip-mirror) | ||
| * [API Reference](#api) | ||
@@ -24,11 +29,116 @@ * [`convert`](#convert) | ||
| * [`version`](#version) | ||
| * [Examples](#examples) | ||
| * [Convert formats](#example-convert) (PNG to JPEG) | ||
| * [Blur](#example-blur) | ||
| * [Resize](#example-resize) | ||
| * [Rotate, flip, and mirror](#example-rotate-flip-mirror) | ||
| * [Installation](#installation) | ||
| * [Linux / Mac OS X](#installation-unix) | ||
| * [Windows](#installation-windows) | ||
| * [Performance](#performance) | ||
| * [License](#license) | ||
| <a name='examples'></a> | ||
| ## Examples | ||
| <a name='example-convert'></a> | ||
| ### Convert formats | ||
| Convert from one format to another with quality control: | ||
| ```js | ||
| fs.writeFileSync('after.png', imagemagick.convert({ | ||
| srcData: fs.readFileSync('before.jpg'), | ||
| format: 'PNG', | ||
| quality: 100 // (best) to 1 (worst) | ||
| })); | ||
| ``` | ||
| Original JPEG: | ||
|  | ||
| Converted to PNG: | ||
| quality 100 | quality 50 | quality 1 | ||
| :---: | :---: | :---: | ||
|  |  |  | ||
| *Image courtesy of [David Yu](https://www.flickr.com/photos/davidyuweb/14175248591).* | ||
| <a name='example-blur'></a> | ||
| ### Blur | ||
| Blur image: | ||
| ```js | ||
| fs.writeFileSync('after.jpg', imagemagick.convert({ | ||
| srcData: fs.readFileSync('before.jpg'), | ||
| blur: 5 | ||
| })); | ||
| ``` | ||
|  becomes  | ||
| *Image courtesy of [Tambako The Jaguar](https://www.flickr.com/photos/tambako/3574360498).* | ||
| <a name='example-resize'></a> | ||
| ### Resize | ||
| Resized images by specifying `width` and `height`. There are three resizing styles: | ||
| * `aspectfill`: Default. The resulting image will be exactly the specified size, and may be cropped. | ||
| * `aspectfit`: Scales the image so that it will not have to be cropped. | ||
| * `fill`: Squishes or stretches the image so that it fills exactly the specified size. | ||
| ```js | ||
| fs.writeFileSync('after_resize.jpg', imagemagick.convert({ | ||
| srcData: fs.readFileSync('before_resize.jpg'), | ||
| width: 100, | ||
| height: 100, | ||
| resizeStyle: 'aspectfill', // is the default, or 'aspectfit' or 'fill' | ||
| gravity: 'Center' // optional: position crop area when using 'aspectfill' | ||
| })); | ||
| ``` | ||
| Original: | ||
|  | ||
| Resized: | ||
| aspectfill | aspectfit | fill | ||
| :---: | :---: | :---: | ||
|  |  |  | ||
| *Image courtesy of [Christoph](https://www.flickr.com/photos/scheinwelten/381994831).* | ||
| <a name='example-rotate-flip-mirror'></a> | ||
| ### Rotate, flip, and mirror | ||
| Rotate and flip images, and combine the two to mirror: | ||
| ```js | ||
| fs.writeFileSync('after_rotateflip.jpg', imagemagick.convert({ | ||
| srcData: fs.readFileSync('before_rotateflip.jpg'), | ||
| rotate: 180, | ||
| flip: true | ||
| })); | ||
| ``` | ||
| Original: | ||
|  | ||
| Modified: | ||
| rotate 90 degrees | rotate 180 degrees | flip | flip + rotate 180 degrees = mirror | ||
| :---: | :---: | :---: | :---: | ||
|  |  |  |  | ||
| *Image courtesy of [Bill Gracey](https://www.flickr.com/photos/9422878@N08/6482704235).* | ||
| <a name='api'></a> | ||
| ## API | ||
| ## API Reference | ||
@@ -51,6 +161,8 @@ <a name='convert'></a> | ||
| resizeStyle: optional. default: 'aspectfill'. can be 'aspectfit', 'fill' | ||
| aspectfill: keep aspect ratio, get the exact provided size, | ||
| crop top/bottom or left/right if necessary | ||
| aspectfill: keep aspect ratio, get the exact provided size. | ||
| aspectfit: keep aspect ratio, get maximum image that fits inside provided size | ||
| fill: forget aspect ratio, get the exact provided size | ||
| gravity: optional. default: 'Center'. used to position the crop area when resizeStyle is 'aspectfill' | ||
| can be 'NorthWest', 'North', 'NorthEast', 'West', | ||
| 'Center', 'East', 'SouthWest', 'South', 'SouthEast', 'None' | ||
| format: optional. output format, ex: 'JPEG'. see below for candidates | ||
@@ -248,114 +360,13 @@ filter: optional. resize filter. ex: 'Lagrange', 'Lanczos'. see below for candidates | ||
| <a name='installation'></a> | ||
| <a name='examples'></a> | ||
| ## Installation | ||
| ## Examples | ||
| <a name='installation-unix'></a> | ||
| <a name='example-convert'></a> | ||
| ### Linux / Mac OS X | ||
| ### Convert formats | ||
| Install [ImageMagick](http://www.imagemagick.org/) with headers before installing this module. | ||
| Tested with ImageMagick 6.7.7 on CentOS 6 and Mac OS X Lion, Ubuntu 12.04 . | ||
| Convert from one format to another with quality control: | ||
| ```js | ||
| fs.writeFileSync('after.png', imagemagick.convert({ | ||
| srcData: fs.readFileSync('before.jpg'), | ||
| quality: 100 // (best) to 1 (worst) | ||
| })); | ||
| ``` | ||
| Original JPEG: | ||
|  | ||
| Converted to PNG: | ||
| quality 100 | quality 50 | quality 1 | ||
| :---: | :---: | :---: | ||
|  |  |  | ||
| *Image courtesy of [David Yu](https://www.flickr.com/photos/davidyuweb/14175248591).* | ||
| <a name='example-blur'></a> | ||
| ### Blur | ||
| Blur image: | ||
| ```js | ||
| fs.writeFileSync('after.jpg', imagemagick.convert({ | ||
| srcData: fs.readFileSync('before.jpg'), | ||
| blur: 5 | ||
| })); | ||
| ``` | ||
|  becomes  | ||
| *Image courtesy of [Tambako The Jaguar](https://www.flickr.com/photos/tambako/3574360498).* | ||
| <a name='example-resize'></a> | ||
| ### Resize | ||
| Resized images by specifying `width` and `height`. There are three resizing styles: | ||
| * `aspectfill`: Default. The resulting image will be exactly the specified size, and may be cropped. | ||
| * `aspectfit`: Scales the image so that it will not have to be cropped. | ||
| * `fill`: Squishes or stretches the image so that it fills exactly the specified size. | ||
| ```js | ||
| fs.writeFileSync('after_resize.jpg', imagemagick.convert({ | ||
| srcData: fs.readFileSync('before_resize.jpg'), | ||
| width: 100, | ||
| height: 100, | ||
| resizeStyle: 'aspectfill' // is the default, or 'aspectfit' or 'fill' | ||
| })); | ||
| ``` | ||
| Original: | ||
|  | ||
| Resized: | ||
| aspectfill | aspectfit | fill | ||
| :---: | :---: | :---: | ||
|  |  |  | ||
| *Image courtesy of [Christoph](https://www.flickr.com/photos/scheinwelten/381994831).* | ||
| <a name='example-rotate-flip-mirror'></a> | ||
| ### Rotate, flip, and mirror | ||
| Rotate and flip images, and combine the two to mirror: | ||
| ```js | ||
| fs.writeFileSync('after_rotateflip.jpg', imagemagick.convert({ | ||
| srcData: fs.readFileSync('before_rotateflip.jpg'), | ||
| rotate: 180, | ||
| flip: true | ||
| })); | ||
| ``` | ||
| Original: | ||
|  | ||
| Modified: | ||
| rotate 90 degrees | rotate 180 degrees | flip | flip + rotate 180 degrees = mirror | ||
| :---: | :---: | :---: | :---: | ||
|  |  |  |  | ||
| *Image courtesy of [Bill Gracey](https://www.flickr.com/photos/9422878@N08/6482704235).* | ||
| ## Installation | ||
| ### Linux / Mac | ||
| Install [Imagemagick](http://www.imagemagick.org/) with headers before installing this module. | ||
| Tested with ImageMagick 6.7.7 on CentOS6 and MacOS10.7, Ubuntu12.04 . | ||
| brew install imagemagick | ||
@@ -392,2 +403,4 @@ | ||
| <a name='installation-windows'></a> | ||
| ### Windows | ||
@@ -411,2 +424,4 @@ | ||
| <a name='performance'></a> | ||
| ## Performance - simple thumbnail creation | ||
@@ -421,2 +436,3 @@ | ||
| <a name='license'></a> | ||
@@ -423,0 +439,0 @@ ## License (MIT) |
+126
-104
@@ -84,2 +84,3 @@ #ifndef BUILDING_NODE_EXTENSION | ||
| std::string resizeStyle; | ||
| std::string gravity; | ||
| std::string format; | ||
@@ -107,2 +108,46 @@ std::string filter; | ||
| #define RETURN_BLOB_OR_ERROR(req) \ | ||
| do { \ | ||
| im_ctx_base* _context = static_cast<im_ctx_base*>(req->data); \ | ||
| delete req; \ | ||
| if (!_context->error.empty()) { \ | ||
| const char *_err_str = _context->error.c_str(); \ | ||
| delete _context; \ | ||
| return NanThrowError(_err_str); \ | ||
| } else { \ | ||
| const Handle<Object> _retBuffer = NanNewBufferHandle(_context->dstBlob.length()); \ | ||
| memcpy( Buffer::Data(_retBuffer), _context->dstBlob.data(), _context->dstBlob.length() ); \ | ||
| delete _context; \ | ||
| NanReturnValue(_retBuffer); \ | ||
| } \ | ||
| } while(0); | ||
| bool ReadImageMagick(Magick::Image *image, Magick::Blob srcBlob, std::string srcFormat, im_ctx_base *context) { | ||
| if( ! srcFormat.empty() ){ | ||
| if (context->debug) printf( "reading with format: %s\n", srcFormat.c_str() ); | ||
| image->magick( srcFormat.c_str() ); | ||
| } | ||
| try { | ||
| image->read( srcBlob ); | ||
| } | ||
| catch (Magick::Warning& warning) { | ||
| if (!context->ignoreWarnings) { | ||
| context->error = warning.what(); | ||
| return false; | ||
| } else if (context->debug) { | ||
| printf("warning: %s\n", warning.what()); | ||
| } | ||
| } | ||
| catch (std::exception& err) { | ||
| context->error = err.what(); | ||
| return false; | ||
| } | ||
| catch (...) { | ||
| context->error = std::string("unhandled error"); | ||
| return false; | ||
| } | ||
| return true; | ||
| } | ||
| void DoConvert(uv_work_t* req) { | ||
@@ -130,26 +175,4 @@ | ||
| if( ! context->srcFormat.empty() ){ | ||
| if (debug) printf( "srcFormat: %s\n", context->srcFormat.c_str() ); | ||
| image.magick( context->srcFormat.c_str() ); | ||
| } | ||
| try { | ||
| image.read( srcBlob ); | ||
| } | ||
| catch (Magick::Warning& warning) { | ||
| if (!context->ignoreWarnings) { | ||
| context->error = warning.what(); | ||
| return; | ||
| } else if (debug) { | ||
| printf("warning: %s\n", warning.what()); | ||
| } | ||
| } | ||
| catch (std::exception& err) { | ||
| context->error = err.what(); | ||
| if ( !ReadImageMagick(&image, srcBlob, context->srcFormat, context) ) | ||
| return; | ||
| } | ||
| catch (...) { | ||
| context->error = std::string("unhandled error"); | ||
| return; | ||
| } | ||
@@ -172,2 +195,19 @@ if (debug) printf("original width,height: %d, %d\n", (int) image.columns(), (int) image.rows()); | ||
| const char* gravity = context->gravity.c_str(); | ||
| if ( strcmp("Center", gravity)!=0 | ||
| && strcmp("East", gravity)!=0 | ||
| && strcmp("West", gravity)!=0 | ||
| && strcmp("North", gravity)!=0 | ||
| && strcmp("South", gravity)!=0 | ||
| && strcmp("NorthEast", gravity)!=0 | ||
| && strcmp("NorthWest", gravity)!=0 | ||
| && strcmp("SouthEast", gravity)!=0 | ||
| && strcmp("SouthWest", gravity)!=0 | ||
| && strcmp("None", gravity)!=0 | ||
| ) { | ||
| context->error = std::string("gravity not supported"); | ||
| return; | ||
| } | ||
| if (debug) printf( "gravity: %s\n", gravity ); | ||
| if( ! context->format.empty() ){ | ||
@@ -216,2 +256,3 @@ if (debug) printf( "format: %s\n", context->format.c_str() ); | ||
| unsigned int resizeheight; | ||
| if ( aspectratioExpected > aspectratioOriginal ) { | ||
@@ -221,4 +262,12 @@ // expected is taller | ||
| resizeheight = height; | ||
| xoffset = (unsigned int)( (resizewidth - width) / 2. ); | ||
| yoffset = 0; | ||
| if ( strstr(gravity, "West") != NULL ) { | ||
| xoffset = 0; | ||
| } | ||
| else if ( strstr(gravity, "East") != NULL ) { | ||
| xoffset = (unsigned int)( resizewidth - width ); | ||
| } | ||
| else { | ||
| xoffset = (unsigned int)( (resizewidth - width) / 2. ); | ||
| } | ||
| yoffset = 0; | ||
| } | ||
@@ -229,4 +278,12 @@ else { | ||
| resizeheight = (unsigned int)( (double)width / (double)image.columns() * (double)image.rows() + 1. ); | ||
| xoffset = 0; | ||
| yoffset = (unsigned int)( (resizeheight - height) / 2. ); | ||
| xoffset = 0; | ||
| if ( strstr(gravity, "North") != NULL ) { | ||
| yoffset = 0; | ||
| } | ||
| else if ( strstr(gravity, "South") != NULL ) { | ||
| yoffset = (unsigned int)( resizeheight - height ); | ||
| } | ||
| else { | ||
| yoffset = (unsigned int)( (resizeheight - height) / 2. ); | ||
| } | ||
| } | ||
@@ -250,18 +307,21 @@ | ||
| // limit canvas size to cropGeometry | ||
| if (debug) printf( "crop to: %d, %d, %d, %d\n", width, height, xoffset, yoffset ); | ||
| Magick::Geometry cropGeometry( width, height, xoffset, yoffset, 0, 0 ); | ||
| if ( strcmp ( gravity, "None" ) != 0 ) { | ||
| // limit canvas size to cropGeometry | ||
| if (debug) printf( "crop to: %d, %d, %d, %d\n", width, height, xoffset, yoffset ); | ||
| Magick::Geometry cropGeometry( width, height, xoffset, yoffset, 0, 0 ); | ||
| Magick::Color transparent( "transparent" ); | ||
| if ( strcmp( context->format.c_str(), "PNG" ) == 0 ) { | ||
| // make background transparent for PNG | ||
| // JPEG background becomes black if set transparent here | ||
| transparent.alpha( 1. ); | ||
| Magick::Color transparent( "transparent" ); | ||
| if ( strcmp( context->format.c_str(), "PNG" ) == 0 ) { | ||
| // make background transparent for PNG | ||
| // JPEG background becomes black if set transparent here | ||
| transparent.alpha( 1. ); | ||
| } | ||
| #if MagickLibVersion > 0x654 | ||
| image.extent( cropGeometry, transparent ); | ||
| #else | ||
| image.extent( cropGeometry ); | ||
| #endif | ||
| } | ||
| #if MagickLibVersion > 0x654 | ||
| image.extent( cropGeometry, transparent ); | ||
| #else | ||
| image.extent( cropGeometry ); | ||
| #endif | ||
| } | ||
@@ -335,4 +395,15 @@ else if ( strcmp ( resizeStyle, "aspectfit" ) == 0 ) { | ||
| Magick::Blob dstBlob; | ||
| image.write( &dstBlob ); | ||
| try { | ||
| image.write( &dstBlob ); | ||
| } | ||
| catch (std::exception& err) { | ||
| std::string message = "image.write failed with error: "; | ||
| message += err.what(); | ||
| context->error = message; | ||
| return; | ||
| } | ||
| catch (...) { | ||
| context->error = std::string("unhandled error"); | ||
| return; | ||
| } | ||
| context->dstBlob = dstBlob; | ||
@@ -381,2 +452,5 @@ } | ||
| // resizeStyle: optional. default: "aspectfill". can be "aspectfit", "fill" | ||
| // gravity: optional. default: "Center". used when resizeStyle is "aspectfill" | ||
| // can be "NorthWest", "North", "NorthEast", "West", | ||
| // "Center", "East", "SouthWest", "South", "SouthEast", "None" | ||
| // format: optional. one of http://www.imagemagick.org/script/formats.php ex: "JPEG" | ||
@@ -447,2 +521,6 @@ // filter: optional. ex: "Lagrange", "Lanczos". see ImageMagick's magick/option.c for candidates | ||
| Local<Value> gravityValue = obj->Get( NanNew<String>("gravity") ); | ||
| context->gravity = !gravityValue->IsUndefined() ? | ||
| NanCString(gravityValue, &count) : "Center"; | ||
| Local<Value> formatValue = obj->Get( NanNew<String>("format") ); | ||
@@ -470,15 +548,3 @@ context->format = !formatValue->IsUndefined() ? | ||
| DoConvert(req); | ||
| convert_im_ctx* context = static_cast<convert_im_ctx*>(req->data); | ||
| delete req; | ||
| if (!context->error.empty()) { | ||
| const char *err_str = context->error.c_str(); | ||
| delete context; | ||
| return NanThrowError(err_str); | ||
| } | ||
| else { | ||
| const Handle<Object> retBuffer = NanNewBufferHandle(context->dstBlob.length()); | ||
| memcpy( Buffer::Data(retBuffer), context->dstBlob.data(), context->dstBlob.length() ); | ||
| delete context; | ||
| NanReturnValue(retBuffer); | ||
| } | ||
| RETURN_BLOB_OR_ERROR(req) | ||
| } | ||
@@ -837,21 +903,5 @@ } | ||
| Magick::Image image; | ||
| try { | ||
| image.read( srcBlob ); | ||
| } | ||
| catch (std::exception& err) { | ||
| std::string what (err.what()); | ||
| std::string message = std::string("image.read failed with error: ") + what; | ||
| std::size_t found = what.find( "warn" ); | ||
| if (context->ignoreWarnings && (found != std::string::npos)) { | ||
| if (context->debug) printf("warning: %s\n", message.c_str()); | ||
| } | ||
| else { | ||
| context->error = message; | ||
| return; | ||
| } | ||
| } | ||
| catch (...) { | ||
| context->error = std::string("unhandled error"); | ||
| if ( !ReadImageMagick(&image, srcBlob, "", context) ) | ||
| return; | ||
| } | ||
@@ -880,21 +930,5 @@ Magick::GravityType gravityType; | ||
| Magick::Image compositeImage; | ||
| try { | ||
| compositeImage.read( compositeBlob ); | ||
| } | ||
| catch (std::exception& err) { | ||
| std::string what (err.what()); | ||
| std::string message = std::string("compositeImage.read failed with error: ") + what; | ||
| std::size_t found = what.find( "warn" ); | ||
| if (context->ignoreWarnings && (found != std::string::npos)) { | ||
| if (context->debug) printf("warning: %s\n", message.c_str()); | ||
| } | ||
| else { | ||
| context->error = message; | ||
| return; | ||
| } | ||
| } | ||
| catch (...) { | ||
| context->error = std::string("unhandled error"); | ||
| if ( !ReadImageMagick(&compositeImage, compositeBlob, "", context) ) | ||
| return; | ||
| } | ||
@@ -970,15 +1004,3 @@ image.composite(compositeImage,gravityType,Magick::OverCompositeOp); | ||
| DoComposite(req); | ||
| composite_im_ctx* context = static_cast<composite_im_ctx*>(req->data); | ||
| delete req; | ||
| if (!context->error.empty()) { | ||
| const char *err_str = context->error.c_str(); | ||
| delete context; | ||
| return NanThrowError(err_str); | ||
| } | ||
| else { | ||
| const Handle<Object> retBuffer = NanNewBufferHandle(context->dstBlob.length()); | ||
| memcpy( Buffer::Data(retBuffer), context->dstBlob.data(), context->dstBlob.length() ); | ||
| delete context; | ||
| NanReturnValue(retBuffer); | ||
| } | ||
| RETURN_BLOB_OR_ERROR(req) | ||
| } | ||
@@ -985,0 +1007,0 @@ } |
+18
-0
@@ -16,2 +16,20 @@ var test = require('tap').test | ||
| test( 'convert invalid format', function (t) { | ||
| var buffer; | ||
| try { | ||
| buffer = imagemagick.convert({ | ||
| srcData: require('fs').readFileSync( "test.png" ), // 58x66 | ||
| width: 100, | ||
| height: 100, | ||
| quality: 80, | ||
| format: 'PNGX', | ||
| debug: debug | ||
| }); | ||
| } catch (e) { | ||
| t.like( e.message, /no decode delegate for this image format/, 'err message' ); | ||
| } | ||
| t.equal( buffer, undefined, 'buffer undefined' ); | ||
| t.end(); | ||
| }); | ||
| test( 'convert invalid number of arguments', function (t) { | ||
@@ -18,0 +36,0 @@ var error = 0; |
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
168256
2.52%25
4.17%816
11.63%453
3.66%3
-25%43
13.16%