Showing posts from July, 2020

A 'Low Memory' GIF decoder

I just released my AnimatedGIF library for Arduino and it contains a lot of optimizations and workarounds to perform well on microcontrollers. I thought it might be useful to document what makes it different from other GIF decoders out there. First a little background on GIF images: GIF (Graphics Interchange Format) Compuserve was an early internet service provider and they created an image format for streaming compressed pictures over a slow and unreliable channel (dial-up internet). Their first format (GIF87) utilized LZW compression for transmitting a single image. LZW compression is a clever way of finding and compressing repeated sequences of symbols and outputting them in a (VLC) variable-length-code stream. The GIF format treats images as a continuous (one dimensional) stream of pixels. By doing it that way, it misses out on taking advantage of horizontal and vertical symmetries. The PNG file format compresses image more effectively not just because Deflate/Inflate compress

Inside the mind of an optimizer

In this post I'm going to walk through my thought process when I examine a piece of code. By explaining each of my changes, hopefully I can reveal some info that will be useful to programmers who don't normally focus on performance. This is the code I'm going to pick apart. It's an image downsample loop from an Arduino sample project that uses machine learning to recognize images from a VGA camera. The requested camera image is QVGA (320x240) resolution and will be downsampled to 10x8 by this loop to make it more manageable for the Arduino Nano 33 BLE to process. Some background bytesPerFrame - holds the value 320x240x2 since each pixel (of type RGB565) occupies 2 bytes.  camdata[] - the uint8_t buffer holding the image rgb_frame[][][] - a 3-dimensional array which will hold the downsampled image WIDTH is a constant containing 320 BLOCK_SIZE is a constant containing 30 (each 30x30 block of pixels from the original image becomes one pixel in rgb_frame[]) What I See The l