SmileBASIC Program Archiver
Root / Submissions / [.]
amihartCreated:
Version:Size:16.76 KB
[Edit] This program is officially dead due to Miiverse shutting down.
Transfer a SmileBASIC program from your 3DS to your PC through the internet to archive it on your PC.
Since the transfer is essentially done through the internet, no special devices are needed! No auxiliary cables or splitters or webcams or anything.
This is for archiving programs with 3DS->PC transfers. It does not support PC->3DS transfers.
Replying to:snail_
How are you taking into account JPEG compression on Miiverse? I would think that messes up the output.
It's because of the way I'm encoding it. The compression loses data and ends up blending the colors together, but the data is encoded using 2x2 boxes that are either red, blue, or green, each representing 1 bit. All I need to do is average the four pixels that make up the box and see what color is most prevalent. The compression simply doesn't drop enough information to make the information non-recoverable. You can fit 24,000 2x2 boxes on the screen at a single time, so you get 3000 bytes of data from a single image.
Here's a close-up of one of the compressed screenshots:
As you can see, the colors are blended together but not enough to make what the original colors were supposed to be unrecognizable.
Replying to:snail_
How are you taking into account JPEG compression on Miiverse? I would think that messes up the output.
Hmm, how do the colored squares represent the data exactly? I'm not sure I follow.
Replying to:snail_
How are you taking into account JPEG compression on Miiverse? I would think that messes up the output.
This is a clever idea, I wish there was a way to counteract the compression though, so you could use single pixels, that would quadruple the amount of data an image could contain. Does the compression really mitigate the dominate color that much with single pixel colors?
Replying to:snail_
How are you taking into account JPEG compression on Miiverse? I would think that messes up the output.
@slackerSnail
It basically uses three colors, R, G, and B, to transfer data, with a list of agreed upon rules (the protocol). If the previous color was R, then R can either change to G or B. If the previous color is G, then the color can either change to R or B. So no matter what color you have just used, you have 2 options to switch to. I then have an agreed upon list of rules that describes which jump represents a 0 and which represents a 1. The purpose of this protocol is that I never reuse the same color twice in a row. It always changes per bit, which in many cases, makes encoded information significantly easier and more efficient to decode. Each box represents 1 bit. How it represents 1 bit is based on the color of the previous box and the color of the current box based on the protocol.
I made this reusing the code I made for my previous program. So how this works is pretty similar, so you can see the explanation for that here.
@gleenxserge
I tried using single pixels but I had trouble recovering the original data after compression.
Here's a zoom-up of a 1x1 encoding after compression:
The first three boxes are supposed to be Green->Blue->Red. But due to the compression, there is 0 blue in that second box (RGB = 0,56,0). In fact, green is the most prevalent color of the first 5 boxes.
You may have missed the forest for the trees a bit, here. :) You could probably just use black and white for 0 and 1. I can see why a webcam-based program would need to read data based on changing colors, you wouldn't want to rely on precise timing like "3 beats of pure white for 1 1 1, 2 beats of black for 0 0," but if you're looking at 2x2 chunks of a static image you should be able to use set colors for 0 and 1, rather than doing it based on changes.
If you used white and black it would end up looking an awful lot like a QR code, actually.
But you could do even better: every 2x2 block could stand for two bits, and you could store double the data! Black = 00, red = 01, green = 10, blue = 11.
Replying to:Unclesporky
You may have missed the forest for the trees a bit, here. :) You could probably just use black and white for 0 and 1. I can see why a webcam-based program would need to read data based on changing colors, you wouldn't want to rely on precise timing like "3 beats of pure white for 1 1 1, 2 beats of black for 0 0," but if you're looking at 2x2 chunks of a static image you should be able to use set colors for 0 and 1, rather than doing it based on changes.
If you used white and black it would end up looking an awful lot like a QR code, actually.
But you could do even better: every 2x2 block could stand for two bits, and you could store double the data! Black = 00, red = 01, green = 10, blue = 11.
Yes, that's something I've considered implementing but haven't gotten around to it yet. Simply using black and white wouldn't make it better, because even though I'm using three colors, each color still represents 1 bit each. So using black and white for 1 bit each would have the exact same efficiency. Using different colors every time is actually better because you'll never end up with a situation where, let's say a green is surrounded by 9 reds. This could cause it to turn red when compressed.
I have been considering trying to use multiple colors to store more bits per block, I just haven't gotten around to it yet. I will probably update this in the future. This RGB method was just the easiest and I already had the code going.
Replying to:snail_
How are you taking into account JPEG compression on Miiverse? I would think that messes up the output.
Yikes, that is lossy (>_<). Have you tried 2x1 areas, would at least double the amount of data. I gave this a shot using different colors ( Yellow, Black, Blue), they tend to compress better, but you'll need to compare hue versus value to determine which pixel. If it's black, the value threshold is quite low even when surrounding pixels get filtered into it. If it's yellow or blue you can tell from the hue R+G or B. Might be worth exploring, but seriously this is a neat application, and very useful for posting online code examples. Get tired of typing out examples to test and than transcribing them to explain to others online.
EDIT:
Better yet, just use white and black pixels (white for bit on, black for off), they don't suffer any compression loss!
(Above image is from miiverse screen cap)
Replying to:snail_
How are you taking into account JPEG compression on Miiverse? I would think that messes up the output.
Really? For 1x1 black/white pixels there's absolutely no compression loss? I'll have to try that, thanks for pointing it out!
Replying to:snail_
How are you taking into account JPEG compression on Miiverse? I would think that messes up the output.
Sure thing, I was quite surprised myself! At 399x239, that's almost 12,000 bytes!
Replying to:snail_
How are you taking into account JPEG compression on Miiverse? I would think that messes up the output.
Yep! You are right, just transferred some data over using this and it worked fine. I will update the key and the software with this version soon.
I just saved a text file with the contents "BOB" and it saved as 4 bytes (fourth byte being the newline character). Unicode characters take up more bytes, but 99% of the characters you will use in a program aren't unicode.
There may be some circumstances though, where you would need to keep the extended characters. Like if you were using any of the window border characters to create a dialog box or ui component. However, instead of sacrificing half your storage to accommodate the odd 2 byte requirement, you could just use a specific bit combination to mark where in the image you need to read 2 bytes and cast them to a unicode character. Like a gray pixel or something. I didn't test to see how gray-scale images effect compression on miiverse, but maybe something like that would work.
EDIT:
In fact if gray-scale remains uneffected by compression, you could extend your storage values greatly. You could use percentage gray to represent series of bits. 50%(127) = 1 bit on, 100%(255) = 128 bits, and you could interpolate inbetween. 49% (126) = 1 bit off, 0% = 127 bits off. Something like that could help squeeze a bit more into your images.
If gray-scale is truly unaffected by compression then I could fit 96 kilobytes into a single image instead of 12, since there are 254 shades of gray.
Internally SB characters are all 2 bytes each. But when you save a file, it's converted to a UTF-8 encoding. This would be why your text file only occupies 4 bytes.
Okay, so a couple of things I noticed testing this with a full grayscale image. There is zero compression loss when you can represent the image as a single channel. I'm guessing the algorithm must be happy enough ditching the other two channels that it leaves the image unmolested. As soon as I added one pixel with color it bled into the other pixels.
The second thing to note, is that the graphics once blitted to the screen (at 8 bits per channel), get stored as 5 bit per channel. When you capture the image, it's getting this 15 bit representation. So you'll need to factor that into your value calculations.