home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fun CD 26
/
OTACD26.ISO
/
archive
/
game
/
dqif
/
dqif.lzh
/
DQIF.C
next >
Wrap
C/C++ Source or Header
|
1997-07-08
|
8KB
|
323 lines
/******************************
* 同級生if BMP変換 *<<Saturn版>>
* Programmed By Melody-Yoshi *
******************************/
/* cc -mips2 -xansi -signed -fullwarn -prototypes dqif.c -o dqif */
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
unsigned char *bz,*mem,*tbl,pal[512],txt[4096];
FILE *fp,*fo;
int xwide,ywide,xseek,xpad,bitcode,bitl;
void writebmphead16(void),outpic(unsigned char *,int);
void conv16(int,int),reduce(unsigned char *,int);
void writelong(long),writeshort(short);
void wrtlen(int),bitwrite(int,int);
short getshort(unsigned char *,int);
int decode(void),getlong(unsigned char *,int);
void main(int argc,char *argv[])
{
char fn[64];
int tblcnt,i,j,m;
if(argc<2){
printf("dqif [file] [flag]\n flag:b0|b1|p0|p1\n");exit(1);
}
strcpy(fn,argv[1]);for(i=0;fn[i];i++)if(fn[i]=='.')break;
strcpy(&fn[i],".pac");
if((fp=fopen(fn,"rb"))==0){
printf("file open error![%s]\n",fn);exit(1);
}
if(argc>2){
if(argv[2][0]=='p' || argv[2][0]=='P')m=2;
if(argv[2][1]=='1')m|=1;
}
fseek(fp,28L,0);fread(txt,1,4,fp);tblcnt=getlong(txt,0);
tbl=(unsigned char *)malloc(tblcnt<<4);
mem=(unsigned char *)malloc(0x4D000);
bz=(unsigned char *)malloc(0x70000);
if(mem==NULL || tbl==NULL || bz==NULL){
printf("insufficient memory!\n");fclose(fp);exit(1);
}
fread(tbl,1,tblcnt<<4,fp);fclose(fp);
strcpy(&fn[i],".dat");
if((fp=fopen(fn,"rb"))==0){
printf("file open error![%s]\n",fn);exit(1);
}
for(i=0;i<tblcnt;i++){
for(j=0;;j++){
fn[j]=tbl[(i<<4)+j];if(fn[j]==0)break;
}
j=getlong(tbl,(i<<4)+8)<<11;fseek(fp,j,0);
j=getlong(tbl,(i<<4)+12);fread(mem,1,j,fp);
j=decode();
j=bz[16]*256+bz[17];xwide=640;ywide=(j&1)?224:160;
if(m&2)strcat(fn,".PIC");
else strcat(fn,".BMP");
if((fo=fopen(fn,"wb"))==0){
printf("file create error![%s]\n",fn);exit(1);
}
conv16(j,m);
fclose(fo);
}
free(mem);free(bz);free(tbl);fclose(fp);
exit(0);
}
int decode(void)
{
int i,j,k,m,p,q,r,cnt,dist,dl;
dl=getlong(mem,16);for(i=0;i<4096;i++)txt[i]=0;
for(p=j=0,q=0xFEE,r=20,k=0;p<dl;k>>=1){
if((k&0xFF00)==0){
k=(mem[r++]|0xFF00)^j;j=(j+1)&255;
}
if(k&1){
m=mem[r++];bz[p++]=txt[q]=m;q=(q+1)&0xFFF;
}
else{
m=mem[r]|(mem[r+1]<<8);r+=2;
cnt=((m&0x0F00)>>8)+3;dist=((m&0xF000)>>4)|(m&255);
for(m=0;m<cnt;m++){
bz[p++]=txt[q]=txt[dist];q=(q+1)&0xFFF;dist=(dist+1)&0xFFF;
}
}
}
return(p);
}
void reduce(unsigned char *b,int f)
{
int i,j,m,r1,r2,b1,b2,g1,g2;
unsigned k;
m=xwide*ywide*2;
if(f==24){
for(i=j=0;i<m;i+=4,j+=3){
k=(b[i]<<8)|(b[i+1]);
r1=(k&0x1F)<<3;g1=(k&0x3E0)>>2;b1=(k&0x7C00)>>7;
k=(b[i+2]<<8)|(b[i+3]);
r2=(k&0x1F)<<3;g2=(k&0x3E0)>>2;b2=(k&0x7C00)>>7;
b[j]=(b1+b2)/2;b[j+1]=(g1+g2)/2;b[j+2]=(r1+r2)/2;
}
}
else{
for(i=j=0;i<m;i+=4,j+=2){
k=(b[i]<<8)|(b[i+1]);
r1=(k&0x1F)<<3;g1=(k&0x3E0)>>2;b1=(k&0x7C00)>>7;
k=(b[i+2]<<8)|(b[i+3]);
r2=(k&0x1F)<<3;g2=(k&0x3E0)>>2;b2=(k&0x7C00)>>7;
r2=(((b1+b2)&0x1F0)<<6)|(((g1+g2)&0x1F0)<<1)|(((r1+r2)&0x1F0)>>4);
b[j+1]=r2&255;b[j]=(r2>>8);
}
}
xwide/=2;
}
void conv16(int mode,int sv)
{
int i,j,x,y,z;
if(sv&2){ /* PIC */
z=(mode>=0x400)?xwide*ywide+18:18;
if(sv&1)reduce(&bz[z],15);
outpic(&bz[z],15);
}
else{
z=(mode>=0x400)?xwide*ywide+18:18;
if(sv&1)reduce(&bz[z],24);
xseek=xwide*3;xpad=(4-(xseek&3))&3;xseek+=xpad;
writebmphead16();
if(sv&1){
for(y=ywide-1;y>=0;y--){
fwrite(&bz[y*xwide*3+z],1,xwide*3,fo);
for(x=0;x<xpad;x++)fputc(0,fo);
}
}
else{
for(y=ywide-1;y>=0;y--){
for(x=0,j=y*xwide*2+z;x<xwide;x++){
i=(bz[j+x*2]<<8)|(bz[j+x*2+1]);
mem[x*3]=(i&0x7C00)>>7;mem[x*3+1]=(i&0x3E0)>>2;
mem[x*3+2]=(i&0x1F)<<3;
}
fwrite(mem,1,xwide*3,fo);
for(x=0;x<xpad;x++)fputc(0,fo);
}
}
}
}
/* WRITE BMP HEADER */
void writebmphead16(void)
{
short i;
unsigned short k;
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);
}
/* PIC-FILE OUTPUT */
void outpic(unsigned char *b,int cbit)
{
int a,ad,c,d,i,p,x,y,xx,yy,r1,g1,b1;
struct{
int c,n,p;
}table[128];
if(cbit==8){
r1=xwide*ywide;
for(i=r1-1,p=r1+r1-2;i>=0;i--,p-=2){
c=b[i]<<1;b[p]=(c&256)>>8;b[p+1]=c&255;
}
}
else{
for(p=0;p<xwide*ywide*2;p+=2){
i=b[p+1]+(b[p]<<8);
r1=(i&0x1f)<<6;g1=(i&0x3E0)<<6;b1=(i&0x7C00)>>9;
i=g1|r1|b1;b[p]=i/256;b[p+1]=i&255;
}
}
bitl=bitcode=0;
for(i=0;i<128;i++){
table[i].c=0;table[i].p=i+1;table[i].n=i-1;
}
table[127].p=0;table[0].n=127;
fprintf(fo,"PIC/MM/XSS:"); /* HEADER */
fputc(26,fo);fputc(0,fo); /* TEXT EOF */
fputc(0,fo);fputc(0,fo); /* MODE */
fputc(0,fo);fputc(cbit,fo); /* COLOR LENGTH */
fputc(xwide/256,fo);fputc(xwide&255,fo); /* SIZE X */
fputc(ywide/256,fo);fputc(ywide&255,fo); /* SIZE Y */
if(cbit==8){
for(i=0;i<256;i++){
r1=pal[i<<1]|(pal[(i<<1)+1]<<8);
b1=(r1&0x7C00)>>7;g1=(r1&0x3E0)>>2;r1=(r1&0x1F)<<3;
r1=(g1<<8)|(r1<<3)|(b1>>2);
fputc(r1/256,fo);fputc(r1&255,fo);
}
}
for(p=y=c=0;y<xwide*ywide*2;y+=2){
if((i=((b[y]<<8)|(b[y+1]))&0xFFFE)!=c){
c=i;b[y]=c>>8;b[y+1]=(c&255)|1;
}
}
for(i=y=0;y<ywide;y++){
for(ad=y*xwide*2,x=0;x<xwide;x++,ad+=2){
i++;
if((c=(b[ad]<<8)|(b[ad+1]))&1){
wrtlen(i);
if(cbit==8)bitwrite(8,c>>1);
else{
for(a=0;a<128;a++)if(table[a].c==(c&0xFFFE))break;
if(a==128){
p=table[p].p;table[p].c=c&0xFFFE;
}
else{
if(p!=a){
table[table[a].p].n=table[a].n;
table[table[a].n].p=table[a].p;
table[table[p].p].n=a;table[a].p=table[p].p;
table[p].p=a;table[a].n=p;p=a;
}
}
if(a!=128)bitwrite(8,a+128);
else bitwrite(16,(unsigned)c/2);
}
for(a=0,xx=x,yy=y+1,r1=((y+1)*xwide+x)*2;yy<ywide;yy++,r1+=xwide*2){
if(c==((b[r1]<<8)|(b[r1+1])))d=2;
else{
xx--;r1-=2;
if(xx>=0 && c==((b[r1]<<8)|(b[r1+1])))d=1;
else{
xx+=2;r1+=4;
if(xx<xwide && c==((b[r1]<<8)|(b[r1+1])))d=3;
else{
xx-=3;r1-=6;
if(xx>=0 && c==((b[r1]<<8)|(b[r1+1])))d=4;
else{
xx+=4;r1+=8;
if(xx<xwide && c==((b[r1]<<8)|(b[r1+1])))d=5;
else break;
}
}
}
}
b[r1]=c>>8;b[r1+1]=c&0xFE;
if(a==0)bitwrite(1,1);
if(d==4)bitwrite(4,2);
if(d==5)bitwrite(4,3);
if(d<=3)bitwrite(2,d);
a=1;
}
if(a==0)bitwrite(1,0);
else bitwrite(3,0);
b[ad]=c>>8;b[ad+1]=c&0xFE;i=0;
}
}
}
wrtlen(i+1);bitwrite(8,0);bitwrite(31,0);
}
/* 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);
}
void wrtlen(int n)
{
int a,b;
a=1;b=4;
while(n>b-2){
a++;b<<=1;
}
bitwrite(a,0xfffffffe);bitwrite(a,(n+1-b/2));
}
void bitwrite(int sz,int n)
{
int i;
if(bitl+sz>32){
i=32-bitl;bitl+=sz-32;
bitcode=(bitcode<<i)|((n>>bitl)&((1<<i)-1));
fputc(bitcode>>24,fo);
fputc((bitcode>>16)&255,fo);
fputc((bitcode>>8)&255,fo);
fputc(bitcode&255,fo);
bitcode=n&((1<<bitl)-1);
}
else if(bitl+sz==32){
bitcode=(bitcode<<sz)|(n&((1<<sz)-1));bitl=0;
fputc(bitcode>>24,fo);
fputc((bitcode>>16)&255,fo);
fputc((bitcode>>8)&255,fo);
fputc(bitcode&255,fo);
}
else{
bitcode=(bitcode<<sz)|(n&((1<<sz)-1));bitl+=sz;
}
}
/* READ LONG VALUE */
int getlong(unsigned char *b,int p)
{
int i;
i=b[p]<<24;i|=b[p+1]<<16;i|=b[p+2]<<8;i|=b[p+3];return(i);
}
/* READ SHORT VALUE */
short getshort(unsigned char *b,int p)
{
short i;
i=b[p]<<8;i|=b[p+1];return(i);
}