-
Notifications
You must be signed in to change notification settings - Fork 2
Automatic Wireless Uploading with the Eye Fi
An eye-fi (http://www.eye.fi) is an SD card which has an onboard wireless connection that can upload photos or movies. Some versions of the card can do more, or do more (raw) formats, but it is generally limited and intended for pics or movies to end up on one of the photo sharing sites. These are generally formatted as FAT32 since they are SDHC cards, but the 2GB apparently work as FAT16.
The upload is AUTOMATIC. You configure the card, and as long as it is near a configured access point, or one that is part of a subscribed service (places like McDonalds), any file in the DCIM directory will be uploaded to Flickr, Picasa, or wherever else it allows. It also seems to be very robust – going in and out of range, cycling power, etc. it will still manage to eventually upload the file.
To use them with a micro SD slot device, you need an adapter, such as: http://www.dealextreme.com/details.dx/sku.27001
The rest is simply playing by the rules for the camera filesystem, starting with creating a DCIM directory off the root:
http://en.wikipedia.org/wiki/Design_rule_for_Camera_File_system
There are also limits from the FAT filesystem itself, e.g. the number of directory entries.
For files to be uploaded, they must be valid JPEGs and there seems to be some minimal size/content, however JPEGs created by the serial camera all seem to upload (even nearly blank ones). You can also have a valid single black pixel with whatever you want in the comment metadata. So taking a minimal http://www.techsupportteam.org/forum/digital-imaging-photography/1892-worlds-smallest-valid-jpeg.html jpeg, you can put any information and if it is above a threshold of size (around 30k for this from tests), the EyeFi will upload it. Then you just need to strip out the comments and you have the file.
For example, below are enpeg.c and depeg.c – they are “unix filters” so read from stdin and write to stdout. They will embed and extract any data into comment records.
But a more interesting possibility is to generate a picture, i.e. use a JPEG something like an LCD screen. Or generate a QR code http://en.wikipedia.org/wiki/QR_Code. There are a few tricks. JPEG uses 8×8 pixel blocks, so things are really easy if you have 8×8 black boxes and 8×8 white boxes. It will actually be lossless doing it this way. Then you need to generate the tables, and simply append the bitfields for the image. JPEG uses Y (luminance) so it starts at 50% gray (use grayscale JPEGs), so the first pixel is 50% up or down, then either “same” or 100% in the other direction. A windows program, http://www.impulseadventure.com/photo/jpeg-snoop.html can show you how things are decoded.
So I generated a .pbm file (text, 0 and 1 for bits) that was a large (4Kx4K) array of random black or white 8×8 blocks. Then used pnmtojpeg telling it to generate an optimized grayscale at quality 0 (most compression). That created a file with small header, and the bitfields were visible in jpeg-snoop. Pull off the header and convert to hex and to an array. Now I just have to set the width and height (at a fixed location in the header), then append the right bitfield for each successive block.
enpeg.c:
#include <stdio.h>
static unsigned char dotjpg0[20] = {
0xFF, 0xD8, 0xFF, 0xE0,
0x00, 0x10, 0x4A, 0x46, 0x49, 0x46, 0x00, 0x01,
0x01, 0x01, 0x00, 0x48, 0x00, 0x48, 0x00, 0x00
};
static unsigned char dotjpg9[] = {
0xFF, 0xDB, 0x00, 0x43, 0x00,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xC2, 0x00, 0x0B, 0x08, 0x00, 0x01, 0x00,
0x01, 0x01, 0x01, 0x11, 0x00,
0xFF, 0xC4, 0x00, 0x14, 0x10, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xFF, 0xDA, 0x00, 0x08, 0x01, 0x01, 0x00, 0x01,
0x3F, 0x10
};
static unsigned char textbuf[65536] = { 0xff, 0xfe };
int main(int argc, char *argv[])
{
int len;
fwrite(dotjpg0, 1, sizeof(dotjpg0), stdout);
for (;;) {
len = fread(&textbuf[4], 1, 65532, stdin);
if (len <= 0)
break;
// fprintf(stderr, "add %d\n", len);
len += 2;
textbuf[2] = len >> 8;
textbuf[3] = len;
fwrite(textbuf, len + 2, 1, stdout);
}
fwrite(dotjpg9, 1, sizeof(dotjpg9), stdout);
}
depeg.c:
#include <stdio.h>
static unsigned char textbuf[65536];
int main(int argc, char *argv[])
{
int len;
fread(textbuf, 1, 20, stdin);
for (;;) {
if (1 > fread(textbuf, 1, 2, stdin))
break;
if (textbuf[0] != 0xff || textbuf[1] != 0xfe)
break;
fread(textbuf, 1, 2, stdin);
len = textbuf[0];
len <<= 8;
len |= textbuf[1];
fread(textbuf, len - 2, 1, stdin);
fwrite(textbuf, len - 2, 1, stdout);
}
}