Security News
Input Validation Vulnerabilities Dominate MITRE's 2024 CWE Top 25 List
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
flipnote.js
Advanced tools
API for handling Flipnote Studio's .ppm animation format, capable of real-time playback using webGL
Flipnote Studio is an application for the Nintendo DSi console, originally released in 2008. Users can create simple flipbook-style animations ("Flipnotes") with the console's touchscreen or camera, and add sounds or music with the microphone. Until 2013, Flipnote creations could also be shared with others on and online 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 manage to find 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 was 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.
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. I wanted to avoid was pre-decoding 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 it, 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.
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.
Research
Security News
A threat actor's playbook for exploiting the npm ecosystem was exposed on the dark web, detailing how to build a blockchain-powered botnet.