Thanks for posting the script again. I was combing through our notes on the IRC log and I found the previous paste dumps you linked, but the links were dead.
The OLED image is stored in the gzipped portion of the Series3 PROM image. It is a 4-bit 48x48 grayscale image stored in a proprietary format, and downloaded to the display via I2C. The first few bytes look like this:
If you extract this image (hint: it is exactly 0x370 bytes long), you can decode it into a PGM file called out.pgm with the oled_decode.pl utility:Code:0000000: 4000 0000 0000 0000 4000 0000 03d0 0000 @.......@....... 0000010: 4000 0000 0000 005b 4040 0000 0000 0bda @......[@@...... 0000020: 4000 0000 0000 0000 4000 dbc0 0000 0000 @.......@....... 0000030: 4013 db40 0000 0000 4000 0001 dbd0 0000 @..@....@.......
You can then edit the PGM file, convert it to/from other formats, etc. You may then re-encode it using the oled_encode.pl script:Code:$ ./oled_decode.pl tivoguy.raw XX: .XX. .XXX: XXXX :XXXX. .XXXX: :XXXXX .:XXXXX: :XXXXX .:XXXXXXX .XXX::. : :X:.:XXX. XX: .XX. :XX :XX :XX .XX XX. XX. :X: .XX .X: XX. .XX XX ...XX .XX .::XXXXXXXXXXXXX::...... :XXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXX::XXXXXXXXXXX .XXXXXXXX XXX.. .: X:XXXXX: :XXXXXXXX XXX .. : XXXX XXXXXXXXX XXXXX :XX::X. :XX: .X. .:XXX: :XXXX. :XXXXX: .XX. :. .XX: :XXXX. :XX.:XX X: X X .XX. .XXXX. :XX XX. X :X : XXX XXXX. :XX XX. XX. .XXX XXXX. :XX XX: .XXX...XXX: .XXX: :XX. XXX XXXXXXXXXX. XXXXXXXXXXXXX: :XXXXXXXXXX :XXXXXXXXXXXXXXXXXX::XXXXX .XXXXXX .:XXXXXXXX. XXXXX. XXXXXX ::::. XXXXXX .XXXXXX:. .XXXXXX: XXXXXXXXX:...:XXXXXXXX XXXXXXXXXXXXXXXXXXXXX: .XXXXXXXXXXXXXXXXXXXX ::::.:XXX::XXXXXXXX XXX .XX. ... :XX .XX :X: .XX :X: .XX ::. :X: .XX :XXXXXXXX XXXXXXX. XXXXXXXXXX.XXXXXXXX: :XXXXXXXXX. XXXXXXXXX XXXXXXX:. :XXXXXXX. .:XXX. .:XXXX.
And then patch it back into the PROM using a hex editor, gzip, etc.Code:$ ./oled_encode.pl out.pgm > new.bin
oled_encode.pl uses ImageMagick/PerlMagick so it can accept other file formats, like PNG, BMP, etc. You can use the netpbm tools (e.g. pnmtopng, pnmtoppm | ppmtobmp) to manipulate this file.
Note that the startup logo does not fill the entire OLED display, as the display is more than 48 pixels wide.
Thanks for posting the script again. I was combing through our notes on the IRC log and I found the previous paste dumps you linked, but the links were dead.
Okay so after much mucking around with the script and with the help of amatus and Mr_Penguin on IRC we've got the oled_encode.pl script fixed:
Some small changes needed to be made to get it working correctly, and the script now properly encodes the source data into the resultant output.Code:#!/usr/bin/perl -w use Image::Magick; use bytes; my($img, @pix, @out, $r, $i, $j, $bytes); die "usage: oled_encode.pl <image.pgm> > out.bin" if(!defined($ARGV[0])); $img = Image::Magick->new; $r = $img->Read($ARGV[0]); warn "$r" if "$r"; $r = $img->Crop(geometry=>'48x48'); warn "$r" if "$r"; for($i = 0; $i < 48; $i++) { @pix = $img->GetPixels(y => $i, map => 'I'); for($j = 0; $j < 48; $j++) { push(@out, int($pix[$j] / (15*1024))); } } $j = 0; $bytes = ""; for($i = 0; $i < 48 * 48 / 3; $i++) { $byte = ($out[$j] << 6) | ($out[$j+1] << 3) | ($out[$j+2]); $bytes .= sprintf("%c", $byte); $j += 3; } $bytes .= sprintf("%c%c", 0, 0); $j = 0; for($i = 0; $i < 110; $i++) { syswrite(STDOUT, "@".substr($bytes, 0, 7)); $bytes = substr($bytes, 7); } exit 0;
Old:
New:
Crappy Proof of Concept (Courtesy of iPhone's Crappy Camera):
I'm actually quite pleased with the result, even though the atrocious photo doesn't do it justice. Once my Canon gets fixed, I'll post new photos.