Parsing images from SD

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(&currentDataSectionLength, 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(&currentDataSectionLength, 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);
}