Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
flipnote.js
Advanced tools
API for handling Flipnote Studio's .ppm animation format, capable of real-time playback using webGL
Flipnote Studio is a DSiWare application released for the Nintendo DSi console in 2008. It lets users create simple flipbook-style animations ("Flipnotes") with the console's touchscreen or camera. Until 2013, Flipnotes could be shared online on a service called Flipnote Hatena.
This project's goal is to allow for entirely browser-based parsing and playback of Flipnote Studio's animation format, .ppm
. It started mostly as a way to challenge myself to learn WebGL, with no real purpose in mind other than making something of a tribute to an app that I spent a lot of my early teens playing with.
I hope that maybe in the long term it will serve some use in archiving Flipnote animations, epecially given that now there's no legitimate way to get Flipnote Studio unless you have a DSi with it already installed.
For now, there's an old work-in-progress video on my twitter account (any glitchyness shown has been fixed since). I'm currently working on implementing this project into a Flipnote player web app to further demonstrate it, so please bear with me!
.ppm
)The PPM format is an entirely custom-made by Nintendo for use within Flipnote Studio. The file extension comes from the Japanese "パラパラマンガ" ("Para Para Manga"), which roughly translates to "flip comic". Its purpose is to store Flipnotes created within the app, which comprise of animation frames, audio, and metadata (author name, timestamp, etc).
PPM animations have 2 layers per frame, each layer is a monochrome bitmap image where each pixel is represented in data by a single bit. Layers can use one of three colors; red, blue, or black/white, the latter being the inverse of the background color. As such, there is a maximum of 3 colors per frame.
To save space (the Nintendo DSi doesn't have much internal memory) layers are compressed in a variety of different ways. The PPM Format Docs cover frame compression in more detail, but the general idea was to avoid storing data for chunks of pixels that have the same value. That said, all the PPM documentation I've come across so far seems to omit noting that there are difference-based frames, where both layers need to be merged with the previous frame to produce a complete image. This is done by XORing each pixel in each layer.
PPMs can also have up to four audio tracks; a one minute long background track and 3 short "sound effects" that can be assigned to any frame. Nintendo went with ADCPM for storing audio data because, again, they wanted to use as little space as possible.
Frame decoding (source) is easy enough to implement so long as you follow the docs. One thing I really wanted to avoid was predecoding frames, though, as it could cause JavaScript execution to lock up for a while and memory usage wouldn't be too great.
The general process looks like this:
Flipnote Studio has 8 playback speed presets, the fastest being 30 frames per second. Hitting that benchmark is necessary for providing accurate real-time playback so it was important to avoid peformance bottlenecks wherever possible. As such, the frame decoder employs a couple of tricks:
set
method can be used to copy one buffer to another, and the fill
method can be used to quickly clear a buffer or set groups of pixels to the same value.putImageData
was proving to be a major bottleneck, so I ended up trying WebGL instead. Layers are already Uint8Arrays so we can bind them to WebGL texture buffers easily, and for our drawing surface we use a quad that fills the whole canvas. Then a fragment shader takes both layer textures and combines them on the GPU.Audio was a little tricky. In my Python PPM decoder I was just able to rely on the audioop module to decode ADPCM, but JavaScript doesn't have any out-of-the-box way to process ADPCM like that. The AudioBuffer API does support PCM audio, however it's a rather young and finicky API where implementations still differ quite a bit. That's no biggie though, the HTML5 <audio>
element also supports PCM via the WAV format! In the end the audio decoding and playing process looks like this:
<audio>
element using the .wav file blob as its source.This project is licensed under the MIT License - see the LICENSE.md file for details.
FAQs
A JavaScript library for parsing, converting, and in-browser playback of the proprietary animation formats used by Nintendo's Flipnote Studio and Flipnote Studio 3D apps.
The npm package flipnote.js receives a total of 8 weekly downloads. As such, flipnote.js popularity was classified as not popular.
We found that flipnote.js demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer 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.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.