/*authur xuntan
this sample program shows how to decode a ssreader image file
based on xuntans reverse engineer work.
gif writing function is not included
*/
#include <stdio.h>
#include <math.h>
#include "gif.h"
typedef struct {
int width;
int height;
unsigned char * data;
}
myimg,*pmyimg;
int huffman1();
int huffman2();
int getnextbit();
void myimagedestory(pmyimg p);
pmyimg readmyimagehead(char * fname);
void decodemyimage(pmyimg img);
void scalemyimage(pmyimg,int neww);
void writegiffile(pmyimg image);
void cropmyimage(pmyimg image);
void error(char *);
/* global variable*/
file * fimg;
unsigned int bdata;
int len=16;
int buf1[1024];
int buf2[1024];
int offset;
int main(int argc,char *argv[]){
file * out;
int color[16];
int i,j;
pmyimg image;
char * p,q;
char * query;
char fname[64];
char buf [64];
char buf2[16];
if(argc<2) {
printf("usage: gifconv filename\n");
exit(0);
}
image=readmyimagehead(argv[1]);
decodemyimage(image);
writegiffile(image);
myimagedestory(image);
}
void error(char * msg){
printf("%s\n",msg);
exit(0);
}
void writegiffile(pmyimg image){
gifstream *stream;
gifdata *cur;
gif89info info;
int i,j;
stream=(gifstream *)malloc(sizeof(gifstream));
if(!stream)
error("error in malloc gif data\n");
stream->width =image->width;
stream->height=image->height;
stream->cmapsize=16;
stream->colormapsize =16;
stream->colorresolution =4;
stream->background =0;
stream->aspectratio= 0;
stream->data =null;
stream->cmapdata[0][0]=255;
stream->cmapdata[0][1]=255;
stream->cmapdata[0][2]=255;
for(i=1;i<16;i++){
stream->cmapdata[i][0]=256-i*16;
stream->cmapdata[i][1]=256-i*16;
stream->cmapdata[i][2]=256-i*16;
}
info.disposal = 0;
info.inputflag = 0;
info.delaytime = 0;
info.transparent = -1;
cur=(gifdata *)malloc(sizeof(gifdata));
cur->type =gif_image;
cur->info =info;
cur->x =0;
cur->y =0;
cur->width=image->width;
cur->height=image->height;
cur->data.image.cmapsize= 0;
cur->data.image.data=image->data;
cur->next=null;
stream->data=cur;
gifwrite("test.gif",stream,1);
}
void cropmyimage(pmyimg image){
int i,j;
int min,max;
char * p,*q;
min=image->width;
max=0;
for(i=150;i<image->height-150;i++){
p=image->data+i*image->width;
for(j=0;j<image->width;j++){
if (*p!=0) break;
p++;
}
if(j<min) min=j;
p=image->data+(i+1)*image->width-1;
for(j=image->width;j>0;j–){
if (*p!=0) break;
p–;
}
if(j>max)
max=j;
}
p=image->data;
for(i=0;i<image->height;i++){
q=image->data+i*image->width;
for(j=min-5;j<max+5;j++){
*p=q[j];
p++;
}
}
image->width=max-min+10;
}
void scalemyimage(pmyimg image,int neww){
int newh;
int i,j;
int sx,sy,ex,ey;
unsigned char *newd,*p;
unsigned char *l1,*l2;
int sum,c,s,t;
newh=image->height*neww/image->width;
newd=(unsigned char *)malloc(newh*neww);
if(!newd)
error("memory allocation error in scaleimage\n");
p=newd;
sy=0;
for(i=0;i<newh;i++){
ey=(i+1)*image->height/newh;
sx=0;
l1=image->data+sy*image->width;
for(j=0;j<neww;j++){
ex=(j+1)*image->width/neww;
sum=0;
c=0;
l2=l1;
for(s=sy;s<ey;s++){
for(t=sx;t<ex;t++){
sum+=l2[t];
c++;
}
l2+=image->width;
}
*p=sum/c;
p++;
sx=ex;
}
sy=ey;
}
image->height=newh;
image->width=neww;
free(image->data);
image->data=newd;
}
pmyimg readmyimagehead(char * fname){
pmyimg image;
int i,j;
unsigned char head[0x38];
image=(pmyimg)malloc(sizeof(myimg));
if(!image){
printf("memory error \n");
exit(0);
}
fimg=fopen(fname,"rb");
if(!fimg){
printf("file open error \n");
exit(0);
}
/*fseek(fimg,3,0)*/;
fread(head,1,0×38,fimg);
image->width=head[3]+head[4]*0x100;
image->height=head[5]+head[6]*0x100;
image->data=(unsigned char *)malloc(image->width*image->height);
if(!image->data){
error("memory allocation error.\n");
}
return image;
}
int getnextbit(){
if(len>=8){
len=0;
offset=ftell(fimg);
bdata=fgetc(fimg);
/*{
printf("error in decoding,file is shorter than expected\n");
exit(0);
} */
}
if((bdata & 0x80) ==0){
len++;
bdata=bdata<<1;
return 0;
}
else{
len++;
bdata=bdata<<1;
return 1;
}
}
void decodemyimage(pmyimg image){
int * curcode,*precode;
int sflag,preflag;
int i,j;
int preindex,curindex;
int width=image->width;
int height=image->height;
int h,w;
int c1,c2;
char * imgline;
curcode=buf1;
precode=buf2;
precode[0]=0;
precode[1]=width;
precode[2]=width;
precode[3]=width;
preindex=0;
curindex=0;
h=w=0;
imgline=image->data;
while(h<height){
preindex=0;
curindex=0;
sflag=1;
preflag=0;
w=0;
while(w<width){
if(getnextbit()){
curcode[curindex]=precode[preindex];
curindex+=1;
preindex+=1;
sflag=!sflag;
preflag=0;
}
else
if(getnextbit()){
if(getnextbit()){
curcode[curindex]=precode[preindex]+1;
}
else{
curcode[curindex]=precode[preindex]-1;
}
preindex++;
curindex++;
sflag=!sflag;
preflag=0;
}
else{
if(getnextbit()){
if(sflag){
c1=readhuffman2();
c2=readhuffman1();
}
else{
c1=readhuffman1();
c2=readhuffman2();
}
if(preflag)
c1=precode[preindex-1]+c1;
else
c1=curcode[curindex-1]+c1;
curcode[curindex]=c1;
c2=c1+c2;
curcode[curindex+1]=c2;
curindex+=2;
while(c2>=precode[preindex])
preindex+=2;
preflag=0;
}
else{
if(getnextbit()){
preindex+=2;
preflag=1;
}
else{
if(getnextbit()){
if(getnextbit()){
curcode[curindex]=precode[preindex]+2;
}
else{
curcode[curindex]=precode[preindex]-2;
}
preindex++;
curindex++;
sflag=!sflag;
preflag=0;
}
else{
if(getnextbit()){
if(getnextbit()){
curcode[curindex]=precode[preindex]+3;
}
else{
curcode[curindex]=precode[preindex]-3;
}
preindex++;
curindex++;
sflag=!sflag;
preflag=0;
}
else{
error("error in decode operator %d\n");
}
}
}
}
}
w=curcode[curindex-1];
}
for(i=0;i<curindex-1;i++){
sflag=(i%2)*15;
for(j=curcode[i];j<curcode[i+1]-1;j++)
imgline[j]=sflag;
}
imgline+=width;
h++;
curcode[curindex]=width;
curcode[curindex+1]=width;
{
int * temp;
temp=precode;
precode=curcode;
curcode=temp;
}
}
}
