#### Archived

This topic is now archived and is closed to further replies.

# Packing BMP files into one file?

This topic is 5061 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hey there. I don''t know exactly what I''m looking for, so I hope you can offer some help. Well, I have seen this done by people on these boards, and I am wanting to learn to do it myself. People pack multiple types of files into one package file (ex. myGfx.pkg). I am just curious, because I would like to be able to do this in future games I am planning. I don''t want to distribute all the individual bitmap files, etc., separately. Also, how would I read each of these into separate bitmap items (extract them from the package file)? If you can''t offer any direct solution, but can offer some help to previous threads, other websites, etc., please do. Thanks in advance, Matt U.

##### Share on other sites
I've never done it before but it seems like it would be simple.

Set your file up like this.

Long - Number of files included.

For each above:
Char[256] - Name of file.
Long - Start of file (from begining).
Long - Length of file.

For each file:
The file.

You could read in the long, then read in the "index" into an array, cruise the array for your file, jump the file to the start, read in the length, bam.

edit:

Havnt compiled it yet, but id like to think it would work.

#include <stdio.h>class cPackageReader{private:	struct sIndex	{		char FileName[256];		long Start;		long Length;	};	FILE *file;	sIndex *Index;	long count;public:	cPackageReader();	~cPackageReader();	bool OpenPackage(char *filename);	void ClosePackage();	bool ReturnFile(char *filename, char *&data);};cPackageReader::cPackageReader(){	file = 0;	Index = 0;}cPackageReader::~cPackageReader(){	delete file;	delete[] Index;}bool cPackageReader::OpenPackage(char *filename){	file = fopen(filename, "r");	if (!file)		return false;		fread(&count, sizeof(long), 1, file);	if (ferror(file))		return false;	Index = new sIndex[count];	memset(Index, 0, sizeof(sIndex)*count);	fread(&Index, sizeof(sIndex), count, file);	if (ferror(file))		return false;	return true;}void cPackageReader::ClosePackage(){	delete[] Index;	Index = 0;	fclose(file);	file = 0;	count = 0;}bool cPackageReader::ReturnFile(char *filename, char *&data){	long i;	for (i =0; i < count; i++)	{		if (strcmp(filename, Index[i].FileName)==0)		{			fseek(file, Index[i].Start, SEEK_SET);			if (ferror(file))				return false;			data = 0;			data = new char[Index[i].Length];			fread(data, Index[i].Length, 1, file);			if (ferror(file))				return false;			return true;		}	}	return false;}

edit2:

The writer, havn't compiled, hope it works, may need to tweek.

