fweiss / mcu-gif

A GIF decoder for MCUs
MIT License
0 stars 1 forks source link
c cpp11 image-processing spec tdd

mcu-gif

A GIF decoder for embedded MCUs

The goals of this project are:

It would be nice to try additional languages. For MCUs, C is the most common.

TDD with ccspec

Initally GTest was used to start development. I felt the GTest reports where just too bland. They were "flat" and had a bunch of noisy formatting I was used to "spec" tests with Jasmine. I found the ccspec framework which promised at least a basic rspec test report. So I started afresh with ccspec to try out comprehensible tests.

Running the ccspec tests

Since this is a TDD project, we'll start by running the tests. The steps are:

Update the Git submodule

The ccspec git repository is linked as a submodule. You'll need to update the git submodule with:

git submodule update --init --recursive

Build and run the tests

This is a CMake project, so it follows that workflow.

See WINDOWS.md for a guide specific to Windows. The following is for MacOS.

Example workflow:

mkdir build
cd build
cmake ..
make install
spec/start

Notice the nested structure of the test report.

Debugging

Example on MacOS using lldb

Make sure executable includes debugging info: cmake -DCMAKE_BUILD_TYPE=Debug ..

Start the lldb debugger: lldb build/gd-test

Launch a process to debug: process launch --environment GTEST_FILTER=DecodeSubBlock.simple

Handy commands:

Hex dump of gif file. Use vi with command :%!xxd Or use xxd

Read image data call graph

gd_read_image_data(&main, pixels, imd.image_size) gd_image_block_read(main, &image_block) gd_expand_codes_init(&image_block->expand_codes, image_block->output) gd_image_subblock_decode(image_block, subblock, subblockSize) // unpack block to codes gd_image_expand_code() // decompress code to indexes gd_string_table_init() gd_string_table_at() gd_string_table_add()

gd_read_image_data()

gd_image_block_read()

gd_image_subblock_unpack()

This was inverted to avoid a callback or state machine. but that may be what makes the structures wonky. Its function is unpack not decode.

gd_image_code_expand()

This could be a state machine that shifts out codes from the byte stream.

Visual test

To visually verify the decoder, a small GUI is included. It can be run on the development host.

SDL2 setup for Mac

Download the dmg from libsdl.org. Copy SDL2.framework to either:

There are some permissions that need to be enabled on MacOS. First is in security, second is at launch.

Use global - there's some absolute path wired into the library.

Use version 2.0.22 Latest has a problem with the Headers needing SDL2 subdirectory.

Building and running the visual test

Example workflow:

cd demo-sdl2
make
./main

You should see a window open, displaying a GIF.

This subproject has not been converted to CMake

Alternative GUI visualizers

Several portable GUI frameworks were investigated:

CCSpec

RSpec is a great model for developing software using TDD. I think ccpec provide a solid implementation for C/C++.

https://github.com/fweiss/ccspec

https://github.com/fweiss/ccspec-example

Unit testing with gtest (deprecated)

This project was originally developed with TDD using gtest.

The gtest example code is in the gtest branch.

Eclipse notes

Finally got initializer list working. The trick is that the LLVM library include file is "vector" not "vector.h" consequenlty the default indexer settings to not properly index it.

Project > Propoerties > C/C++ General > Indexer:

https://wiki.eclipse.org/CDT/User/NewIn83#Toolchains

Bugs

string_table_spec.cc
NMAKE : fatal error U1073: don't know how to make 'spec\ccspec\ccspec.lib'
Stop.
NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.29.30037\bin\HostX86\x86\nmake.exe"' : return code '0x2'

Links and references

Really easy and comprehensive guide to decoding GIFs:

https://commandlinefanatic.com/cgi-bin/showarticle.cgi?article=art011

More detailed description bit-by-bit

http://www.matthewflickinger.com/lab/whatsinagif/bits_and_bytes.asp

Best LZW for GIF description with examples

https://www.eecis.udel.edu/~amer/CISC651/lzw.and.gif.explained.html

https://www.geeksforgeeks.org/sdl-library-in-c-c-with-examples/

https://lazyfoo.net/tutorials/SDL/01_hello_SDL/mac/index.php

https://www.willusher.io/sdl2%20tutorials/2013/08/17/lesson-1-hello-world

Some good insights into TDD applied to GIF decoding:

http://debuggable.com/posts/test-driven-development-in-real-world-apps:480f4dd5-514c-45f2-b3dc-4a16cbdd56cb

The official W3C GIF89a specification

A good summary of the GIF file format:

http://netghost.narod.ru/gff/graphics/summary/gif.htm