
/*****************************************************************************/
/****  File sorgente gifencode.c                              	          ****/
/****  di Alberto Geneletti	version 1.0	giugno 1993               ****/
/****                                                                     ****/
/****  Routines di codifica della sintassi del formato GIF.               ****/
/*****************************************************************************/

#include <stdio.h>
#include <string.h>

#include "gif.h"

int SaveGIF(char *FileName, GIFImage *GIFIm)
{

	char Size;
	char CommentSize;
	char Sig89[] = "GIF89a";
	
   	if(GIFIm->Status & FILE_OPEN)
		CloseGIF(GIFIm);

   	if(!(GIFIm->FD = fopen(FileName,"wb")))
		return(FILE_EXIST);

   	GIFIm->Status |= FILE_OPEN;

   	if(!GIFIm->ScreenDescriptor) {
		if(!(GIFIm->ScreenDescriptor = (ScreenDescriptor *)
			malloc(sizeof(ScreenDescriptor)) )) {
				return(ALLOCATION_ERROR);
		}
		else
			GIFIm->AllocationFlags |= AUTOALLOCATED_SCR_DESCRIPTOR;

		GIFIm->ScreenDescriptor->LSBWidth =
				(int8)(GIFIm->Width & 0xff);
		GIFIm->ScreenDescriptor->MSBWidth =
				(int8)(GIFIm->Width >> 8);
		GIFIm->ScreenDescriptor->LSBHeight =
				(int8)(GIFIm->Height & 0xff);
		GIFIm->ScreenDescriptor->MSBHeight =
				(int8)(GIFIm->Height >> 8);
		GIFIm->ScreenDescriptor->PackedFields =
				(int8)((GIFIm->Depth - 1) | 0xf0);
		GIFIm->ScreenDescriptor->BackGround = 0;
		GIFIm->ScreenDescriptor->Aspect = 0;
        }

	if(!GIFIm->ImageDescriptor) {
		if (!(GIFIm->ImageDescriptor = (ImageDescriptor *)
			malloc(sizeof(ImageDescriptor)))) {
				return(ALLOCATION_ERROR);
		}
		else 
        		GIFIm->AllocationFlags |= AUTOALLOCATED_IMG_DESCRIPTOR;

		GIFIm->ImageDescriptor->LSBLeftOffset = 0;
		GIFIm->ImageDescriptor->MSBLeftOffset = 0;
		GIFIm->ImageDescriptor->LSBTopOffset = 0;
		GIFIm->ImageDescriptor->MSBTopOffset = 0;
		GIFIm->ImageDescriptor->LSBWidth =
				(int8)(GIFIm->Width & 0xff);
		GIFIm->ImageDescriptor->MSBWidth =
				(int8)(GIFIm->Width >> 8);
		GIFIm->ImageDescriptor->LSBHeight =
				(int8)(GIFIm->Height & 0xff);
		GIFIm->ImageDescriptor->MSBHeight =
				(int8)(GIFIm->Height >> 8);
	}

        GIFIm->InitialCodeSize = GIFIm->Depth;

   	if(GIFIm->InterLace)
		GIFIm->ImageDescriptor->PackedFields = (int8)
				((GIFIm->Depth - 1) | 0x40);
	else
		GIFIm->ImageDescriptor->PackedFields = (int8)0x00;

	if(GIFIm->CommentExtension)
		memcpy(GIFIm->Signature,Sig89,6);


   	if(fwrite(GIFIm->Signature,1,6,GIFIm->FD) != 6) {
		CloseGIF(GIFIm);
		return(OUT_OF_DISK_SPACE);
   	}

	if(fwrite((char *)GIFIm->ScreenDescriptor,1,
		sizeof(ScreenDescriptor),GIFIm->FD)
		!=sizeof(ScreenDescriptor) ) {
			CloseGIF(GIFIm);
			return(OUT_OF_DISK_SPACE);
   	}

   	if(GIFIm->ScreenDescriptor->PackedFields &0x80)
		if(fwrite((char *)&GIFIm->GlobalColorMap->Entry[0],1,
			GIFIm->NGlobalColors * 3,GIFIm->FD) !=
			GIFIm->NGlobalColors * 3) {
				CloseGIF(GIFIm);
				return(OUT_OF_DISK_SPACE);
		}

   	fwrite(",",1,1,GIFIm->FD);

   	if (fwrite((char *)GIFIm->ImageDescriptor,1,sizeof(ImageDescriptor),
		GIFIm->FD) != sizeof(ImageDescriptor)) {
			CloseGIF(GIFIm);
			return(OUT_OF_DISK_SPACE);
   	}

   	if(GIFIm->ImageDescriptor->PackedFields &0x80)
		if(fwrite((char *)&GIFIm->LocalColorMap->Entry[0],1,
			GIFIm->NLocalColors * 3,GIFIm->FD)
			!= GIFIm->NLocalColors * 3) {
				CloseGIF(GIFIm);
				return(OUT_OF_DISK_SPACE);

	    	}

   	Size = (char)GIFIm->InitialCodeSize;
   	fwrite(&Size,1,1,GIFIm->FD);
   	PutBitMap(GIFIm);

   	if(GIFIm->CommentExtension) {
		fwrite("!",1,1,GIFIm->FD);
		fputc(0xfe,GIFIm->FD);
		CommentSize = (char)(strlen(GIFIm->CommentExtension)+1);
		fwrite(&CommentSize,1,1,GIFIm->FD);
		fwrite(GIFIm->CommentExtension,1,(int)CommentSize,GIFIm->FD);
		fputc(0x00,GIFIm->FD);
   	}

   	fwrite(";",1,1,GIFIm->FD);

        CloseGIF(GIFIm);
        return(OK);
}

