home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fun CD 26
/
OTACD26.ISO
/
archive
/
game
/
dcast
/
dcast.lzh
/
DCAST.C
next >
Wrap
C/C++ Source or Header
|
1998-07-05
|
8KB
|
331 lines
/******************************
* DOUBLE CAST BMP CONVERTER *
* Programmed By Melody-Yoshi *
******************************/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<windows.h>
#include<commdlg.h>
/* GLOBAL */
unsigned char *mem,*bz,pal[512];
char current[128];
int xwide,ywide,bitl;
FILE *fp,*fo;
unsigned char bitcode;
/* PROTO-TYPES */
int decode(unsigned char *,unsigned char *),analyze(char *);
void outbmp(char *,int),outbmp8(char *,int,int);
void writeshort(short),writelong(long);
int loadbit(int,unsigned char*,int *),load1bit(unsigned char *,int *);
void main(int argc,char *argv[])
{
int i,fsize;
char fn[64],fz[64];
WIN32_FIND_DATA fd;
HANDLE h;
BOOL f;
if(argc<2){
OPENFILENAME ofn;
char szFile[256];
szFile[0]=0;
memset(&ofn,0,sizeof(OPENFILENAME));
ofn.lStructSize=sizeof(OPENFILENAME);
ofn.hwndOwner=NULL;ofn.nFilterIndex=1;
ofn.lpstrFilter="ダブルキャストの画像ファイル\0*.GPX;*.GPL\0\0";
ofn.lpstrFile=szFile;ofn.nMaxFile=sizeof(szFile);
ofn.lpstrFileTitle=NULL;ofn.lpstrInitialDir=NULL;
ofn.Flags=OFN_HIDEREADONLY|OFN_PATHMUSTEXIST;
if(GetOpenFileName(&ofn)){
strcpy(fn,szFile);
}
else exit(1);
}
else strcpy(fn,argv[1]);
strcpy(current,argv[0]);
for(i=strlen(current)-1;i>=0;i--)if(current[i]==':' || current[i]=='\\')break;
current[i+1]=0;
bz=(unsigned char *)malloc(0xE1000);
mem=(unsigned char *)malloc(0x9F000);
if(mem==NULL || bz==NULL){
printf("メモリが足りません。\n");exit(1);
}
for(i=0;fn[i];i++){
if(fn[i]>='a' && fn[i]<='z')fn[i]-=32;
}
for(fn[i]=0;i>=0;i--)if(fn[i]==':' || fn[i]=='\\')break;
h=FindFirstFile(fn,&fd);f=TRUE;
fn[i+1]=0;
while(h!=INVALID_HANDLE_VALUE && f){
if((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)==0){
strcpy(fz,fn);strcat(fz,fd.cFileName);
printf("%s\n",fz);fflush(stdout);
if((fp=fopen(fz,"rb"))==0){
printf("file open error![%s]\n",fz);exit(1);
}
fseek(fp,0L,2);fsize=(int)ftell(fp);fseek(fp,0L,0);
fread(mem,1,fsize,fp);fclose(fp);
strcpy(fz,fd.cFileName);
for(i=0;fz[i];i++)if(fz[i]=='.')break;
fz[i]=0;
analyze(fz);
}
f=FindNextFile(h,&fd);
}
FindClose(h);free(mem);free(bz);exit(0);
}
int analyze(char *fn)
{
int i,j,k,m;
m=1;pal[1]=0xAB;
if(mem[0]==0x83 && mem[1]==0xA1){
i=decode(bz,mem);
if(i>0){
m=0;
if(pal[1]==0xAB)outbmp(fn,-1);
else outbmp8(fn,-1,256);
}
}
else if(mem[0]==0 && mem[1]==0 && mem[3]==0){
j=mem[2];
for(k=0;k<j;k++){
i=mem[k*4+4]|(mem[k*4+5]<<8)|(mem[k*4+6]<<16);
i=decode(bz,&mem[i]);
if(i>0){
m=0;
if(pal[1]==0xAB)outbmp(fn,k);
else outbmp8(fn,k,256);
}
}
}
return(m);
}
int decode(unsigned char *c,unsigned char *b)
{
int i,j,k,m,p,q,r,w,x;
unsigned short s[256];
if(b[16]!=1 && b[16]!=2)return(-1);
for(i=0;i<256;i++)s[i]=i;
xwide=(b[29]<<8)|b[28];ywide=(b[31]<<8)|b[30];p=32;
if(b[17]){
i=b[p]|(b[p+1]<<8);j=b[p+2];k=i*j*2;
memcpy(pal,&b[p+4],k);p=(p+k+7)&0xFFFFFFFC;
}
switch(b[16]&15){
case 1:w=xwide*ywide;break;
case 2:w=xwide*ywide*2;pal[1]=0xAB;break;
}
memset(c,0,w);
for(bitl=q=r=0;q<w;){
if(load1bit(b,&p)){
if(load1bit(b,&p)){
if(load1bit(b,&p)){
j=loadbit(4,b,&p)+1;
i=0;while(load1bit(b,&p))i++;
m=(loadbit(i,b,&p)+(1<<i));
switch(b[16]&15){
case 0:break;
case 1:
for(i=0;i<m;i++,q++)c[q]=c[q-j];
break;
case 2:
for(i=0,j<<=1;i<m;i++,q+=2){
c[q]=c[q-j];c[q+1]=c[q-j+1];
}
break;
}
}
else{
j=loadbit(5,b,&p);
i=0;while(load1bit(b,&p))i++;
m=(loadbit(i,b,&p)+(1<<i));
switch(b[16]&15){
case 0:break;
case 1:
x=q%xwide;i=q-x;
if(x<16)i=i-xwide+j;
else if(x>xwide-16)i=i+j-32;
else i=q-xwide+j-16;
for(j=0;j<m;j++,q++,i++)c[q]=c[i];
break;
case 2:
i=q/2;x=i%xwide;i=i-x;
if(x<16)i=i-xwide+j;
else if(x>xwide-16)i=i+j-32;
else i=q/2-xwide+j-16;
for(j=0,i<<=1;j<m;j++,q+=2,i+=2){
c[q]=c[i];c[q+1]=c[i+1];
}
break;
}
}
}
else{
j=loadbit(4,b,&p)+1;k=loadbit(5,b,&p);
i=0;while(load1bit(b,&p))i++;
m=(loadbit(i,b,&p)+(1<<i));
switch(b[16]&15){
case 0:break;
case 1:
x=q%xwide;i=q-x;
if(x<16)i=i-xwide+k;
else if(x>xwide-16)i=i+k-32;
else i=q-xwide+k-16;
i-=xwide*j;
for(j=0;j<m;j++,q++,i++)c[q]=c[i];
break;
case 2:
i=q/2;x=i%xwide;i=i-x;
if(x<16)i=i-xwide+k;
else if(x>xwide-16)i=i+k-32;
else i=q/2-xwide+k-16;
i-=xwide*j;
for(j=0,i<<=1;j<m;j++,q+=2,i+=2){
c[q]=c[i];c[q+1]=c[i+1];
}
break;
}
}
}
else{
switch(b[16]&15){
case 0: break;
case 1: c[q++]=b[p++];break;
case 2:
k=b[p++];
if(k&0x80){
k=s[((((k&0x7F)<<1)|load1bit(b,&p))+r)&255];
c[q]=k/256;c[q+1]=k&255;q+=2;
}
else{
k=(k<<8)|b[p++];c[q]=k/256;c[q+1]=k&255;q+=2;
r=(r-1)&255;s[r]=k;
}
break;
}
}
}
return(q);
}
/* OUTPUT BMP FILE */
void outbmp8(char *fn,int no,int c)
{
int i,j,sx,xpad;
char fz[48],fs[4];
unsigned short k;
if(no>=0){
fs[0]=(no>>4)+'0';if(fs[0]>57)fs[0]+=7;
fs[1]=(no&15)+'0';if(fs[1]>57)fs[1]+=7;
fs[2]=0;
}
else fs[0]=0;
if(c==16){
for(i=xwide*ywide-1;i>=0;i--)bz[i]=((bz[i]&0xF0)>>4)|((bz[i]&0x0F)<<4);
}
strcpy(fz,current);strcat(fz,fn);strcat(fz,fs);strcat(fz,".BMP");
if((fo=fopen(fz,"wb"))==0){
printf("file create errror.[%s]\n",fz);exit(1);
}
sx=(c==256)?xwide:xwide/2;xpad=(4-(sx&3))&3;
fputc('B',fo);fputc('M',fo); /* ID */
writelong((long)c*4L+54L+(long)(sx+xpad)*(long)ywide); /* FILE SIZE */
writelong(0L); /* RESERVED */
writelong((long)c*4L+54L); /* IMAGE OFFSET */
writelong(40L); /* INFO SIZE */
writelong((long)xwide); /* dx */
writelong((long)ywide); /* dy */
writeshort(1); /* PLAIN */
if(c==256)writeshort(8); /* DEPTH */
else writeshort(4);
writelong(0L); /* COMPRESS TYPE */
writelong(0L);
writelong(0L); /* x per meter */
writelong(0L); /* y per meter */
writelong((long)c); /* COLOR */
writelong(0L);
for(i=0;i<c;i++){
k=(pal[i*2+1]<<8)|pal[i*2];
fputc((k&0x7c00)>>7,fo); /* BLUE */
fputc((k&0x3e0)>>2,fo); /* GREEN */
fputc((k&0x1f)<<3,fo); /* RED */
fputc(0,fo);
}
for(i=ywide-1;i>=0;i--){
fwrite(&bz[i*sx],1,sx,fo);
for(k=0;k<xpad;k++)fputc(0,fo);
}
fclose(fo);
}
void outbmp(char *fn,int no)
{
int x,y,xpad;
char fz[64],fs[4];
if(no>=0){
fs[0]=no/16+'0';if(fs[0]>57)fs[0]+=7;
fs[1]=(no&15)+'0';if(fs[1]>57)fs[1]+=7;
fs[2]=0;
}
else fs[0]=0;
strcpy(fz,current);strcat(fz,fn);strcat(fz,fs);strcat(fz,".BMP");
for(y=xwide*ywide*2-2,x=xwide*ywide*3-3;y>=0;y-=2,x-=3){
xpad=(bz[y]<<8)|bz[y+1];
bz[x+2]=(xpad&0x1F)<<3;
bz[x+1]=(xpad&0x3E0)>>2;
bz[x]=(xpad&0x7C00)>>7;
}
if((fo=fopen(fz,"wb"))==0){
printf("file create error![%s]\n",fz);exit(1);
}
xpad=(4-((xwide*3)&3))&3;
fputc('B',fo);fputc('M',fo); /* ID */
writelong(54L+(long)xwide*(long)ywide*3L+(long)xpad*(long)ywide); /* FILE
SIZE */
writelong(0L); /* RESERVED */
writelong(54L); /* IMAGE OFFSET */
writelong(40L); /* INFO SIZE */
writelong((long)xwide); /* dx */
writelong((long)ywide); /* dy */
writeshort(1); /* PLAIN */
writeshort(24); /* DEPTH */
writelong(0L); /* COMPRESS TYPE */
writelong(0L);
writelong(0L); /* x per meter */
writelong(0L); /* y per meter */
writelong(0L);
writelong(0L);
for(y=ywide-1;y>=0;y--){
fwrite(&bz[y*xwide*3],1,xwide*3,fo);
for(x=0;x<xpad;x++)fputc(0,fo);
}
fclose(fo);
}
/* WRITE SHORT VALUE */
void writeshort(short n)
{
fputc(n&255,fo);fputc((n>>8)&255,fo);
}
/* WRITE LONG VALUE */
void writelong(long n)
{
fputc((int)(n&255),fo);n/=256L;
fputc((int)(n&255),fo);n/=256L;
fputc((int)(n&255),fo);n/=256L;
fputc((int)(n&255),fo);
}
/* READ n BIT */
int loadbit(int sz,unsigned char *m,int *p)
{
int i,j;
for(i=j=0;i<sz;i++)j=(j<<1)|load1bit(m,p);
return(j);
}
/* READ 1 BIT */
int load1bit(unsigned char *m,int *p)
{
if(bitl==0){
bitl=8;bitcode=m[(*p)++];
}
bitl--;return((bitcode>>bitl)&1);
}