care for corrupted data, improved client termination behaviour
[physik/nlsop.git] / conv_fg_tif.c
1 /*
2  * ati framegrabber tif to bmp converter ;)
3  *
4  * achtung: totaler muell code, der hoffentlich seinen zweck erfuellt
5  *          fuer die netten tiff 16bit rgb bilder vom tem(?).
6  */
7
8 #include <stdio.h>
9 #include <sys/types.h>
10 #include <sys/stat.h>
11 #include <fcntl.h>
12 #include <unistd.h>
13 #include <stdlib.h>
14 #include <string.h>
15
16 typedef struct s_pic_info {
17  int width;
18  int height;
19  int bps;
20  short bits[3]; /* max 3 values */
21  int rps; /* rows per strip */
22  int soc; /* strip offset counts */
23  int sbc; /* strip byte counts */
24  int *so; /* pointer to strip offsets */
25  int *sb; /* pointer to the byte counts per strip */
26 } t_pic_info;
27
28 static inline void _short2int(short *dst, unsigned char *buf) {
29         *dst=(buf[1]<<8)|buf[0];        
30 }
31
32 static inline void _word2int(int *dst, unsigned char *buf) {
33         *dst=(buf[3]<<24)|(buf[2]<<16)|(buf[1]<<8)|buf[0];
34 }
35 #define short2int(a,b) _short2int(&a,b)
36 #define word2int(a,b) _word2int(&a,b)
37
38 int parse_table(int fd,int offset,t_pic_info *pi) {
39  int i;
40  short de;
41  unsigned char buf[12]; /* 12 byte directory entry */
42
43  lseek(fd,offset,SEEK_SET);
44  read(fd,buf,2);
45  short2int(de,buf);
46
47  printf("parsing %d tags\n",de);
48
49  for(i=0;i<de;i++) {
50   unsigned char *obuf;
51   short tag;
52   short type;
53   int count;
54   int vo;
55   int j;
56
57   lseek(fd,offset+2+i*12,SEEK_SET);
58   read(fd,buf,12);
59   short2int(tag,buf);
60   short2int(type,buf+2);
61   word2int(count,buf+4);
62   word2int(vo,buf+8);
63
64   switch(tag) {
65    case 256:
66     pi->width=vo;
67     printf("width: %d\n",vo);
68     break;
69    case 257:
70     pi->height=vo;
71     printf("height: %d\n",vo);
72     break;
73    case 258:
74     pi->bps=count;
75     if(count!=1) {
76      printf("warning, only converting 16 bit rgb files!");
77      obuf=(unsigned char *)malloc(count*2);
78      lseek(fd,vo,SEEK_SET);
79      read(fd,obuf,2*count);
80      for(j=0;j<count;j++) short2int(pi->bits[j],obuf+2*j);
81      free(obuf);
82     }
83     else pi->bits[0]=vo;
84     printf("bits per sample: %d %d %d\n",pi->bits[0],pi->bits[1],pi->bits[2]);
85     break;
86    case 259:
87     if(vo!=1) puts("warning, compressed file - i am going to do bullshit!");
88     break;
89    case 262:
90     if(vo!=2) puts("warning, no rgb file - i am going to do bullshit!");
91     break;
92    case 273:
93     pi->soc=count;
94     printf("%d strip offsets\n",count);
95     obuf=(unsigned char *)malloc(count*4);
96     pi->so=(int *)malloc(count*4);
97     lseek(fd,vo,SEEK_SET);
98     read(fd,obuf,count*4);
99     for(j=0;j<count;j++) word2int(pi->so[j],obuf+4*j);
100     free(obuf);
101     break;
102    case 278:
103     pi->rps=vo;
104     printf("rows per strip: %d\n",vo);
105     break;
106    case 279:
107     pi->sbc=count;
108     printf("strip bytes: %d\n",count);
109     obuf=(unsigned char *)malloc(count*4);
110     pi->sb=(int *)malloc(count*4);
111     lseek(fd,vo,SEEK_SET);
112     read(fd,obuf,count*4);
113     for(j=0;j<count;j++) word2int(pi->sb[j],obuf+4*j);
114     free(obuf);
115     break;
116   }
117  }
118
119  return 1;
120 }
121
122 int main(int argc,char **argv) {
123  int tfd,fd,i,tmp=0;
124  int offset,size;
125  unsigned char *buf;
126  unsigned char tbuf[4];
127  t_pic_info pi;
128  /* for bmp */
129  int foo,k,l,bmps;
130  unsigned char bbuf[128];
131  short bla;
132  int m;
133
134  puts("");
135  puts("ati framegrabber tiff to bmp converter.");
136  puts("");
137  puts("no compressed files!");
138  puts("no 'big' or 'special' files! ;)");
139  puts("");
140
141  memset(&pi,0,sizeof(t_pic_info));
142
143  fd=open(argv[1],O_RDONLY);
144  tfd=open(argv[2],O_WRONLY|O_CREAT);
145
146  if((fd<0) || (tfd<0)) {
147   puts("error opening files ...");
148   return -1;
149  }
150
151  lseek(fd,0,SEEK_SET);
152  size=lseek(fd,0,SEEK_END);
153  lseek(fd,0,SEEK_SET);
154
155  lseek(fd,4,SEEK_SET);
156  read(fd,tbuf,4);
157  word2int(offset,tbuf);
158
159  printf("offset: %04x (%d)\n",offset,offset);
160
161  /* we only need first table! */
162  parse_table(fd,offset,&pi);
163
164  printf("\n");
165  printf("let's see what we have:\n");
166  puts("");
167  printf("we have %d strips, the offsets are:\n",pi.soc);
168  printf("1st: %04x, 2nd: %04x, ... last: %04x\n",
169         pi.so[0],pi.so[1],pi.so[pi.soc-1]);
170  printf("their lenght in bytes is:\n");
171  printf("1st: %d ... last: %d\n",pi.sb[0],pi.sb[pi.sbc-1]);
172
173  printf("checking ...\n");
174  printf("we have %d pixels, each has %d bytes => %d bytes\n",
175         pi.width*pi.height,pi.bps*pi.bits[0]/8,
176         pi.width*pi.height*pi.bps*pi.bits[0]/8);
177  for(i=0;i<pi.sbc;i++) tmp+=pi.sb[i];
178  printf("the tiff provides %d bytes! ok? :)\n",tmp);
179
180  puts("");
181  printf("writing bmp file %s...",argv[2]);
182
183  foo=3*pi.width;
184  bmps=(foo+(4-foo%4))*pi.height;
185
186  memset(bbuf,0,sizeof(bbuf));
187  bbuf[0]='B'; bbuf[1]='M';
188  bbuf[2]=(bmps+0x36)&0xff;
189  bbuf[3]=(bmps+0x36)>>8;
190  bbuf[10]=0x36;
191  bbuf[14]=0x28;
192  bbuf[18]=pi.width&0xff;
193  bbuf[19]=pi.width>>8;
194  bbuf[22]=pi.height&0xff;
195  bbuf[23]=pi.height>>8;
196  bbuf[26]=1;
197  bbuf[28]=24;
198  bbuf[34]=bmps&0xff;
199  bbuf[35]=bmps>>8;
200  bbuf[38]=0x12;
201  bbuf[39]=0x0b;
202  bbuf[42]=bbuf[38];
203  bbuf[43]=bbuf[39];
204  
205  write(tfd,bbuf,54);
206
207  buf=(unsigned char *)malloc(pi.width*pi.height*pi.bits[0]/8);
208  m=0;
209  for(k=0;k<pi.sbc;k++) {
210   lseek(fd,pi.so[k],SEEK_SET);
211   read(fd,buf+m,pi.sb[k]);
212   m+=pi.sb[k];
213  }
214
215  for(k=0;k<pi.height;k++) {
216   for(l=0;l<pi.width;l++) {
217    short2int(bla,buf+2*(pi.width*(pi.height-k-1)+l));
218    bbuf[0]=((bla>>10)&31)<<3; /* blau */
219    bbuf[1]=((bla>>5)&31)<<3; /* gelb */
220    bbuf[2]=(bla&31)<<3; /* rot */
221    write(tfd,bbuf,3);
222   }
223   if(foo%4) {
224    memset(bbuf,0,4-foo%4);
225    write(tfd,bbuf,4-foo%4);  
226   }
227  }
228
229  printf("done!\n");
230  printf("now go and kill ati!!!1\n");
231
232  close(fd);
233  close(tfd);
234  free(buf);
235
236  return 1;
237 }