剑芒罗曼史2解图片程序

来源:互联网 发布:单片机程序编译软件 编辑:程序博客网 时间:2024/04/29 10:56
剑芒罗曼史2解图片程序

mcg文件

file head 40h
---------------------------
10h palette offset
1ch width
20h height
---------------------------

palette 400h
---------------------------
BMP's palette
---------------------------

pixel data
使用一种比较特殊的压缩法,至少是我不知道的,呵呵,具体的解码函数看0x422990吧

使用工具

IDA 4.0
TRW 2000


注:
dat/plane/n0.mcg,实际上不是mcg文件,好像是bmp吧,先把它换名再运行才不会出问题!


#include <stdio.h>
#include <windows.h>
#include <malloc.h>
#include <io.h>
#include <conio.h>

typedef struct BITMAPHEADER
{
   unsigned short type;
   unsigned long  size;
   unsigned long  reserved;
   unsigned long  offbits;
   unsigned long  headsize;
   unsigned long  width;
   unsigned long  height;
   unsigned short planes;
   unsigned short bit; 
} BITMAPHEADER;

void encode(BYTE *dst,DWORD length1,BYTE *src,DWORD length2);

void LoadXmp(DWORD &w,DWORD &h,BYTE* &data,char *name)
{
   BITMAPHEADER bmph;
   FILE *fp;
   char *tmp,*line;
   int i,pitch;
   unsigned j;

   fp=fopen(name,"rb");
//   fp=CreateFile(name,0x80000000,1,NULL,3,0x10000080,0);
   
//   GetFileSize(fp,&w);

   data=(BYTE *)malloc(w);
   if(data==NULL)
   {
   printf("Out of memory!");
   return ;
   }

   fread(data,w,1,fp);

   fclose(fp);

//   ReadFile(fp,data,w,&h,NULL);

//   CloseHandle(fp);
}

void SaveBmp(DWORD w,DWORD h,BYTE *data,char * name)
{
FILE *f;
BITMAPFILEHEADER bithead;
BITMAPINFOHEADER bitinfo;
DWORD headsize,linesize,i,j,s,w1,h1;
unsigned long color;

if(data==NULL)
return ;

if((f=fopen(name,"wb"))==NULL)
{
   printf("write file error");
}

memcpy(&w1,data+0x1c,4);
memcpy(&h1,data+0x20,4);
// w1=(DWORD)(*(data+0x1c));
// h1=(DWORD)(*(data+0x20));

linesize=(w1+3)&0xfffffffc;
s=linesize-3;

headsize=sizeof(bithead)+sizeof(bitinfo);
bithead.bfType='MB';
bithead.bfSize=headsize+linesize*h1+1024;
bithead.bfReserved1=bithead.bfReserved2=0;
bithead.bfOffBits=headsize+1024;
fwrite(&bithead,1,sizeof(bithead),f);

bitinfo.biSize=sizeof(bitinfo);
bitinfo.biWidth=w1;
bitinfo.biHeight=h1;
bitinfo.biPlanes=1;
   bitinfo.biBitCount=8;
bitinfo.biCompression=BI_RGB;
bitinfo.biSizeImage=0;
   bitinfo.biXPelsPerMeter=72;
bitinfo.biYPelsPerMeter=72;
bitinfo.biClrUsed=0;
   bitinfo.biClrImportant=0;
fwrite(&bitinfo,1,sizeof(bitinfo),f);


fwrite(data+0x40,0x400,1,f);

BYTE *pixel_data;
pixel_data=(BYTE *)malloc(linesize*h1);
if(pixel_data==NULL)
{
printf("out of memory");
goto ret;
}

encode(pixel_data,linesize*h1,data+0x440,w-0x440);


for(i=0;i<h1;i++)
fwrite(pixel_data+linesize*(h1-i-1),linesize,1,f);

if(pixel_data!=NULL)
free(pixel_data);

ret:
fclose(f);
}

void encode(BYTE *dst,DWORD length1,BYTE *src,DWORD length2)
{
BYTE tmp[0x1000];
DWORD i,j,k,num;

memset(tmp,0,0x1000);

// i=(DWORD)src+length2;
__asm{
mov eax,src;
mov ebx,length2;
add eax,ebx;
mov i,eax;

mov eax,dst;
mov ebx,length1;
add eax,ebx;
mov k,eax;
}

__asm{
push ebx;
push edx;

push esi;

mov ebx,src;
mov edx,dst;
mov esi,0x0fee;

jmp _422a50;
_422a42:
shr num,1;
mov eax,num;
test ah,1;
jnz _422a5d;
_422a50:
mov cl,byte ptr [ebx];
mov ch,0xff;
and ecx,0xffff;
mov num,ecx;

inc ebx;
_422a5d:
test byte ptr num,1;
jz _422a80;
_422a64:
mov al,[ebx];
and esi,0x0fff;

mov ecx,esi;
inc esi;
inc ebx;

mov byte ptr [edx],al;
inc edx;

mov [ecx+tmp],al;

jmp _422ad8;
_422a80:
mov ax,[ebx];
mov cl,ah;

and eax,0x0fff;
shr cl,4;
add cl,3;
inc ebx;
inc ebx;

cmp cl,0;
jz _422ad7;

mov j,ebx;
mov bl,cl;
_422aab:
and eax,0x0fff;
and esi,0x0fff;

mov cl,byte ptr [tmp+eax];
mov [edx],cl;

mov [tmp+esi],cl;

inc eax;
inc esi;
inc edx;

dec bl;
jnz _422aab;
mov ebx,j;
_422ad7:
_422ad8:
cmp ebx,i;
jnb _ret;
cmp edx,k;
jb _422a42;
_ret:
pop esi;
pop edx;
pop ebx;
}
}

void main()
{
DWORD w,h;
BYTE *data;
bool ret;
int i;
long done;
_finddata_t f;

done=_findfirst("*.mcg",&f);
if(done==-1)
return ;
ret=false;

while(!ret)
{
w=f.size;
LoadXmp(w,h,data,f.name);

i=0;
next:
while(f.name[i]!='.')
i++;
if(!((f.name[i+1]=='m'||f.name[i+1]=='M')&&(f.name[i+2]=='c'||f.name[i+2]=='C')&&(f.name[i+3]=='g'||f.name[i+3]=='G')))
{
i++;
goto next;
}

f.name[i+1]='b';
f.name[i+2]='m';
f.name[i+3]='p';

SaveBmp(w,h,data,f.name);

if(data!=NULL)
free(data);

ret=_findnext(done,&f);
}

return ;
}

原创粉丝点击