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