No, it’s not trying to load all image into RAM, there’s just dictionary, for decoding GIF file…
This is the error, that gives local compiler:
c:/program files (x86)/gnu tools arm embedded/4.8 2013q4/bin/../lib/gcc/arm-none
-eabi/4.8.3/../../../../arm-none-eabi/bin/ld.exe: region `RAM' overflowed by 808
bytes
collect2.exe: error: ld returned 1 exit status
make: *** [core-firmware.elf] Error 1
gif.h:
#ifndef __GIF_H__
#define __GIF_H__
#include <SD.h>
#include "ws2812.h"
#include "spark_wiring_usbserial.h"
typedef struct{
unsigned short SCREEN_WIDTH;
unsigned short SCREEN_HEIGHT;
unsigned char BYTE_5;
unsigned char BACKGROUND;
unsigned char ASPECT_RATIO;
} SCREEN_DESC;
//Struktura do przechowywania deskryptora obrazu
typedef struct{
unsigned short LEFT;
unsigned short UP;
unsigned short IMAGE_WIDTH;
unsigned short IMAGE_HEIGHT;
unsigned char BYTE_9;
} IMAGE_DESC;
//Struktura triady (R,G,B)
typedef struct{
unsigned char R;
unsigned char G;
unsigned char B;
} COLOR;
//Struktura pliku GIF - deskryptory
typedef struct{
SCREEN_DESC screenDesc;
IMAGE_DESC imageDesc;
} GIF_IMAGE;
//Struktura elementu slownika
typedef struct{
unsigned short code;
unsigned short prevCode;
unsigned short nextCode;
} DICTIONARY_ENTRY;
typedef unsigned short WORD;
class GIF
{
private:
unsigned char BUFFER[16];
unsigned char tempCHAR2[3];
unsigned short PrimaryCodeSize, PrimaryDictSize;
unsigned short currentCodeSize, currentDictSize;
unsigned short code, oldcode = 0;
unsigned short code1, code2;
unsigned short code_CLEAR, code_END;
COLOR g_GlobalColorTable[256];
#define MAX_DICT_SIZE 100
DICTIONARY_ENTRY Dictionary[MAX_DICT_SIZE]; //max. 4096
unsigned char bitsRemaining;
unsigned short getNextCode(void);
int checkSignature(char*);
File g_fileObject;
WORD g_odczytanych_bajtow;
unsigned char read_code;
unsigned short x_pos, y_pos, k;
//unsigned short sWidth, sHeight;
unsigned char byte5;
unsigned char byte9;
unsigned char currentDataSectionLength;
public:
int drawGIFImage(File, GIF_IMAGE*);
unsigned char counter;
void GIFDrawPixel(unsigned char);
unsigned short imgWidth, imgHeight;
led *framebuffer;
};
#endif
gif.cpp:
#include "gif.h"
int GIF::drawGIFImage(File fileObject, GIF_IMAGE * gifImage){
unsigned int i;
unsigned char bpp;
unsigned short minLZWCodeLength;
unsigned int GCT_size;
g_fileObject = fileObject;
g_fileObject.read((void*)&BUFFER, 6);
if(checkSignature((char*)BUFFER) != 1) return -1;
g_fileObject.read(&BUFFER, 7);
(*gifImage).screenDesc.SCREEN_WIDTH = (BUFFER[1] << 8) + BUFFER[0];
(*gifImage).screenDesc.SCREEN_HEIGHT= (BUFFER[3] << 8) + BUFFER[2];
(*gifImage).screenDesc.BYTE_5 = BUFFER[4];
(*gifImage).screenDesc.BACKGROUND = BUFFER[5];
(*gifImage).screenDesc.ASPECT_RATIO = BUFFER[6];
byte5 = (*gifImage).screenDesc.BYTE_5;
bpp = (byte5 & 0x07);
GCT_size = 2 << bpp;
if(byte5 & 0x80){
for(i = 0; i < GCT_size; i++){
g_fileObject.read(&BUFFER, 3);
g_GlobalColorTable[i].R = BUFFER[0];
g_GlobalColorTable[i].G = BUFFER[1];
g_GlobalColorTable[i].B = BUFFER[2];
}
}
else return -1;
do g_fileObject.read(&BUFFER, 1);
while(BUFFER[0] != 0x2C);
g_fileObject.read(&BUFFER, 11);
(*gifImage).imageDesc.LEFT = (BUFFER[1] << 8) + BUFFER[0];
(*gifImage).imageDesc.UP = (BUFFER[3] << 8) + BUFFER[2];
(*gifImage).imageDesc.IMAGE_WIDTH = (BUFFER[5] << 8) + BUFFER[4];
(*gifImage).imageDesc.IMAGE_HEIGHT= (BUFFER[7] << 8) + BUFFER[6];
(*gifImage).imageDesc.BYTE_9 = BUFFER[8];
imgWidth = (*gifImage).imageDesc.IMAGE_WIDTH;
imgHeight = (*gifImage).imageDesc.IMAGE_HEIGHT;
byte9 = (*gifImage).imageDesc.BYTE_9;
minLZWCodeLength = BUFFER[9] + 1;
currentDataSectionLength = BUFFER[10];
code_CLEAR = GCT_size;
code_END = GCT_size + 1;
PrimaryDictSize = GCT_size + 2;
PrimaryCodeSize = minLZWCodeLength;
currentCodeSize = minLZWCodeLength;
currentDictSize = PrimaryDictSize;
counter = 0;
for(i = 0; i < MAX_DICT_SIZE; i++)
Dictionary[i].prevCode = Dictionary[i].nextCode = 0;
x_pos = 1; y_pos = 130;
bitsRemaining = 0;
while( (code = getNextCode()) != code_END){
if(code == code_CLEAR){
currentCodeSize = PrimaryCodeSize;
currentDictSize = PrimaryDictSize;
oldcode = getNextCode();
if(oldcode > currentDictSize){
return -3;
}
GIFDrawPixel(oldcode);
continue;
}
if(code < currentDictSize){
code1 = code;
code2 = 0;
while(code1 >= PrimaryDictSize){
Dictionary[code1 - PrimaryDictSize].nextCode = code2;
code2 = code1;
code1 = Dictionary[code1 - PrimaryDictSize].prevCode;
if(code1 >= code2)
return -3;
}
GIFDrawPixel(code1);
while(code2!=0){
GIFDrawPixel(Dictionary[code2 - PrimaryDictSize].code);
code2 = Dictionary[code2 - PrimaryDictSize].nextCode;
}
Dictionary[currentDictSize - PrimaryDictSize].code = code1;
Dictionary[currentDictSize - PrimaryDictSize].prevCode = oldcode;
++currentDictSize;
if(currentDictSize == MAX_DICT_SIZE) return -2;
if((currentDictSize) == (0x0001<<currentCodeSize))
++currentCodeSize;
if(currentCodeSize > 12)
currentCodeSize = 12;
oldcode = code;
else
{
code1 = oldcode;
code2 = 0;
while(code1 >= PrimaryDictSize){
Dictionary[code1 - PrimaryDictSize].nextCode = code2;
code2 = code1;
code1 = Dictionary[code1 - PrimaryDictSize].prevCode;
if(code1 >= code2)
return -3;
}
GIFDrawPixel(code1);
while(code2!=0){
GIFDrawPixel(Dictionary[code2 - PrimaryDictSize].code);
code2 = Dictionary[code2 - PrimaryDictSize].nextCode;
}
GIFDrawPixel(code1);
Dictionary[currentDictSize - PrimaryDictSize].code = code1;
Dictionary[currentDictSize - PrimaryDictSize].prevCode = oldcode;
++currentDictSize;
if(currentDictSize == MAX_DICT_SIZE) return -2;
if((currentDictSize) == (0x0001<<currentCodeSize))
++currentCodeSize;
if(currentCodeSize > 12)
currentCodeSize = 12;
oldcode = code;
}
}
return 0;
}
int GIF::checkSignature(char * IN){
char signature[6];
int i;
for(i = 0; i < 6; i++)
signature[i] = IN[i];
if( (strcmp(signature,"GIF87a") == 0) || (strcmp(signature,"GIF89a") == 0) )
return 1;
else
return 0;
}
unsigned short GIF::getNextCode(void){
unsigned int retval=0, temp;
if(bitsRemaining >= currentCodeSize){
retval = (read_code & ((0x01 << currentCodeSize) - 1));
read_code >>= currentCodeSize;
bitsRemaining -= currentCodeSize;
}
else{
retval = (read_code & ((0x01 << bitsRemaining) - 1));
g_fileObject.read(&read_code, 1);
++counter;
if(counter == currentDataSectionLength){
counter = 0;
g_fileObject.read(¤tDataSectionLength, 1);
}
if((currentCodeSize - bitsRemaining) <= 8){
temp = (read_code & ((0x01 << (currentCodeSize - bitsRemaining)) - 1));
retval += (temp << bitsRemaining);
read_code >>= (currentCodeSize - bitsRemaining);
bitsRemaining = 8 - (currentCodeSize - bitsRemaining);
}
else{
retval += (read_code << bitsRemaining);
g_fileObject.read(&read_code, 1);
++counter;
if(counter == currentDataSectionLength){
counter = 0;
g_fileObject.read(¤tDataSectionLength, 1);
}
retval += ((read_code & ((0x01 << (currentCodeSize - bitsRemaining - 8)) - 1)) << (bitsRemaining + 8));
read_code >>= (currentCodeSize - bitsRemaining - 8);
bitsRemaining = 8 - (currentCodeSize - bitsRemaining - 8);
}
}
return retval;
}
void GIF::GIFDrawPixel(unsigned char code){
COLOR rgbColor;
rgbColor = g_GlobalColorTable[code];
int pix = x_pos*imgHeight+y_pos;
Serial.println((int)pix);
Serial.println((int)rgbColor.R);
Serial.println((int)rgbColor.G);
Serial.println((int)rgbColor.B);
}