|
Lines 342-347
Link Here
|
| 342 |
} |
342 |
} |
| 343 |
|
343 |
|
| 344 |
|
344 |
|
|
|
345 |
static unsigned long read_tiff_long(FILE *in,int little_endian) |
| 346 |
{ |
| 347 |
unsigned long ret; |
| 348 |
|
| 349 |
if(little_endian) |
| 350 |
{ |
| 351 |
ret=fgetc(in); |
| 352 |
ret|=(fgetc(in)<<8); |
| 353 |
ret|=(fgetc(in)<<16); |
| 354 |
ret|=(fgetc(in)<<24); |
| 355 |
} |
| 356 |
else |
| 357 |
{ |
| 358 |
ret=(fgetc(in)<<24); |
| 359 |
ret|=(fgetc(in)<<16); |
| 360 |
ret|=(fgetc(in)<<8); |
| 361 |
ret|=fgetc(in); |
| 362 |
} |
| 363 |
|
| 364 |
return(ret); |
| 365 |
} |
| 366 |
|
| 367 |
|
| 368 |
static unsigned int read_tiff_short(FILE *in,int little_endian) |
| 369 |
{ |
| 370 |
unsigned int ret; |
| 371 |
|
| 372 |
if(little_endian) |
| 373 |
{ |
| 374 |
ret=fgetc(in); |
| 375 |
ret|=(fgetc(in)<<8); |
| 376 |
} |
| 377 |
else |
| 378 |
{ |
| 379 |
ret=(fgetc(in)<<8); |
| 380 |
ret|=fgetc(in); |
| 381 |
} |
| 382 |
|
| 383 |
return(ret); |
| 384 |
} |
| 385 |
|
| 386 |
|
| 387 |
int get_exif_orientation(char *filename) |
| 388 |
{ |
| 389 |
static int xzgv_orient_lookup[]={0,1,3,2,7,4,6,5}; |
| 390 |
FILE *in; |
| 391 |
unsigned char buf[4]; |
| 392 |
long ifd0_ofs; |
| 393 |
int little_endian,f,num_ents; |
| 394 |
int exif_orient; |
| 395 |
|
| 396 |
if((in=fopen(filename,"rb"))==NULL) |
| 397 |
return(0); |
| 398 |
|
| 399 |
fread(buf,1,4,in); |
| 400 |
if(memcmp(buf,"\xff\xd8\xff\xe1",4)!=0) |
| 401 |
{ |
| 402 |
fclose(in); |
| 403 |
return(0); |
| 404 |
} |
| 405 |
|
| 406 |
/* we can ignore data size */ |
| 407 |
fgetc(in); |
| 408 |
fgetc(in); |
| 409 |
|
| 410 |
fread(buf,1,4,in); |
| 411 |
if(memcmp(buf,"Exif",4)!=0 || fgetc(in) || fgetc(in)) |
| 412 |
{ |
| 413 |
fclose(in); |
| 414 |
return(0); |
| 415 |
} |
| 416 |
|
| 417 |
/* now at tiff header */ |
| 418 |
fread(buf,1,4,in); |
| 419 |
if(memcmp(buf,"II*\0",4)!=0 && memcmp(buf,"MM\0*",4)!=0) |
| 420 |
{ |
| 421 |
fclose(in); |
| 422 |
return(0); |
| 423 |
} |
| 424 |
|
| 425 |
little_endian=(memcmp(buf,"II*\0",4)==0); |
| 426 |
|
| 427 |
/* orientation is an IFD0 tag, so read IFD0 offset and seek */ |
| 428 |
ifd0_ofs=12+read_tiff_long(in,little_endian); |
| 429 |
fseek(in,ifd0_ofs,SEEK_SET); |
| 430 |
|
| 431 |
/* search IFD0 for Orientation (0x112) */ |
| 432 |
exif_orient=-1; |
| 433 |
num_ents=read_tiff_short(in,little_endian); |
| 434 |
for(f=0;f<num_ents;f++) |
| 435 |
{ |
| 436 |
fseek(in,ifd0_ofs+2+12*f,SEEK_SET); |
| 437 |
if(read_tiff_short(in,little_endian)==0x112 && |
| 438 |
read_tiff_short(in,little_endian)==3 && |
| 439 |
read_tiff_long(in,little_endian)==1) |
| 440 |
{ |
| 441 |
exif_orient=read_tiff_short(in,little_endian); |
| 442 |
break; |
| 443 |
} |
| 444 |
} |
| 445 |
|
| 446 |
fclose(in); |
| 447 |
|
| 448 |
if(exif_orient<1 || exif_orient>8) |
| 449 |
return(0); |
| 450 |
|
| 451 |
/* return, converting Exif orientation to xzgv format */ |
| 452 |
|
| 453 |
return(xzgv_orient_lookup[exif_orient-1]); |
| 454 |
} |
| 455 |
|
| 456 |
|
| 345 |
/* small wrapper function for backend_create_image_from_file() which |
457 |
/* small wrapper function for backend_create_image_from_file() which |
| 346 |
* deals with mrf files and other oddities (currently GIF/PNG). |
458 |
* deals with mrf files and other oddities (currently GIF/PNG). |
| 347 |
* |
459 |
* |
|
Lines 359-364
Link Here
|
| 359 |
jpeg_exif_orient=0; |
471 |
jpeg_exif_orient=0; |
| 360 |
|
472 |
|
| 361 |
ret=backend_create_image_from_file(file); /* use backend's loader */ |
473 |
ret=backend_create_image_from_file(file); /* use backend's loader */ |
|
|
474 |
|
| 475 |
if(use_exif_orient) |
| 476 |
jpeg_exif_orient=get_exif_orientation(file); |
| 477 |
|
| 362 |
origw=0; origh=0; |
478 |
origw=0; origh=0; |
| 363 |
if(ret) |
479 |
if(ret) |
| 364 |
{ |
480 |
{ |