JunkBox_Lib  1.10.2
tiff_tool.c
Go to the documentation of this file.
1 
9 #include "tiff_tool.h"
10 
11 
13 
14 
23 TIFF_ifd** read_tiff_file(const char* fname)
24 {
25  TIFF_ifd** ptr_ifd = NULL;
26  unsigned long int size;
27  int i;
28 
29  ptr_ifd = (TIFF_ifd**)malloc((MAX_IFD_DEM_NUM+1)*sizeof(TIFF_ifd*));
30  if (ptr_ifd==NULL) return NULL;
31  for (i=0; i<MAX_IFD_DEM_NUM+1; i++) ptr_ifd[i] = NULL;
32 
33  unsigned char* buf = read_file(fname, &size);
34  if (size<=0 || buf==NULL) {
35  free(ptr_ifd);
36  freeNull(buf);
37  return NULL;
38  }
39 
40  int num = 0;
41  do {
42  ptr_ifd[num] = get_tiff_ifd(buf, num+1);
43  if (ptr_ifd[num]==NULL) break;
44  num++;
45  } while(num<MAX_IFD_DEM_NUM && ptr_ifd[num-1]->value!=0);
46 
47  //if (num==MAX_IFD_DEM_NUM && ptr_ifd[num-1]->value!=0) {
48  // PRINT_MESG("READ_TIFF_FILE: included image file number is over %d!!\n", MAX_IFD_DEM_NUM);
49  //}
50 
51  for (i=0; i<num; i++) {
52  proc_tiff_ifd(ptr_ifd[i], buf);
53  }
54 
55  freeNull(buf);
56  return ptr_ifd;
57 }
58 
59 
74 TIFF_ifd* get_tiff_ifd(unsigned char* buf, int num)
75 {
76  TIFF_ifd* ifd = NULL;
77  int i, k;
78 
79  // Endian
80  if (buf[0]=='I' && buf[1]=='I') {
82  }
83  else if (buf[0]=='M' && buf[1]=='M') {
85  }
86  else {
87  return NULL;
88  }
89 
90  unsigned char* ptr = buf + 2;
91  short version = *((short*)ptr);
92  if (TIFF_Swap_Flag) version = swaps(version);
93  if (version!=42) {
94  return NULL;
95  }
96 
97  ptr += 2;
98  unsigned int offset = *((unsigned int*)ptr);
99  if (TIFF_Swap_Flag) offset = swapl(offset);
100 
101  if (num<0) num = 1;
102  k = 0;
103  while (k!=num && offset!=0) {
104  k++;
105  ptr = buf + offset;
106  short nn = *((short*)ptr);
107  if (TIFF_Swap_Flag) nn = swaps(nn);
108  ptr += 2;
109 
110  if (k==num) {
111  ifd = (TIFF_ifd*)malloc(sizeof(TIFF_ifd)*(nn+1));
112  if (ifd==NULL) {
113  return NULL;
114  }
115  memset(ifd, 0, sizeof(TIFF_ifd)*(nn+1));
116  //
117  memset(&ifd[0], 0, 12);
118  ifd[0].type = num;
119  ifd[0].count = nn;
120 
121  for (i=1; i<=nn; i++) {
122  if (k==num) {
123  memcpy(&ifd[i], ptr, 12);
124  if (TIFF_Swap_Flag) {
125  ifd[i].tag = swaps(ifd[i].tag);
126  ifd[i].type = swaps(ifd[i].type);
127  ifd[i].count = swapl(ifd[i].count);
128  ifd[i].value = swapl(ifd[i].value);
129  }
130  ifd[i].ex_value = NULL;
131  }
132  ptr += 12;
133  }
134  }
135  else {
136  for (i=0; i<nn; i++) ptr += 12;
137  }
138 
139  offset = *((unsigned int*)ptr);
140  if (TIFF_Swap_Flag) offset = swapl(offset);
141  }
142 
143  if (ifd!=NULL) ifd[0].value = offset;
144  return ifd;
145 }
146 
147 
148 void proc_tiff_ifd(TIFF_ifd* ptr, unsigned char* buf)
149 {
150  int i, j;
151  int cnt = ptr->count;
152  int width=0, height=0, depth=1, bdepth=1, comp=1, color=0;
153  int tilew=0, tileh=0;
154 
155  MSGraph vp;
156  TIFF_ifd* ifd = ptr + 1;
157  TIFF_ifd* strip_ifd = NULL;
158 
159  memset(&vp, 0, sizeof(MSGraph));
160 
161  for (i=1; i<=cnt; i++) {
162 
163  int offsize = get_tiff_type_length(ifd->type)*ifd->count;
164  if (offsize>4) {
165  //PRINT_MESG("Malloc Ex_Value. Tag = %d, Length = %d\n", ifd->tag, offsize);
166  ifd->ex_value = (void*)malloc(offsize);
167  memcpy(ifd->ex_value, buf + ifd->value, offsize);
168  }
169 
170  // Tag
171  switch(ifd->tag) {
172 
173  case TIFF_TAG_WIDTH:
174  width = get_tiff_uint_field(ifd, 0);
175  break;
176 
177  case TIFF_TAG_HEIGHT:
178  height = get_tiff_uint_field(ifd, 0);
179  break;
180 
181  case TIFF_TAG_DEPTH:
182  if (ifd->count==1) depth = ifd->value;
183  else if (ifd->count>=2) {
184  for (j=0, depth=0; j<(int)ifd->count; j++) {
185  depth += get_tiff_uint_field(ifd, j);
186  }
187  }
188  bdepth = (depth+7)/8;
189  break;
190 
191  case TIFF_TAG_COMP:
192  comp = get_tiff_uint_field(ifd, 0);
193  if (comp!=1) {
194  //PRINT_MESG("PROC_TIFF_IFD: In this version, I can not processes compressed TIFF imgae!!\n");
195  ptr->type = -1;
196  }
197  break;
198 
199  case TIFF_TAG_COLOR:
200  color = get_tiff_uint_field(ifd, 0);
201  if (color==3) {
202  //PRINT_MESG("PROC_TIFF_IFD: In this version, I can not processes Color Map!!\n");
203  ptr->type = -1;
204  }
205  break;
206 
207  // STRIP
208  case TIFF_TAG_STRIP:
209  vp = make_MSGraph(width, height, 1, depth);
210  if (vp.gp!=NULL) {
211  if (ifd->count==1) {
212  memcpy(vp.gp, buf+ifd->value, width*height*bdepth);
213  }
214  else {
215  strip_ifd = ifd;
216  }
217  }
218  else {
219  ptr->type = -2;
220  }
221  break;
222 
223  case TIFF_TAG_STRIP_CNT:
224  if (ifd->count>1) {
225  unsigned char* img = (unsigned char*)vp.gp;
226  for (j=0; j<(int)ifd->count; j++) {
227  int size = get_tiff_uint_field(ifd, j);
228  int img_ptr = get_tiff_uint_field(strip_ifd, j);
229  memcpy(img, buf+img_ptr, size);
230  img += size;
231  }
232  }
233  break;
234 
235  // TILE
236  case TIFF_TAG_TILE_WIDTH:
237  tilew = get_tiff_uint_field(ifd, 0);
238  break;
239 
241  tileh = get_tiff_uint_field(ifd, 0);
242  break;
243 
245  if (tilew>0 && tileh>0) {
246  int xnum = (width +tilew-1)/tilew;
247  int ynum = (height+tileh-1)/tileh;
248  if (vp.gp!=NULL) free_MSGraph(&vp);
249 
250  vp = make_MSGraph(tilew*xnum, tileh*ynum, 1, depth);
251  if (vp.gp!=NULL) {
252  MSGraph mp = make_MSGraph(tilew, tileh, 1, depth);
253  int size = tilew*tileh*bdepth;
254 
255  for (j=0; j<(int)ifd->count; j++) { // Block
256  int img_ptr = get_tiff_uint_field(ifd, j);
257  memcpy(mp.gp, buf+img_ptr, size);
258 
259  int k, l, m;
260  int ii = j%xnum;
261  int jj = j/xnum;
262  for (k=0; k<tileh; k++) {
263  int kk = k*tilew;
264  int yy = (jj*tileh + k)*vp.xs;
265  for (l=0; l<tilew; l++) {
266  int ll = (kk + l)*bdepth;
267  int xx = (yy + ii*tilew + l)*bdepth;
268  for (m=0; m<bdepth; m++) {
269  vp.gp[xx+m] = mp.gp[ll+m];
270  }
271  }
272  }
273  }
274  free_MSGraph(&mp);
275  }
276  else {
277  ptr->type = -2;
278  }
279  }
280  break;
281 
282  case TIFF_TAG_TILE_BYTE:
283  {
284  int block = tilew*tileh*bdepth;
285  for (j=0; j<(int)ifd->count; j++) {
286  int size = get_tiff_uint_field(ifd, j);
287  if (block!=size) {
288  PRINT_MESG("PROC_TIFF_IFD: Not match Tile Size %d != %d\n", block, size);
289  ptr->type = -1;
290  }
291  }
292  }
293  break;
294  }
295  ifd++;
296  }
297 
298  if (ptr->type<0) {
299  free_MSGraph(&vp);
300  }
301  else {
302  if (vp.gp!=NULL) {
303  ptr->ex_value = (void*)malloc(sizeof(MSGraph));
304  memcpy(ptr->ex_value, &vp, sizeof(MSGraph));
305  }
306  }
307  return;
308 }
309 
310 
311 void print_tiff_ifd(FILE* fp, TIFF_ifd* ifd, int max_values)
312 {
313  int i;
314  if (max_values<0) max_values = 0;
315 
316  if (ifd->tag==0) {
317  int num = ifd->count;
318  ifd++;
319  for (i=1; i<=num; i++) {
320  print_tiff_ifd_indiv(fp, ifd, max_values);
321  ifd++;
322  }
323  }
324  else {
325  print_tiff_ifd_indiv(fp, ifd, max_values);
326  }
327 
328 }
329 
330 
331 void print_tiff_ifd_indiv(FILE* fp, TIFF_ifd* ifd, int max_values)
332 {
333  int i;
334  if (max_values<0) max_values = 0;
335 
336  fprintf(fp, "%5d %2d %d -> ", ifd->tag, ifd->type, ifd->count);
337 
338  if (ifd->ex_value!=NULL) {
339  int count = Min((int)ifd->count, max_values);
340 
341  if (ifd->type==TIFF_TYPE_ASCII) {
342  fprintf(fp, " %s", get_tiff_ascii_field(ifd, 0));
343  }
344  else if (ifd->type==TIFF_TYPE_SOHRT || ifd->type==TIFF_TYPE_SSHORT) {
345  for (i=0; i<count; i++) fprintf(fp, " %d", get_tiff_uint_field(ifd, i));
346  }
347  else if (ifd->type==TIFF_TYPE_LONG || ifd->type==TIFF_TYPE_SLONG) {
348  for (i=0; i<count; i++) fprintf(fp, " %d", get_tiff_uint_field(ifd, i));
349  }
350  else if (ifd->type==TIFF_TYPE_RATIONAL || ifd->type==TIFF_TYPE_SRATIONAL) {
351  for (i=0; i<count; i++) fprintf(fp, " %d/%d", get_tiff_uint_field(ifd, 2*i), get_tiff_uint_field(ifd, 2*i+1));
352  }
353  else if (ifd->type==TIFF_TYPE_FLOAT || ifd->type==TIFF_TYPE_DOUBLE) {
354  for (i=0; i<count; i++) fprintf(fp, " %f", get_tiff_double_field(ifd, i));
355  }
356  else if (count>0) fprintf(fp, " PRINT_TIFF_IFD_INDIV: not supported IFD type => %d", ifd->type);
357 
358  if (ifd->type!=TIFF_TYPE_ASCII && count<(int)ifd->count && count!=0) fprintf(fp, " .......");
359  }
360  else fprintf(fp, " %d", ifd->value);
361 
362  fprintf(fp, "\n");
363  fflush(fp);
364 }
365 
366 
368 {
369  if (ifd==NULL) return;
370  freeNull(ifd->ex_value);
371  free(ifd);
372 }
373 
374 
376 {
377  if (ptr_ifd==NULL) return;
378 
379  TIFF_ifd** ptr = ptr_ifd;
380  while ((*ptr)!=NULL) {
381  if ((*ptr)->tag==0) {
382  if ((*ptr)->ex_value!=NULL) {
383  free_MSGraph((MSGraph*)(*ptr)->ex_value);
384  }
385  }
386 
387  free_TIFF_ifd(*ptr);
388  ptr++;
389  }
390 
391  free(ptr_ifd);
392 }
393 
394 
395 char* get_tiff_ascii_field(TIFF_ifd* ifd, int offset)
396 {
397  if (ifd==NULL) return NULL;
398  if (ifd->type!=TIFF_TYPE_ASCII) return NULL;
399  if (offset<0) offset = 0;
400 
401  int len = get_tiff_type_length(ifd->type);
402  unsigned char* ptr = NULL;
403 
404  if (len*ifd->count>4 && ifd->ex_value!=NULL) ptr = (unsigned char*)(ifd->ex_value);
405  else ptr = (unsigned char*)&(ifd->value);
406 
407  return (char*)(ptr + offset);
408 }
409 
410 
411 unsigned int get_tiff_uint_field(TIFF_ifd* ifd, int offset)
412 {
413  if (ifd==NULL) return 0;
414  if (ifd->type!=TIFF_TYPE_SOHRT && ifd->type!=TIFF_TYPE_SSHORT &&
415  ifd->type!=TIFF_TYPE_LONG && ifd->type!=TIFF_TYPE_SLONG &&
416  ifd->type!=TIFF_TYPE_RATIONAL && ifd->type!=TIFF_TYPE_SRATIONAL) return 0;
417  if (offset<0) offset = 0;
418 
419  unsigned int ret = 0;
420  int len = get_tiff_type_length(ifd->type);
421  unsigned char* ptr = NULL;
422 
423  if (len*ifd->count>4 && ifd->ex_value!=NULL) ptr = (unsigned char*)(ifd->ex_value);
424  else ptr = (unsigned char*)&(ifd->value);
425 
426  if (ifd->type==TIFF_TYPE_RATIONAL || ifd->type==TIFF_TYPE_SRATIONAL) len /= 2;
427 
428  if (len==2) {
429  if (TIFF_Swap_Flag) ret = swaps(*(unsigned short*)(ptr + offset*2));
430  else ret = *(unsigned short*)(ptr + offset*2);
431  }
432  else if (len==4) {
433  if (TIFF_Swap_Flag) ret = swapl(*(unsigned int*)(ptr + offset*4));
434  else ret = *(unsigned int*)(ptr + offset*4);
435  }
436 
437  return ret;
438 }
439 
440 
441 double get_tiff_double_field(TIFF_ifd* ifd, int offset)
442 {
443  if (ifd==NULL) return 0.0;
444  if (ifd->type!=TIFF_TYPE_FLOAT && ifd->type!=TIFF_TYPE_DOUBLE) return 0.0;
445  if (offset<0) offset = 0;
446 
447  double ret = 0.0;
448  int len = get_tiff_type_length(ifd->type);
449  unsigned char* ptr = NULL;
450 
451  if (len*ifd->count>4 && ifd->ex_value!=NULL) ptr = (unsigned char*)(ifd->ex_value);
452  else ptr = (unsigned char*)&(ifd->value);
453 
454  if (len==4) {
455  ret = *(float*)(ptr + offset*4);
456  }
457  else if (len==8) {
458  ret = *(double*)(ptr + offset*8);
459  }
460 
461  return ret;
462 }
463 
464 
465 int get_tiff_type_length(short type)
466 {
467  int byte_num[] = {0, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8};
468 
469  if (type>0 && type<13) return byte_num[type];
470  return 0;
471 }
472 
473 
474 TIFF_ifd* find_tiff_ifd(TIFF_ifd* ifd, unsigned short tag)
475 {
476  if (ifd==NULL && tag<=0) return NULL;
477 
478  int i;
479  int count = ifd->count;
480 
481  if (ifd->tag!=0) {
482  if (ifd->tag==tag) return ifd;
483  else return NULL;
484  }
485 
486  ifd++;
487  for (i=0; i<count; i++) {
488  if (ifd->tag==tag) return ifd;
489  ifd++;
490  }
491  return NULL;
492 }
493 
#define Min(x, y)
Definition: common.h:250
#define TRUE
Definition: common.h:226
#define FALSE
Definition: common.h:223
MSGraph make_MSGraph(int xs, int ys, int zs, int depth)
Definition: gdata.c:277
#define free_MSGraph(v)
Definition: gdata.h:181
unsigned char ** buf
Definition: jpeg_tool.h:96
unsigned char unsigned long * len
Definition: jpeg_tool.h:96
Definition: gdata.h:98
int xs
xサイズ. 4Byte.
Definition: gdata.h:99
unsigned char * gp
グラフィックデータへのポインタ. xs*ys*zs*depth.
Definition: gdata.h:104
uDWord value
Definition: tiff_tool.h:20
uWord tag
Definition: tiff_tool.h:17
sWord type
Definition: tiff_tool.h:18
uDWord count
Definition: tiff_tool.h:19
void * ex_value
Definition: tiff_tool.h:21
TIFF_ifd * get_tiff_ifd(unsigned char *buf, int num)
Definition: tiff_tool.c:74
int TIFF_Swap_Flag
Definition: tiff_tool.c:12
char * get_tiff_ascii_field(TIFF_ifd *ifd, int offset)
Definition: tiff_tool.c:395
unsigned int get_tiff_uint_field(TIFF_ifd *ifd, int offset)
Definition: tiff_tool.c:411
void print_tiff_ifd_indiv(FILE *fp, TIFF_ifd *ifd, int max_values)
Definition: tiff_tool.c:331
TIFF_ifd ** read_tiff_file(const char *fname)
Definition: tiff_tool.c:23
void free_TIFF_ifd_dem(TIFF_ifd **ptr_ifd)
Definition: tiff_tool.c:375
void proc_tiff_ifd(TIFF_ifd *ptr, unsigned char *buf)
Definition: tiff_tool.c:148
void free_TIFF_ifd(TIFF_ifd *ifd)
Definition: tiff_tool.c:367
void print_tiff_ifd(FILE *fp, TIFF_ifd *ifd, int max_values)
Definition: tiff_tool.c:311
TIFF_ifd * find_tiff_ifd(TIFF_ifd *ifd, unsigned short tag)
Definition: tiff_tool.c:474
int get_tiff_type_length(short type)
Definition: tiff_tool.c:465
double get_tiff_double_field(TIFF_ifd *ifd, int offset)
Definition: tiff_tool.c:441
TIFF TOOL HEADER.
#define TIFF_TYPE_DOUBLE
Definition: tiff_tool.h:48
#define TIFF_TAG_WIDTH
Definition: tiff_tool.h:50
#define TIFF_TAG_TILE_BYTE
Definition: tiff_tool.h:70
#define TIFF_TYPE_LONG
Definition: tiff_tool.h:40
#define TIFF_TAG_STRIP_CNT
Definition: tiff_tool.h:57
#define TIFF_TYPE_FLOAT
Definition: tiff_tool.h:47
#define TIFF_TAG_COLOR
Definition: tiff_tool.h:54
#define MAX_IFD_DEM_NUM
Definition: tiff_tool.h:35
#define TIFF_TYPE_RATIONAL
Definition: tiff_tool.h:41
#define TIFF_TAG_STRIP
Definition: tiff_tool.h:55
#define TIFF_TYPE_SRATIONAL
Definition: tiff_tool.h:46
#define TIFF_TAG_HEIGHT
Definition: tiff_tool.h:51
#define TIFF_TAG_COMP
Definition: tiff_tool.h:53
#define TIFF_TYPE_SOHRT
Definition: tiff_tool.h:39
#define TIFF_TAG_DEPTH
Definition: tiff_tool.h:52
#define TIFF_TYPE_SLONG
Definition: tiff_tool.h:45
#define TIFF_TAG_TILE_HEIGHT
Definition: tiff_tool.h:68
#define TIFF_TAG_TILE_WIDTH
Definition: tiff_tool.h:67
#define TIFF_TYPE_ASCII
Definition: tiff_tool.h:38
#define TIFF_TYPE_SSHORT
Definition: tiff_tool.h:44
#define TIFF_TAG_TILE_OFFSET
Definition: tiff_tool.h:69
unsigned char * read_file(const char *fname, long unsigned int *size)
ファイルからデータを読み込む
Definition: tools.c:2460
short swaps(unsigned short p)
16bit の上下8bitを入れ替える.
Definition: tools.c:1872
int is_big_endian(void)
エンディアンの動的チェック
Definition: tools.c:114
int is_little_endian(void)
エンディアンの動的チェック
Definition: tools.c:80
int swapl(unsigned int p)
32bit pを8bitづつ逆順にする
Definition: tools.c:1896
#define freeNull(p)
Definition: tools.h:201
#define PRINT_MESG
環境依存用の出力関数.print_message()
Definition: tools.h:475