#include <stdio.h>class cPackageWriter{private:	struct sIndexOut	{		char FileName[256];		long Start;		long Length;	};	struct sIndex	{		char FileName[256];		long Start;		long Length;		char *data;		sIndex *next;		sIndex(sIndex *ptr)		{			memset(filename, 0, 256);			next = ptr;			data = 0;		}		~sIndex()		{			delete[] data;			delete next;		}	};	sIndex *Index;	bool creating;	long count;public:	cPackageWriter();	~cPackageWriter();	bool CreatePackage();	bool Addfile(char *filename);	bool FinalizePackage(char *filename);	bool AddChunk(char *data, long length, char *name);};cPackageWriter::cPackageWriter(){	Index = 0;	creating = false;}cPackageWriter::~cPackageWriter(){	delete Index;}bool cPackageWriter::CreatePackage(){	if (creating)		return false;		creating = true;	delete Index;	Index = 0;	count = 0;	return true;}bool cPackageWriter::FinalizePackage(char *filename){	sIndex *indexer = Index;	sIndexOut *outindex;	long boop = 0;	if (!creating || count == 0)		return false;	FILE *file = fopen(filename, "wb");	if (file == 0) 		return false;	fwrite(&count, sizeof(long), 1, file);	outindex = new sIndexOut[count];	memset(outindex, 0, sizeof(sIndexOut)*count);	boop = sizeof(long) + sizeof(sIndexOut)*count;	for (long i = 0; i < count; i ++)	{		memcpy(outindex[i].filename, indexer->FileName, 256);		outindex[i].Length = indexer->Length;		outindex[i].start = boop;		boop += indexer->Length;		indexer = indexer->next;	}	fwrite(outindex, sizeof(sIndexOut), count, file);	indexer = Index;	for (long i = 0; i < count; i ++)	{		fwrite(indexer->data, indexer->length, 1, file);	}	fclose(file);	creating = false;	return true;}bool cPackageWriter::AddChunk(char *data, long length, char *name){	if (!creating)		return false;	sIndex *temp = Index;	Index = 0;	Index = new sIndex(temp);	memcpy(Index->FileName, name, strlen(name));	Index->Length = length	Index->data = new char[Index->Length];	memcpy(Index->data, data, length);	count++;	return true;}bool cPackageWriter::Addfile(char *filename){	if (!creating)		return false;	sIndex *temp = Index;	File *file = fopen(filename, "rb");	if (file == 0)		return false;	Index = 0;	Index = new sIndex(temp);	memcpy(Index->FileName, filename, strlen(filename));	fseek(file, 0, SEEK_END);	Index->Length = ftell(file);	Index->data = new char[Index->Length];	fseek(file, 0, SEEK_SET);	fread(Index->data, Index->Length, 1, file);	if (ferror(file))	{		Index->next = 0;		delete Index;		Index = temp;		return false;	}	count++;	return true;}

[edited by - honayboyz on April 10, 2004 12:28:49 PM]

[edited by - honayboyz on April 10, 2004 1:02:24 PM]

##### Share on other sites
Hey, thanks for the reply. I kind of thought it would have something to do with that.

Now I need to know how to place the data that is read into a bitmap, and save it to a temporary file. How would I do that?

##### Share on other sites
For your typical archive type of file, it is better to put the header at the end of the file. This allows it to be much easier to add files to an archive. As then you only need to add the file to the end, where the original header began, and then write out the new header.

##### Share on other sites
Good call, would you put a value at the begining of the file telling where the header started then?

##### Share on other sites
quote:
Original post by Mastaba
For your typical archive type of file, it is better to put the header at the end of the file. This allows it to be much easier to add files to an archive. As then you only need to add the file to the end, where the original header began, and then write out the new header.

A game content archive isn''t your typical archive type of file. It doesn''t matter how long it takes to build the archive, since that''s done before the game ever ships. The only speed that matters is the speed of locating and loading a particular file within the archive.

"Sneftel is correct, if rather vulgar." --Flarelocke

##### Share on other sites
True. But wouldn''t you want your toolset to be the best it could be?

##### Share on other sites
Yes. And a good toolset should never sacrifice the quality of the user experience, not for anything.

Besides, realistically, how often are you going to append files to a content archive? I can think of only one possibility: when you first create the first draft of a piece of content. After that, you''d be updating the file in the archive, and if it changed size, you''d have to move the other files around anyway. So the actual benefits of this are extremely limited.

"Sneftel is correct, if rather vulgar." --Flarelocke

##### Share on other sites
Your goofy. Why would appending files at the end sacrifice the users experience?

You act like it would cost a life to put the index at the end, yea my free code that probably dosnt work already, wont work. If files were apendable, removeable, replacable it wouldn''t hurt.

##### Share on other sites
Putting the index at the end slows access times by forcing extra seeks, thus making individual files slower to load. It''s not a big difference, but since (as I explained) putting the index at the end is more or less useless, there''s really no reason for the extra complexity.

"Sneftel is correct, if rather vulgar." --Flarelocke

##### Share on other sites
When are you going to give in? So this isn''t just a girly fight, post some evidence of how it''s so useless. How slow is 1 more seek? All you would have to do is seek into the index. How much more code do you have to add to reorder a file with the index in the front?

Actualy, I guess if you look at it from the, "if it isn''t broke dont fix it" view, it is useless for his only listed purpose.