add ati tiff to bmp conv tool
[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
133  puts("");
134  puts("ati framegrabber tiff to bmp converter.");
135  puts("");
136  puts("no compressed files!");
137  puts("no 'big' or 'special' files! ;)");
138  puts("");
139
140  memset(&pi,0,sizeof(t_pic_info));
141
142  fd=open(argv[1],O_RDONLY);
143  tfd=open(argv[2],O_WRONLY|O_CREAT);
144
145  if((fd<0) || (tfd<0)) {
146   puts("error opening files ...");
147   return -1;
148  }
149
150  lseek(fd,0,SEEK_SET);
151  size=lseek(fd,0,SEEK_END);
152  lseek(fd,0,SEEK_SET);
153
154  lseek(fd,4,SEEK_SET);
155  read(fd,tbuf,4);
156  word2int(offset,tbuf);
157
158  printf("offset: %04x (%d)\n",offset,offset);
159
160  /* we only need first table! */
161  parse_table(fd,offset,&pi);
162
163  printf("\n");
164  printf("let's see what we have:\n");
165  puts("");
166  printf("we have %d strips, the offsets are:\n",pi.soc);
167  printf("1st: %04x, 2nd: %04x, ... last: %04x\n",pi.so[0],pi.so[1],pi.so[pi.soc-1]);
168  printf("their lenght in bytes is:\n");
169  printf("1st: %d ... last: %d\n",pi.sb[0],pi.sb[pi.sbc-1]);
170
171  printf("checking ...\n");
172  printf("we have %d pixels, each has %d bytes => %d bytes\n",pi.width*pi.height,pi.bps*pi.bits[0]/8,pi.width*pi.height*pi.bps*pi.bits[0]/8);
173  for(i=0;i<pi.sbc;i++) tmp+=pi.sb[i];
174  printf("the tiff provides %d bytes! ok? :)\n",tmp);
175
176  buf=(unsigned char *)malloc(size);
177
178  if(buf==NULL) {
179   puts("error allocating memory ...");
180   return -1;
181  }
182
183  puts("");
184  printf("writing bmp file %s...",argv[2]);
185
186  foo=3*pi.width;
187  bmps=(foo+(4-foo%4))*pi.height;
188
189  memset(bbuf,0,sizeof(bbuf));
190  bbuf[0]='B'; bbuf[1]='M';
191  bbuf[2]=(bmps+0x36)&0xff;
192  bbuf[3]=(bmps+0x36)>>8;
193  bbuf[10]=0x36;
194  bbuf[14]=0x28;
195  bbuf[18]=pi.width&0xff;
196  bbuf[19]=pi.width>>8;
197  bbuf[22]=pi.height&0xff;
198  bbuf[23]=pi.height>>8;
199  bbuf[26]=1;
200  bbuf[28]=24;
201  bbuf[34]=bmps&0xff;
202  bbuf[35]=bmps>>8;
203  bbuf[38]=0x12;
204  bbuf[39]=0x0b;
205  bbuf[42]=bbuf[38];
206  bbuf[43]=bbuf[39];
207  
208  write(tfd,bbuf,54);
209  for(k=0;k<pi.height;k++) {
210   for(l=0;l<pi.width;l++) {
211    /* read rgb value (16bit) */
212    lseek(fd,pi.so[k/pi.rps]+2*l+2*(k%pi.rps)*pi.width,SEEK_SET);
213    read(fd,tbuf,pi.bits[0]/8);
214    short2int(bla,tbuf);
215    // bla=(tbuf[0]<<8)|tbuf[1];
216    bbuf[0]=(bla>>10)<<3;
217    bbuf[1]=((bla>>5)&31)<<3;
218    bbuf[2]=(bla&31)<<3;
219    write(tfd,bbuf,3);
220   }
221   if(foo%4) {
222    memset(bbuf,0,4-foo%4);
223    write(tfd,bbuf,4-foo%4);
224   }
225  }
226
227  printf("done!\n");
228  printf("now go and kill ati!!!1\n");
229
230  close(fd);
231  close(tfd);
232  free(buf);
233
234  return 1;
235 }