00001
00014
00015
00016
00017
00018 #include "TiffTool.h"
00019
00020
00021 int TIFF_Swap_Flag = FALSE;
00022
00023
00032 TIFF_ifd** read_tiff_file(const char* fname)
00033 {
00034 TIFF_ifd** ptr_ifd = NULL;
00035 unsigned long int size;
00036 int i;
00037
00038 ptr_ifd = (TIFF_ifd**)malloc((MAX_IFD_DEM_NUM+1)*sizeof(TIFF_ifd*));
00039 if (ptr_ifd==NULL) return NULL;
00040 for (i=0; i<MAX_IFD_DEM_NUM+1; i++) ptr_ifd[i] = NULL;
00041
00042 unsigned char* buf = read_file(fname, &size);
00043 if (size<=0 || buf==NULL) {
00044 free(ptr_ifd);
00045 freeNull(buf);
00046 return NULL;
00047 }
00048
00049 int num = 0;
00050 do {
00051 ptr_ifd[num] = get_tiff_ifd(buf, num+1);
00052 if (ptr_ifd[num]==NULL) break;
00053 num++;
00054 } while(num<MAX_IFD_DEM_NUM && ptr_ifd[num-1]->value!=0);
00055
00056
00057
00058
00059
00060 for (i=0; i<num; i++) {
00061 proc_tiff_ifd(ptr_ifd[i], buf);
00062 }
00063
00064 freeNull(buf);
00065 return ptr_ifd;
00066 }
00067
00068
00083 TIFF_ifd* get_tiff_ifd(unsigned char* buf, int num)
00084 {
00085 TIFF_ifd* ifd = NULL;
00086 int i, k;
00087
00088
00089 if (buf[0]=='I' && buf[1]=='I') {
00090 if (is_big_endian()) TIFF_Swap_Flag = TRUE;
00091 }
00092 else if (buf[0]=='M' && buf[1]=='M') {
00093 if (is_little_endian()) TIFF_Swap_Flag = TRUE;
00094 }
00095 else {
00096 return NULL;
00097 }
00098
00099 unsigned char* ptr = buf + 2;
00100 short version = *((short*)ptr);
00101 if (TIFF_Swap_Flag) version = swaps(version);
00102 if (version!=42) {
00103 return NULL;
00104 }
00105
00106 ptr += 2;
00107 unsigned int offset = *((unsigned int*)ptr);
00108 if (TIFF_Swap_Flag) offset = swapl(offset);
00109
00110 if (num<0) num = 1;
00111 k = 0;
00112 while (k!=num && offset!=0) {
00113 k++;
00114 ptr = buf + offset;
00115 short nn = *((short*)ptr);
00116 if (TIFF_Swap_Flag) nn = swaps(nn);
00117 ptr += 2;
00118
00119 if (k==num) {
00120 ifd = (TIFF_ifd*)malloc(sizeof(TIFF_ifd)*(nn+1));
00121 if (ifd==NULL) {
00122 return NULL;
00123 }
00124
00125 memset(&ifd[0], 0, 12);
00126 ifd[0].type = num;
00127 ifd[0].count = nn;
00128
00129 for (i=1; i<=nn; i++) {
00130 if (k==num) {
00131 memcpy(&ifd[i], ptr, 12);
00132 if (TIFF_Swap_Flag) {
00133 ifd[i].tag = swaps(ifd[i].tag);
00134 ifd[i].type = swaps(ifd[i].type);
00135 ifd[i].count = swapl(ifd[i].count);
00136 ifd[i].value = swapl(ifd[i].value);
00137 }
00138 ifd[i].ex_value = NULL;
00139 }
00140 ptr += 12;
00141 }
00142 }
00143 else {
00144 for (i=0; i<nn; i++) ptr += 12;
00145 }
00146
00147 offset = *((unsigned int*)ptr);
00148 if (TIFF_Swap_Flag) offset = swapl(offset);
00149 }
00150
00151 if (ifd!=NULL) ifd[0].value = offset;
00152 return ifd;
00153 }
00154
00155
00156 void proc_tiff_ifd(TIFF_ifd* ptr, unsigned char* buf)
00157 {
00158 int i, j;
00159 int cnt = ptr->count;
00160 int width=0, height=0, depth=1, bdepth=1, comp=1, color=0;
00161 int tilew=0, tileh=0;
00162
00163 MSGraph vp;
00164 TIFF_ifd* ifd = ptr + 1;
00165 TIFF_ifd* strip_ifd = NULL;
00166
00167 memset(&vp, 0, sizeof(MSGraph));
00168
00169
00170 for (i=1; i<=cnt; i++) {
00171
00172 int offsize = get_tiff_type_length(ifd->type)*ifd->count;
00173 if (offsize>4) {
00174
00175 ifd->ex_value = (void*)malloc(offsize);
00176 memcpy(ifd->ex_value, buf + ifd->value, offsize);
00177 }
00178
00179
00180 switch(ifd->tag) {
00181
00182 case TIFF_TAG_WIDTH:
00183 width = get_tiff_uint_field(ifd, 0);
00184 break;
00185
00186 case TIFF_TAG_HEIGHT:
00187 height = get_tiff_uint_field(ifd, 0);
00188 break;
00189
00190 case TIFF_TAG_DEPTH:
00191 if (ifd->count==1) depth = ifd->value;
00192 else if (ifd->count>=2) {
00193 for (j=0, depth=0; j<(int)ifd->count; j++) {
00194 depth += get_tiff_uint_field(ifd, j);
00195 }
00196 }
00197 bdepth = (depth+7)/8;
00198 break;
00199
00200 case TIFF_TAG_COMP:
00201 comp = get_tiff_uint_field(ifd, 0);
00202 if (comp!=1) {
00203
00204 ptr->type = -1;
00205 }
00206 break;
00207
00208 case TIFF_TAG_COLOR:
00209 color = get_tiff_uint_field(ifd, 0);
00210 if (color==3) {
00211
00212 ptr->type = -1;
00213 }
00214 break;
00215
00216
00217
00218 case TIFF_TAG_STRIP:
00219 vp = make_MSGraph(width, height, 1, depth);
00220 if (vp.gp!=NULL) {
00221 if (ifd->count==1) {
00222 memcpy(vp.gp, buf+ifd->value, width*height*bdepth);
00223 }
00224 else {
00225 strip_ifd = ifd;
00226 }
00227 }
00228 else {
00229 ptr->type = -2;
00230 }
00231 break;
00232
00233 case TIFF_TAG_STRIP_CNT:
00234 if (ifd->count>1) {
00235 unsigned char* img = (unsigned char*)vp.gp;
00236 for (j=0; j<(int)ifd->count; j++) {
00237 int size = get_tiff_uint_field(ifd, j);
00238 int img_ptr = get_tiff_uint_field(strip_ifd, j);
00239 memcpy(img, buf+img_ptr, size);
00240 img += size;
00241 }
00242 }
00243 break;
00244
00245
00246 case TIFF_TAG_TILE_WIDTH:
00247 tilew = get_tiff_uint_field(ifd, 0);
00248 break;
00249
00250 case TIFF_TAG_TILE_HEIGHT:
00251 tileh = get_tiff_uint_field(ifd, 0);
00252 break;
00253
00254 case TIFF_TAG_TILE_OFFSET:
00255 if (tilew>0 && tileh>0) {
00256 int xnum = (width +tilew-1)/tilew;
00257 int ynum = (height+tileh-1)/tileh;
00258 if (vp.gp!=NULL) free_MSGraph(&vp);
00259
00260 vp = make_MSGraph(tilew*xnum, tileh*ynum, 1, depth);
00261 if (vp.gp!=NULL) {
00262 MSGraph mp = make_MSGraph(tilew, tileh, 1, depth);
00263 int size = tilew*tileh*bdepth;
00264
00265 for (j=0; j<(int)ifd->count; j++) {
00266 int img_ptr = get_tiff_uint_field(ifd, j);
00267 memcpy(mp.gp, buf+img_ptr, size);
00268
00269 int k, l, m;
00270 int ii = j%xnum;
00271 int jj = j/xnum;
00272 for (k=0; k<tileh; k++) {
00273 int kk = k*tilew;
00274 int yy = (jj*tileh + k)*vp.xs;
00275 for (l=0; l<tilew; l++) {
00276 int ll = (kk + l)*bdepth;
00277 int xx = (yy + ii*tilew + l)*bdepth;
00278 for (m=0; m<bdepth; m++) {
00279 vp.gp[xx+m] = mp.gp[ll+m];
00280 }
00281 }
00282 }
00283 }
00284 free_MSGraph(&mp);
00285 }
00286 else {
00287 ptr->type = -2;
00288 }
00289 }
00290 break;
00291
00292 case TIFF_TAG_TILE_BYTE:
00293 {
00294 int block = tilew*tileh*bdepth;
00295 for (j=0; j<(int)ifd->count; j++) {
00296 int size = get_tiff_uint_field(ifd, j);
00297 if (block!=size) {
00298 PRINT_MESG("PROC_TIFF_IFD: Not match Tile Size %d != %d\n", block, size);
00299 ptr->type = -1;
00300 }
00301 }
00302 }
00303 break;
00304 }
00305
00306 ifd++;
00307 }
00308
00309 if (ptr->type<0) {
00310 free_MSGraph(&vp);
00311 }
00312 else {
00313 if (vp.gp!=NULL) {
00314 ptr->ex_value = (void*)malloc(sizeof(MSGraph));
00315 memcpy(ptr->ex_value, &vp, sizeof(MSGraph));
00316 }
00317 }
00318 return;
00319 }
00320
00321
00322 void print_tiff_ifd(FILE* fp, TIFF_ifd* ifd, int max_values)
00323 {
00324 int i;
00325 if (max_values<0) max_values = 0;
00326
00327 if (ifd->tag==0) {
00328 int num = ifd->count;
00329 ifd++;
00330 for (i=1; i<=num; i++) {
00331 print_tiff_ifd_indiv(fp, ifd, max_values);
00332 ifd++;
00333 }
00334 }
00335 else {
00336 print_tiff_ifd_indiv(fp, ifd, max_values);
00337 }
00338
00339 }
00340
00341
00342 void print_tiff_ifd_indiv(FILE* fp, TIFF_ifd* ifd, int max_values)
00343 {
00344 int i;
00345 if (max_values<0) max_values = 0;
00346
00347 fprintf(fp, "%5d %2d %d -> ", ifd->tag, ifd->type, ifd->count);
00348
00349 if (ifd->ex_value!=NULL) {
00350 int count = Min((int)ifd->count, max_values);
00351
00352 if (ifd->type==TIFF_TYPE_ASCII) {
00353 fprintf(fp, " %s", get_tiff_ascii_field(ifd, 0));
00354 }
00355 else if (ifd->type==TIFF_TYPE_SOHRT || ifd->type==TIFF_TYPE_SSHORT) {
00356 for (i=0; i<count; i++) fprintf(fp, " %d", get_tiff_uint_field(ifd, i));
00357 }
00358 else if (ifd->type==TIFF_TYPE_LONG || ifd->type==TIFF_TYPE_SLONG) {
00359 for (i=0; i<count; i++) fprintf(fp, " %d", get_tiff_uint_field(ifd, i));
00360 }
00361 else if (ifd->type==TIFF_TYPE_RATIONAL || ifd->type==TIFF_TYPE_SRATIONAL) {
00362 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));
00363 }
00364 else if (ifd->type==TIFF_TYPE_FLOAT || ifd->type==TIFF_TYPE_DOUBLE) {
00365 for (i=0; i<count; i++) fprintf(fp, " %f", get_tiff_double_field(ifd, i));
00366 }
00367 else if (count>0) fprintf(fp, " PRINT_TIFF_IFD_INDIV: not supported IFD type => %d", ifd->type);
00368
00369 if (ifd->type!=TIFF_TYPE_ASCII && count<(int)ifd->count && count!=0) fprintf(fp, " .......");
00370 }
00371 else fprintf(fp, " %d", ifd->value);
00372
00373 fprintf(fp, "\n");
00374 fflush(fp);
00375 }
00376
00377
00378 void free_TIFF_ifd(TIFF_ifd* ifd)
00379 {
00380 if (ifd==NULL) return;
00381 freeNull(ifd->ex_value);
00382 free(ifd);
00383 }
00384
00385
00386 void free_TIFF_ifd_dem(TIFF_ifd** ptr_ifd)
00387 {
00388 if (ptr_ifd==NULL) return;
00389
00390 TIFF_ifd** ptr = ptr_ifd;
00391 while ((*ptr)!=NULL) {
00392 if ((*ptr)->tag==0) {
00393 if ((*ptr)->ex_value!=NULL) {
00394 free_MSGraph((MSGraph*)(*ptr)->ex_value);
00395 }
00396 }
00397
00398 free_TIFF_ifd(*ptr);
00399 ptr++;
00400 }
00401
00402 free(ptr_ifd);
00403 }
00404
00405
00406 char* get_tiff_ascii_field(TIFF_ifd* ifd, int offset)
00407 {
00408 if (ifd==NULL) return NULL;
00409 if (ifd->type!=TIFF_TYPE_ASCII) return NULL;
00410 if (offset<0) offset = 0;
00411
00412 int len = get_tiff_type_length(ifd->type);
00413 unsigned char* ptr = NULL;
00414
00415 if (len*ifd->count>4 && ifd->ex_value!=NULL) ptr = (unsigned char*)(ifd->ex_value);
00416 else ptr = (unsigned char*)&(ifd->value);
00417
00418 return (char*)(ptr + offset);
00419 }
00420
00421
00422 unsigned int get_tiff_uint_field(TIFF_ifd* ifd, int offset)
00423 {
00424 if (ifd==NULL) return 0;
00425 if (ifd->type!=TIFF_TYPE_SOHRT && ifd->type!=TIFF_TYPE_SSHORT &&
00426 ifd->type!=TIFF_TYPE_LONG && ifd->type!=TIFF_TYPE_SLONG &&
00427 ifd->type!=TIFF_TYPE_RATIONAL && ifd->type!=TIFF_TYPE_SRATIONAL) return 0;
00428 if (offset<0) offset = 0;
00429
00430 unsigned int ret = 0;
00431 int len = get_tiff_type_length(ifd->type);
00432 unsigned char* ptr = NULL;
00433
00434 if (len*ifd->count>4 && ifd->ex_value!=NULL) ptr = (unsigned char*)(ifd->ex_value);
00435 else ptr = (unsigned char*)&(ifd->value);
00436
00437 if (ifd->type==TIFF_TYPE_RATIONAL || ifd->type==TIFF_TYPE_SRATIONAL) len /= 2;
00438
00439 if (len==2) {
00440 if (TIFF_Swap_Flag) ret = swaps(*(unsigned short*)(ptr + offset*2));
00441 else ret = *(unsigned short*)(ptr + offset*2);
00442 }
00443 else if (len==4) {
00444 if (TIFF_Swap_Flag) ret = swapl(*(unsigned int*)(ptr + offset*4));
00445 else ret = *(unsigned int*)(ptr + offset*4);
00446 }
00447
00448 return ret;
00449 }
00450
00451
00452 double get_tiff_double_field(TIFF_ifd* ifd, int offset)
00453 {
00454 if (ifd==NULL) return 0.0;
00455 if (ifd->type!=TIFF_TYPE_FLOAT && ifd->type!=TIFF_TYPE_DOUBLE) return 0.0;
00456 if (offset<0) offset = 0;
00457
00458 double ret = 0.0;
00459 int len = get_tiff_type_length(ifd->type);
00460 unsigned char* ptr = NULL;
00461
00462 if (len*ifd->count>4 && ifd->ex_value!=NULL) ptr = (unsigned char*)(ifd->ex_value);
00463 else ptr = (unsigned char*)&(ifd->value);
00464
00465 if (len==4) {
00466 ret = *(float*)(ptr + offset*4);
00467 }
00468 else if (len==8) {
00469 ret = *(double*)(ptr + offset*8);
00470 }
00471
00472 return ret;
00473 }
00474
00475
00476 int get_tiff_type_length(short type)
00477 {
00478 int byte_num[] = {0, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8};
00479
00480 if (type>0 && type<13) return byte_num[type];
00481 return 0;
00482 }
00483
00484
00485 TIFF_ifd* find_tiff_ifd(TIFF_ifd* ifd, unsigned short tag)
00486 {
00487 if (ifd==NULL && tag<=0) return NULL;
00488
00489 int i;
00490 int count = ifd->count;
00491
00492 if (ifd->tag!=0) {
00493 if (ifd->tag==tag) return ifd;
00494 else return NULL;
00495 }
00496
00497 ifd++;
00498 for (i=0; i<count; i++) {
00499 if (ifd->tag==tag) return ifd;
00500 ifd++;
00501 }
00502 return NULL;
00503 }
00504
00505