📄 pack.cpp
字号:
#include "graphics.h"
DATA_FILE *data_file = NULL;
// 建立一个数据文件
void create_data_file(char *filename)
{
close_data_file();
data_file = new DATA_FILE;
data_file->fp = fopen(filename, "wb+");
put_message(data_file->fp == NULL, "错误,建立新数据文件失败。");
data_file->file_count = 0;
fwrite(&data_file->file_count, sizeof(DWORD), 1, data_file->fp);
data_file->pack_file_list = create_list();
}
// 打开一个数据文件
void open_data_file(char *filename)
{
close_data_file();
data_file = new DATA_FILE;
data_file->fp = fopen(filename, "rb");
put_message(data_file->fp == NULL, "错误,打开数据文件失败。");
fread(&data_file->file_count, sizeof(DWORD), 1, data_file->fp);
data_file->pack_file_list = create_list();
PACK_FILE *temp;
// 装入数据文件列表
for (DWORD i = 0; i < data_file->file_count; i++)
{
temp = new PACK_FILE;
fread(&temp->ID, sizeof(DWORD), 1, data_file->fp);
fread(&temp->pos, sizeof(DWORD), 1, data_file->fp);
fread(temp->filename, 64, 1, data_file->fp);
fread(&temp->oldsize, sizeof(DWORD), 1, data_file->fp);
fread(&temp->filesize, sizeof(DWORD), 1, data_file->fp);
fread(&temp->compress, sizeof(BOOL), 1, data_file->fp);
add_point(data_file->pack_file_list, temp);
fseek(data_file->fp, temp->filesize, SEEK_CUR);
}
}
/* * * * * * * * * * * *
* 添加文件到数据文件 *
* 音乐文件不要压缩 *
* * * * * * * * * * * */
void add_file(char *filename, DWORD ID, BOOL comp)
{
put_message(data_file == NULL, "错误,当前没有打开数据文件。");
FILE *fp;
PACK_FILE *pf = new PACK_FILE;
put_message(pf == NULL, "错误,没有足够的内存。");
fp = fopen(filename, "rb");
put_message(fp == NULL, "错误,打开文件%s失败", filename);
fseek(data_file->fp, 0, SEEK_END);
fseek(fp, 0, SEEK_END);
DWORD pos = ftell(data_file->fp);
DWORD size = ftell(fp);
fseek(data_file->fp, 0, SEEK_SET);
fseek(fp, 0, SEEK_SET);
data_file->file_count++;
fwrite(&data_file->file_count, sizeof(DWORD), 1, data_file->fp);
fseek(data_file->fp, 0, SEEK_END);
pos += sizeof(PACK_FILE);
pf->ID = ID;
pf->pos = pos;
strcpy(pf->filename, filename);
char *buffer = new char [size];
put_message(buffer == NULL, "错误,没有足够的内存。");
fread(buffer, size, 1, fp);
pf->oldsize = size;
pf->filesize = size;
if (!comp)
{
pf->compress = FALSE;
fwrite(&pf->ID, sizeof(DWORD), 1, data_file->fp);
fwrite(&pf->pos, sizeof(DWORD), 1, data_file->fp);
fwrite(&pf->filename, 64, 1, data_file->fp);
fwrite(&pf->oldsize, sizeof(DWORD), 1, data_file->fp);
fwrite(&pf->filesize, sizeof(DWORD), 1, data_file->fp);
fwrite(&pf->compress, sizeof(BOOL), 1, data_file->fp);
fwrite(buffer, pf->filesize, 1, data_file->fp);
delete buffer;
}
else
{
char *cbuffer = new char [pf->filesize];
pf->filesize = compress(buffer, pf->filesize, cbuffer);
pf->compress = TRUE;
fwrite(&pf->ID, sizeof(DWORD), 1, data_file->fp);
fwrite(&pf->pos, sizeof(DWORD), 1, data_file->fp);
fwrite(&pf->filename, 64, 1, data_file->fp);
fwrite(&pf->oldsize, sizeof(DWORD), 1, data_file->fp);
fwrite(&pf->filesize, sizeof(DWORD), 1, data_file->fp);
fwrite(&pf->compress, sizeof(BOOL), 1, data_file->fp);
fwrite(cbuffer, pf->filesize, 1, data_file->fp);
delete buffer;
delete cbuffer;
}
add_point(data_file->pack_file_list, pf);
fclose(fp);
}
// 关闭数据文件
void close_data_file()
{
if (data_file != NULL)
{
free_list(&data_file->pack_file_list);
fclose(data_file->fp);
}
}
// 只有数据包内的子文件才可以在压缩状态打开
// 读入一个标准WindowsBMP(8位色 或 24位色)
BMP *load_pack_win_bitmap(char *filename)
{
BOOL find_ok = FALSE;
seek_to_first(data_file->pack_file_list);
PACK_FILE *pf;
for (DWORD c = 0; c < data_file->file_count; c++)
{
pf = (PACK_FILE *)get_data(data_file->pack_file_list);
if (strcmp(pf->filename, filename) == 0)
{
find_ok = TRUE;
break;
}
seek_to_next(data_file->pack_file_list);
}
if (!find_ok)
return NULL;
fseek(data_file->fp, pf->pos, SEEK_SET);
BMP *bmp;
if (!pf->compress)
{
// 处理没有压缩的
BITMAPFILEHEADER bmpheader; // 取BMP文件头信息
if (fread(&bmpheader, sizeof(bmpheader), 1, data_file->fp) == NULL)
{
fclose(data_file->fp);
put_message(TRUE,
"错误,读取文件头失败。");
}
if (bmpheader.bfType != 19778)
{
fclose(data_file->fp);
put_message(TRUE,
"错误,不是标准Windows BMP文件。");
}
BITMAPINFOHEADER bmpinfo;// 取BMP文件信息
if (fread(&bmpinfo, sizeof(bmpinfo), 1, data_file->fp) == NULL)
{
fclose(data_file->fp);
put_message(TRUE,
"错误,读取图象信息失败。");
}
if ((bmpinfo.biCompression != BI_RGB) || ((bmpinfo.biBitCount!=8)&&(bmpinfo.biBitCount != 24)))
{
fclose(data_file->fp); // 是否未压缩且为8 or 24位色
put_message(TRUE,
"错误,这个Windows BMP是已压缩的。");
}
bmp = new BMP;
put_message(bmp == NULL, "错误,没有足够的内存。");
bmp->height = bmpinfo.biHeight ;
bmp->width = bmpinfo.biWidth ;
bmp->cliptop = bmp->clipleft = 0;
bmp->clipright = bmp->width - 1;
bmp->clipbottom = bmp->height - 1;
bmp->pitch_byte = WORD(bmp->width << 1);
bmp->pitch_word = bmp->width;
bmp->pitch_dword = bmp->width / 2;
bmp->surface_byte = bmp->pitch_byte * bmp->height;
bmp->surface_word = bmp->pitch_word * bmp->height;
bmp->surface_dword = bmp->pitch_dword * bmp->height;
bmp->colorkey = 0x0;
bmp->bit = new WORD [bmp->surface_word];
if (Is555)
bmp->pixelbitcount = 15;
else
bmp->pixelbitcount = 16;
put_message(bmp->bit == NULL, "错误,没有足够的内存。");
if (bmpinfo.biBitCount == 8) // 8位色的处理
{
RGBQUAD *quad;
quad = new RGBQUAD[256];
if (quad == NULL)
{
fclose(data_file->fp);
put_message(TRUE,
"错误,没有足够的内存。");
return NULL;
}
WORD *pal;
pal = new WORD[256];
if (pal == NULL)
{
delete quad;
fclose(data_file->fp);
put_message(TRUE,
"错误,没有足够的内存。");
return NULL;
}
fread(quad, sizeof(RGBQUAD) * 256, 1, data_file->fp);
DWORD c;
for (int i = 0; i < 256; i++) // 调色板
{
c = ((((DWORD)quad[i].rgbRed) << 16) | (((DWORD)quad[i].rgbGreen) << 8) | ((DWORD)quad[i].rgbBlue));
pal[i] = true_to_hi(c);
}
for (int ii = 0; ii < 256; ii++)
pal[ii] = true_to_hi(*((DWORD *)(quad + ii)));
WORD* Offset = bmp->bit;
DWORD linesize;
BYTE* buffer;
linesize = (bmpinfo.biWidth + 3) & 0xfffffffc;
buffer = (BYTE *)malloc(linesize);
for (i = bmpinfo.biHeight - 1; i >= 0; i--)
{
Offset = bmp->bit + i * bmpinfo.biWidth ;
fread(buffer, linesize, 1, data_file->fp);
for (int j = 0; j < bmpinfo.biWidth; j++)
Offset[j] = pal[buffer[j]];
}
delete buffer;
Offset = NULL;
delete pal;
delete quad;
return bmp;
}
// 24位色处理
int linesize = (bmpinfo.biWidth * 3 + 3) & 0xfffffffc;
BYTE *Buffer;
Buffer = new BYTE[linesize];
if (Buffer == NULL)
{
fclose(data_file->fp);
put_message(TRUE,
"错误,没有足够的内存。");
return NULL;
}
WORD *Offset;
for (int i = bmpinfo.biHeight - 1; i >= 0; i--)
{
fread(Buffer, linesize, 1, data_file->fp);
Offset = bmp->bit + i * bmpinfo.biWidth;
for (int j = 0; j < bmpinfo.biWidth; j++)
Offset[j] = true_to_hi((*(DWORD *)(Buffer + j * 3)));
}
delete Buffer;
Offset = NULL;
return bmp;
}
else
{
// 处理压缩过的
BITMAPFILEHEADER bmpheader; // 取BMP文件头信息
char *filebuffer, *cbuffer, *pbuffer;
cbuffer = new char [pf->filesize];
put_message(cbuffer == NULL, "错误,没有足够的内存空间。");
fread(cbuffer, pf->filesize, 1, data_file->fp);
filebuffer = new char [pf->oldsize];
put_message(filebuffer == NULL, "错误,没有足够的内存空间。");
decompress(cbuffer, pf->filesize, filebuffer);
delete cbuffer;
pbuffer = filebuffer;
memcpy(&bmpheader, pbuffer, sizeof(bmpheader));
pbuffer += sizeof(bmpheader);
if (bmpheader.bfType != 19778)
{
delete filebuffer;
fclose(data_file->fp);
put_message(TRUE,
"错误,不是标准Windows BMP文件。");
}
BITMAPINFOHEADER bmpinfo;// 取BMP文件信息
memcpy(&bmpinfo, pbuffer, sizeof(bmpinfo));
pbuffer += sizeof(bmpinfo);
if ((bmpinfo.biCompression != BI_RGB) || ((bmpinfo.biBitCount!=8)&&(bmpinfo.biBitCount != 24)))
{
delete filebuffer;
fclose(data_file->fp); // 是否未压缩且为8 or 24位色
put_message(TRUE,
"错误,这个Windows BMP是已压缩的。");
}
bmp = new BMP;
put_message(bmp == NULL, "错误,没有足够的内存。");
bmp->height = bmpinfo.biHeight ;
bmp->width = bmpinfo.biWidth ;
bmp->cliptop = bmp->clipleft = 0;
bmp->clipright = bmp->width - 1;
bmp->clipbottom = bmp->height - 1;
bmp->pitch_byte = WORD(bmp->width << 1);
bmp->pitch_word = bmp->width;
bmp->pitch_dword = bmp->width / 2;
bmp->surface_byte = bmp->pitch_byte * bmp->height;
bmp->surface_word = bmp->pitch_word * bmp->height;
bmp->surface_dword = bmp->pitch_dword * bmp->height;
bmp->colorkey = 0x0;
bmp->bit = new WORD [bmp->surface_word];
if (Is555)
bmp->pixelbitcount = 15;
else
bmp->pixelbitcount = 16;
put_message(bmp->bit == NULL, "错误,没有足够的内存。");
if (bmpinfo.biBitCount == 8) // 8位色的处理
{
RGBQUAD *quad;
quad = new RGBQUAD[256];
if (quad == NULL)
{
delete bmp;
delete filebuffer;
fclose(data_file->fp);
put_message(TRUE,
"错误,没有足够的内存。");
return NULL;
}
WORD *pal;
pal = new WORD[256];
if (pal == NULL)
{
delete bmp;
delete filebuffer;
delete quad;
fclose(data_file->fp);
put_message(TRUE,
"错误,没有足够的内存。");
return NULL;
}
memcpy(quad, pbuffer, sizeof(RGBQUAD) * 256);
pbuffer += sizeof(RGBQUAD) * 256;
DWORD c;
for (int i = 0; i < 256; i++) // 调色板
{
c = ((((DWORD)quad[i].rgbRed) << 16) | (((DWORD)quad[i].rgbGreen) << 8) | ((DWORD)quad[i].rgbBlue));
pal[i] = true_to_hi(c);
}
for (int ii = 0; ii < 256; ii++)
pal[ii] = true_to_hi(*((DWORD *)(quad + ii)));
WORD* Offset = bmp->bit;
DWORD linesize;
BYTE* buffer;
linesize = (bmpinfo.biWidth + 3) & 0xfffffffc;
buffer = (BYTE *)malloc(linesize);
for (i = bmpinfo.biHeight - 1; i >= 0; i--)
{
Offset = bmp->bit + i * bmpinfo.biWidth ;
memcpy(buffer, pbuffer, linesize);
pbuffer += linesize;
for (int j = 0; j < bmpinfo.biWidth; j++)
Offset[j] = pal[buffer[j]];
}
delete filebuffer;
delete buffer;
Offset = NULL;
delete pal;
delete quad;
return bmp;
}
// 24位色处理
int linesize = (bmpinfo.biWidth * 3 + 3) & 0xfffffffc;
BYTE *Buffer;
Buffer = new BYTE[linesize];
if (Buffer == NULL)
{
delete filebuffer;
delete bmp;
fclose(data_file->fp);
put_message(TRUE,
"错误,没有足够的内存。");
return NULL;
}
WORD *Offset;
for (int i = bmpinfo.biHeight - 1; i >= 0; i--)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -