switching colors in PROGMEM stored icons

ok call me crazy, but I have actually begun work on my own GIF decoder Arduino sketch.

If you really just see the GIF file format description as a "how-to" of how the bytes need to be decoded and analyzed, then it should be possible to just walk through all that, bit by bit (or rather: byte by byte :slight_smile: ), write code accordingly, and at the end hopefully display an image correctly.

Here's my code so far:

#include "logo.h"

void showGIF(uint16_t gifName, uint16_t width, uint16_t height, uint16_t xpos, uint16_t ypos) {

  boolean goodFile = false;
  char header[6];
  byte headerElement;

  // reading header
  for (byte i = 0; i <= 5; i++) {

    headerElement = pgm_read_byte(&MGlogo[i]);
    header[i] = headerElement;
  }

  if (String(header).startsWith("GIF89a")) {

    Serial.print("Header found: ");
    Serial.println(header);
    goodFile = true;
  }

  else Serial.println("Wrong file header found. Doing nothing.");

  if (goodFile) {
    //reading file width
    int fileWidth   = (pgm_read_byte(&MGlogo[6])) | (pgm_read_byte(&MGlogo[7]) << 8);
    int fileHeight  = (pgm_read_byte(&MGlogo[8])) | (pgm_read_byte(&MGlogo[9]) << 8);


    Serial.println("-------------\nImage information:\n");
    Serial.print("File dimensions: ");
    Serial.print(fileWidth);
    Serial.print(" x ");
    Serial.print(fileHeight);
    Serial.println(" px");

    // Reading Packed Field byte and expanding it
    byte packedField = pgm_read_byte(&MGlogo[10]);
    Serial.print("Packed Field: ");
    Serial.println(packedField, BIN);

    byte globalColorTableFlag = bitRead(packedField, 7);

    byte colorResolution = (bitRead(packedField, 6) <<2) | (bitRead(packedField, 5) << 1) | (bitRead(packedField, 4));

    byte sortFlag = (bitRead(packedField, 4) >> 0);

    byte globalColorTableSize = (bitRead(packedField, 0)) | (bitRead(packedField, 1) << 1) | (bitRead(packedField, 2) << 2);
    
    globalColorTableSize = pow(2, globalColorTableSize) + 1;

    Serial.print("Global color table: ");
    if (globalColorTableFlag == 1) Serial.println("Y");
    else Serial.println("N");

    Serial.print("Global color resolution: ");
    Serial.println(colorResolution);


    Serial.print("Color sorting: ");
    if (sortFlag == 1) Serial.println("decreasing");
    else Serial.println("increasing");

    Serial.print("Color table size: ");
    Serial.print(globalColorTableSize);
    Serial.println(" indexed colors");
  }
}

void setup()
{

  Serial.begin(115200);
  showGIF(MGlogo, 30, 30, 0, 0);

}

void loop()
{

  /* add main program code here */

}

I've attached all the files to this post.

A few hiccups so far; I can't do

pgm_read_byte(&gifName[i])

, it tells me "invalid types 'uint16_t {aka unsigned int}[byte {aka unsigned char}]' for array subscript". Not 100% sure what that's about.

Also, I'm still having trouble analyzing the "packed field" byte, which contains several bits of information. I get wrong values for color resolution (should be "8"), and the number of indexed colors (is 4 but should be 10).

According to sourceforge, the packed field byte looks like this:

My packed field byte I get from my code, when expanded, equals 10000100. So I am going to have to see why that is.

I may be wholely out of my depth here trying to write a GIF decoder function like this, but it kind of seems like a cool sub-project to take on while I will spend two weeks twiddling my thumbs waiting for my ESP32 module to arrive from China :slight_smile:

mglogo-zip2.zip (2.38 KB)