
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
SIMDope 🎨 - Color trafficking library faster than tools not mentioning it, lighting fast and around 1500 lines of code (~7kB Gzipped and 0 dep.)
A Color Trafficking Library Designed for Lightning-Fast Processing

SIMDope is a library that optimizes color processing by leveraging arrays of bytes and specialized classes. The primary class, SIMDope.Colors, enhances performance when working with color lists. The secondary class, SIMDope.Color, facilitates transformation, conversion, and operations on individual colors. Notably, elements retrieved from a new instance of SIMDope.Colors are not copied, contributing to its exceptional speed and reduced burden on the garbage collector.
Instead of copying elements, a view of the TypedArray colors data is obtained, allowing for faster operations. Changes made to retrieved elements are reflected in the original TypedArray, resulting in optimized performance.
Using our color quantization algorithm (coming soon to NPM), we can reduce 250K colors to 1K in just 0.3-0.4 seconds. The capability to blend them all together is truly remarkable. A canvas of 512x512 is approximately 250K pixels, yet this library handles multiple millions of operations per second. It is expected to be 4-16 times faster than most other libraries, thanks to SIMD JS & ASM JS!
To understand its usage, especially given its performance-oriented nature, refer to the source code. However, here are various ways to create a new color object.
npm install simdope
// Use the file located in /dist/index.min.js for proper polyfill support (pre-Chrome 61.0)
var Color = window.SIMDOPE.Color;
var Colors = window.SIMDOPE.Colors;
// Use the file located in / for compatibility with code processors like Babel
import { Color, Colors } from "simdope";
npm install simdope
// Use the file located in /dist/index.min.js because it has polyfills required for < Chrome 61.0 (September 5, 2017)
var Color = window.SIMDOPE.Color;
var Colors = window.SIMDOPE.Colors;
// Use the file located in / because it will be parsed properly by piece of code such as Babel
import {Color, Colors} from "simdope";
// If the first parameter is detected as an ArrayBuffer,
// the second parameters tells the constructor
// where to start the sub view, knowing that it will
// multiply it by 4 since there is 4 bytes per ccolor compoment.
// If the first parameters is a Uint8Array, it will use it
Color(with_main_buffer, offset_4bytes)
// Create a color of r: 0, g: 0, b: 0, a: 0
Color.new_zero()
Color.new_of(r, g, b, a)
Color.new_safe_of(r, g, b, a)
Color.new_from(agbr_array)
Color.new_array(rgba_array)
Color.new_array_safe(rgba_array)
Color.new_uint32(uint32)
Color.new_hsla(h, s, l, a)
Color.new_hex(hex_anything)
// Get only
color.r
color.g
color.b
color.a
color.uint32
color.hex
color.hsla
color.lab
color.ycbcra
color.skin // Boolean is skin
color.tail // Tail, usefull for chaining multiple color before blending witin the object AND list at once
color.rgbaon4bits
color.rgbaon6bits
color.rgbaon8bits
color.rgbaon12bits
color.offset
// Private properties (see methods to access them preferably)
color.buffer_
color.subarray_ // It doesn't copy the data, it creates a "pointer" instance
color.slice_ // This clone the data, it creates a whole new Uint8Array
// Get
color.get_buffer()
color.get_subarray()
color.get_slice()
color.sum_rgba()
color.sum_rgb()
color.is_dark()
color.is_skin()
color.is_fully_transparent()
color.is_fully_opaque()
color.is_not_skin()
color.is_not_fully_transparent()
color.is_not_fully_opaque()
// Set
color.set(with_buffer) // Uint8Array or ArrayBuffer, it will check the type of the parameter but it will be slower
color.set_from_simdope(color);
color.set_from_array(new Uint8Array(4)); // ABGR
color.set_from_buffer(with_buffer, offset_four_bytes); // Used to reuse the instanciated object when you need to retrieve an el.
// You need to premultiply alpha to tell to which intensity you'll blend the color when calling `.blend_with_tails()`
// We don't want to store yet another property especially just for maybe blending them once then
color.set_tail(simdope_instance, premultiply_alpha_255_optional)
color.simplify(divider) // 1.6, 2, 3.2, 4, 4.8, 6... Simplify means divide all, coerce to Uint, multiply them again
color.blend_with(another_color, strength_on_255, should_return_transparent, is_alpha_addition)
color.blend_first_with(another_color, strength_on_255, should_return_transparent, is_alpha_addition)
color.blend_first_with_tails(is_alpha_addition); // This method will delete all tail's "links" then, for memory concerns
color.match_with(another_color, threshold_on_255) // This was an old function I kept
color.manhattan_match_with(another_color, threshold_float) // This is the fastest color matching algh.
color.euclidean_match_with(another_color, threshold_float) // This is a fast and great color matching algh.
color.cie76_match_with(another_color, threshold_float) // This is a great color matching algh. but it requires more efforts
color.set_r(r)
color.set_g(g)
color.set_b(b)
color.set_a(a)
color.to_greyscale();
color.to_greyscale_luma();
// Create + copy a new instance
Color.with_r(color, r)
Color.with_g(color, g)
Color.with_b(color, b)
Color.with_a(color, a)
Color.with_inverse(color)
// Return a result YET YOU DON'T NEED THE RETURN VALUE
// TYPED ARRAY ARE MUTABLE, THEY MUTATE STATE FOR EVERY "REFERENCE"
// WHEN YOU MODIFY AN ELEMENT, IT MODIFY THE LIST TOO
Color.with_match(color_a, color_b, threshold_on_255)
Color.blend(color_a, color_b, strength_on_one, should_return_transparent, is_alpha_addition)
Please, look at the source code to know more about other cool ways of using it ...
// Create a new "list/array" of colors, you can work with
// both Uint32Array, it will use its buffer and
// also Uint8Array, it will use its buffer...
// ArrayBuffer works too!
Colors(with_main_buffer)
// Get only
colors.length
colors.buffer
// Get
colors.get_element(index, old_color_object_optional_faster)
// But often except if you `.copy()` the color... yet even if you reuse the same single color object:
// It update the color within your list's buffer when you get an element and apply changes
// Both start and end are an index, not an offset
colors.subarray_uint32(start, end)
colors.slice_uint32(start, end)
colors.subarray_uint8(start, end)
colors.slice_uint8(start, end)
// It uses the `Set` class to remove similar uint32 entries, yet it might need some polyfills for old browser.
colors.get_deduplicated_uint32a()
// It uses a high-performance 8bits 3D Hilbert curve algorithm to sort them on one dimension, very efficient...
colors.get_deduplicated_sorted_uint32a()
// Set
colors.set_element(index, color_object)
// Both start and end are an index, not an offset
colors.buffer_setUint8(index, number)
colors.buffer_setUint32(index, number)
var white = Color.new_of(255, 255, 255, 255);
var green = Color.new_of(0, 255, 0, 255);
var red = Color.new_of(255, 0, 0, 255);
var simdope_my_colors = Colors(imagedata);
// That rewrite the inner data of our array but also white if we don't copy it
simdope_my_colors.get_element(0).blend_with(white.copy(), 192, false, false);
simdope_my_colors.get_element(1).blend_with(white, 0.25*255, false, false) ;
simdope_my_colors.get_element(2)
.blend_with(white.copy(), 0.25*255, false, true)
.blend_with(green.copy(), 0.75*255, false, true)
.blend_with(red.copy(), 0.25*255, false, true)
var purple = simdope_my_colors.get_element(2);
var purple_copy = purple.copy();
var purple_hex = purple.hex;
var purple_uint32 = purple.uint32;
var is_purple_dark = purple.is_dark();
var is_purple_dark_but_from_hex = Color.new_hex(purple_hex).is_dark();
var purple_alpha_but_from_uint32 = Color.new_uint32(purple_uint32).a;
var some_uint32array_colors = simdope_my_colors.subarray_uint32(0, 3);
var some_colors = new Colors(some_uint32array_colors.buffer);
some_colors.set_uint32_element(0, purple.uint32);
some_colors.set_uint32_element(1, purple.uint32);
For more usage scenarios, explore the source code.
Please refer to the source code for additional information and advanced usage scenarios.
FAQs
SIMDope 🎨 - Color trafficking library faster than tools not mentioning it, lighting fast and around 1700 lines of code (~34kB and 0 dep.)
The npm package simdope receives a total of 5 weekly downloads. As such, simdope popularity was classified as not popular.
We found that simdope demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.