I was a little less sure I loved the image formats, so I went ahead and reversed them. This document explains the file format of the OnHand's image file (MMP) and video file (MMV). I also provide a few examples if you don't care how they work and just want stuff to put in the watch. ;)
Originally, I was working on compressed versions of both. But neither really provided the gains I was looking for, although I may revisit the movie format again in the future. So I'll just provide my research. :)
All multi-byte numbers are stored in little endian format.
The MMP header consists of 4 bytes:
Offset | Size | Description |
0 | 2 | Width of image |
2 | 2 | Height of image Should be a multiple of 8 |
The remainder of the image is stored as 'stripes' of uncompressed data. Each byte represents one column of 8 pixels. In this pattern, an entire row is stored before the next row, meaning that each row takes up width bytes, and describes 8 pixel rows. The least significant bit represents the highest row, and the most significant bit represents the lowest row.
So, for a 102-pixel wide image, the bytes are laid out like this:
Row Bytes 0-7 : 5 6 7 8 9 10 11 12 13 14 ... 8-15 : 107 108 109 110 111 112 113 114 115 116... 16-23: 209 210 211 212 213 214 215 216 217 218...
Note that behaviour is undefined if the height is not a multiple of 8 pixels - not all readers treat the last stripe of data the same way.
As it turns out, MMV files are in fact derived from MMP files, making them fairly easy to build. An MMV file is a series of MMP frames, with a 16 byte header preceding each one. The stream is terminated by a header containing all FF.
Notes online hinted that the frame rate is fixed at 4 fps, and that seems more or less correct based on my observations.
The MMV header is 16 bytes long:
Offset | Size | Description |
0 | 2 | Number of bytes in this frame (including the MMP header) |
2 | 2 | Unknown |
4 | 2 | Unknown |
6 | 2 | Unknown |
8 | 2 | X offset of image in pixels |
10 | 2 | Y offset of image in pixels Should be a multiple of 8 |
12 | 2 | Unknown |
14 | 2 | Unknown |
Note that because you can specify a different size and different offset for each frame, it is possible to compress your movie some by updating only a changed rectangle of the screen each frame, rather than the whole thing. I suspect in most real world cases, though, you won't save much.
After this 16 byte header, comes an MMP file, complete with it's own header.
The MMP file is followed by another MMV header, and so forth.
If there is enough demand (or someone pays me), I'll convert my crappy little movie conversion tool into something that can actually be used. ;) Otherwise, it's a simple format, and there's enough here for any programmer to get to work on.
Visit the Software section of my web page for some OnHand related files, including a simple image converter.