/* scans first IDF and returns the n-th tag */ uint32 TIFFGetRawTagListEntry( TIFF * tif, int tagidx ) { int count = TIFFGetRawTagListCount( tif); int fd = TIFFFileno( tif); //printf("count %i\n", count); /* read count of tags (2 Bytes) */ int i; /* replace i/o operatrions with in-memory-operations */ uint8 * ifdentries = NULL; ifdentries = malloc ( sizeof(uint8) * 12 * count); if (read(fd, ifdentries, 12 * count) != 12*count) { perror ("TIFF Header read error3"); exit(EXIT_FAILURE); } uint8 * e = ifdentries; for (i = 0; i<count; i++) { uint8 lo = *e; e++; uint8 hi = *e; uint16 tagid = (hi << 8) + lo; e++; if (TIFFIsByteSwapped(tif)) TIFFSwabShort(&tagid); if (i == tagidx) { // printf("tag idx=%i, tag=%u (0x%04x) (0x%02x) (0x%02x)\n", i, tagid, tagid, hi, lo); free( ifdentries ); return tagid; } e+=10; } /* loop each tag until end or given tag found */ free( ifdentries ); return 0; }
/* scans first IDF and returns count of tags * Hint: sideeffect, if succeed the seek points to beginning of the first * IFD-entry */ int TIFFGetRawTagListCount (TIFF * tif) { int fd = TIFFFileno( tif); /* seek the image file directory (bytes 4-7) */ uint32 offset = get_first_IFD( fd ); // printf("diroffset to %i (0x%04lx)\n", offset, offset); //printf("byte swapped? %s\n", (TIFFIsByteSwapped(tif)?"true":"false")); /* read and seek to IFD address */ lseek(fd, (off_t) offset, SEEK_SET); uint16 count; if (read(fd, &count, 2) != 2) { perror ("TIFF Header read error2"); exit(EXIT_FAILURE); } if (TIFFIsByteSwapped(tif)) TIFFSwabShort(&count); return count; }
ret_t check_tagorder(TIFF* tif) { printf("check if tags are in ascending order\n"); int count = TIFFGetRawTagListCount( tif); int fd = TIFFFileno( tif); //printf("count %i\n", count); /* read count of tags (2 Bytes) */ int i; /* replace i/o operatrions with in-memory-operations */ uint8 * ifdentries = NULL; ifdentries = malloc ( sizeof(uint8) * 12 * count); if (read(fd, ifdentries, 12 * count) != 12*count) { perror ("TIFF Header read error5"); exit(EXIT_FAILURE); } uint8 * e = ifdentries; uint16 lasttag = 0; for (i = 0; i<count; i++) { uint8 lo = *e; e++; uint8 hi = *e; uint16 tag = (hi << 8) + lo; e++; if (TIFFIsByteSwapped(tif)) TIFFSwabShort(&tag); if (i>0 && lasttag >= tag) { // printf("tag idx=%i, tag=%u (0x%04x) (0x%02x) (0x%02x)\n", i, tag, tag, hi, lo); free( ifdentries ); tif_fails("Invalid TIFF directory; tags are not sorted in ascending order, previous tag:%u (%s) , actual tag:%u (%s)\n", lasttag, TIFFTagName(tif, lasttag), tag, TIFFTagName(tif, tag)); } lasttag = tag; e+=10; } /* loop each tag until end or given tag found */ free( ifdentries ); ret_t res; res.returnmsg=NULL; res.returncode=0; return res; }
main(int argc, char** argv) { char* cp; int npages, ok; struct stat sb; TIFF* tif; float vres, w, h; long pageWidth, pageLength; char sender[80]; char date[80]; struct pageSizeInfo* info; if (argc != 2) { fprintf(stderr, "usage: %s file.tif\n", argv[0]); exit(-1); } printf("%s:\n", argv[1]); TIFFSetErrorHandler(NULL); TIFFSetWarningHandler(NULL); tif = TIFFOpen(argv[1], "r"); if (tif == NULL) { printf("Could not open (%s).\n", strerror(errno)); exit(0); } ok = isFAXImage(tif); if (!ok) { printf("Does not look like a facsimile?\n"); exit(0); } if (TIFFGetField(tif, TIFFTAG_IMAGEDESCRIPTION, &cp)) sanitize(sender, cp, sizeof (sender)); else strcpy(sender, "<unknown>"); printf("%11s %s\n", "Sender:", sender); TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &pageWidth); TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &pageLength); if (TIFFGetField(tif, TIFFTAG_YRESOLUTION, &vres)) { short resunit = RESUNIT_NONE; TIFFGetField(tif, TIFFTAG_RESOLUTIONUNIT, &resunit); if (resunit == RESUNIT_CENTIMETER) vres *= 25.4; } else vres = 98; npages = 0; do { npages++; } while (TIFFReadDirectory(tif)); printf("%11s %u\n", "Pages:", npages); if (vres == 98) printf("%11s Normal\n", "Quality:"); else if (vres == 196) printf("%11s Fine\n", "Quality:"); else printf("%11s %.2f lines/inch\n", "Quality:", vres); h = pageLength / (vres < 100 ? 3.85 : 7.7); w = (pageWidth / 204.) * 25.4; info = closestPageSize(w, h); if (info) printf("%11s %s\n", "Page:", getPageName(info)); else printf("%11s %lu by %lu\n", "Page:", pageWidth, pageLength); delPageSize(info); if (!TIFFGetField(tif, TIFFTAG_DATETIME, &cp)) { struct stat sb; fstat(TIFFFileno(tif), &sb); strftime(date, sizeof (date), "%Y:%m:%d %H:%M:%S %Z", localtime(&sb.st_mtime)); } else sanitize(date, cp, sizeof (date)); printf("%11s %s\n", "Received:", date); exit(0); }
/* scans first IDF and returns the type of the n-th tag */ ifd_entry_t TIFFGetRawTagIFDListEntry( TIFF * tif, int tagidx ) { int count = TIFFGetRawTagListCount( tif); #ifdef DEBUG printf(" count of tags = %i\n", count); #endif int fd = TIFFFileno( tif); //printf("count %i\n", count); /* read count of tags (2 Bytes) */ int i; ifd_entry_t ifd_entry; /* replace i/o operatrions with in-memory-operations */ uint8 * ifdentries = NULL; ifdentries = malloc ( sizeof(uint8) * 12 * count); if (read(fd, ifdentries, 12 * count) != 12*count) { perror ("TIFF Header read error4"); exit(EXIT_FAILURE); } uint8 * e = ifdentries; for (i = 0; i<count; i++) { uint8 lo = *e; e++; uint8 hi = *e; uint16 tagid = (hi << 8) + lo; e++; if (TIFFIsByteSwapped(tif)) TIFFSwabShort(&tagid); if (i == tagidx) { // tag type check lo = *e; e++; hi = *e; e++; uint16 tagtype = (hi << 8) + lo; if (TIFFIsByteSwapped(tif)) TIFFSwabShort(&tagtype); uint32 count = (*(e++)); count += (*(e++) << 8); count += (*(e++) << 16); count += (*(e++) << 24); if (TIFFIsByteSwapped(tif)) TIFFSwabLong( &count); #ifdef DEBUG printf("\ncount=%0x\n\n", count); #endif /* is value or offset? */ /* TODO */ ifd_entry.count=count; ifd_entry.datatype=tagtype; uint8 data[4]; data[0] = *(e++); data[1] = *(e++); data[2] = *(e++); data[3] = *(e++); uint32 value_or_offset = (data[0]); value_or_offset += (data[1] << 8); value_or_offset += (data[2] << 16); value_or_offset += (data[3] << 24); if (TIFFIsByteSwapped(tif)) TIFFSwabLong( &value_or_offset); switch( tagtype) { case 1: /* 8-bit unsigned integer */ case 2: /* 8-bit bytes w/ last byte null */ case 6: /* !8-bit signed integer */ case 7: /* !8-bit untyped data */ if (count > 4) { /* offset */ ifd_entry.value_or_offset=is_offset; ifd_entry.data32offset=value_or_offset; } else { /* values */ ifd_entry.value_or_offset=is_value; ifd_entry.data8[0] = data[0]; ifd_entry.data8[1] = data[1]; ifd_entry.data8[2] = data[2]; ifd_entry.data8[3] = data[3]; #ifdef DEBUG printf("data8[0]=%u\n", data[0]); printf("data8[1]=%u\n", data[1]); printf("data8[2]=%u\n", data[2]); printf("data8[3]=%u\n", data[3]); #endif }; break; case 3: /* 16-bit unsigned integer */ case 8: /* !16-bit signed integer */ if (count > 2) { /* offset */ ifd_entry.value_or_offset=is_offset; ifd_entry.data32offset=value_or_offset; } else { /* values */ ifd_entry.value_or_offset=is_value; uint16 w0 = (data[0]) + (data[1]<<8); uint16 w1 = (data[2]) + (data[3]<<8); if (TIFFIsByteSwapped(tif)) { TIFFSwabShort( &w0 ); TIFFSwabShort( &w1 ); } ifd_entry.data16[0] = w0; ifd_entry.data16[1] = w1; #ifdef DEBUG printf("data16[0]=%u\n", w0); printf("data16[1]=%u\n", w1); #endif }; break; case 4: /* 32-bit unsigned integer */ case 9: /* !32-bit signed integer */ if (count > 1) { /* offset */ ifd_entry.value_or_offset=is_offset; ifd_entry.data32offset=value_or_offset; } else { /* values */ ifd_entry.value_or_offset=is_value; ifd_entry.data32=value_or_offset; #ifdef DEBUG printf("data32[0]=%u\n", value_or_offset); #endif }; break; case 5: /* 64-bit unsigned fraction */ case 10: /* !64-bit signed fraction */ case 11: /* !32-bit IEEE floating point */ case 12: /* !64-bit IEEE floating point */ case 13: /* %32-bit unsigned integer (offset) */ case 16: /* BigTIFF 64-bit unsigned integer */ case 17: /* BigTIFF 64-bit signed integer */ case 18: /* BigTIFF 64-bit unsigned integer (offset) */ ifd_entry.value_or_offset=is_offset; ifd_entry.data32offset=value_or_offset; } free( ifdentries ); #ifdef DEBUG printf("tag idx=%i, tag=%u (0x%04x) tagtype=0x%04x is_offset=%s count=%d value_or_offset=0x%08x\n", i, tagid, tagid, tagtype, (ifd_entry.value_or_offset==is_offset ? "true" : "false"), count, value_or_offset); #endif return ifd_entry; } e+=10; } /* loop each tag until end or given tag found */ free( ifdentries ); return ifd_entry; }
/* get count-data datastream from offset-address */ offset_t read_offsetdata( TIFF * tif, uint32 address, uint16 count, uint16 datatype) { int fd = TIFFFileno( tif); /* read and seek to IFD address */ lseek(fd, (off_t) address, SEEK_SET); offset_t offset; offset.count = count; offset.datatype = datatype; switch (datatype) { case 1: /* 8-bit unsigned integer */ case 7: /* !8-bit untyped data */ /* offset.data8p = NULL; offset.data8p = malloc ( sizeof(uint8) * count); if (read(fd, offset.data8p, sizeof(uint8) * count) != sizeof(uint8) *count) perror ("TIFF Offset read error"); */ offset_malloc(fd, offset.data8p, uint8, count) break; case 2: /* 8-bit bytes w/ last byte null */ assert( sizeof(char) == sizeof(uint8)); offset_malloc(fd, offset.datacharp, char, count) break; case 6: /* !8-bit signed integer */ offset_malloc(fd, offset.datas8p, int8, count) break; case 3: /* 16-bit unsigned integer */ offset_malloc(fd, offset.data16p, uint16, count) break; case 8: /* !16-bit signed integer */ offset_malloc(fd, offset.datas16p, int16, count) break; case 4: /* 32-bit unsigned integer */ case 13: /* %32-bit unsigned integer (offset) */ offset_malloc(fd, offset.data32p, uint32, count) break; case 9: /* !32-bit signed integer */ offset_malloc(fd, offset.datas32p, uint32, count) break; case 5: /* 64-bit unsigned fraction */ fprintf(stderr, "offsetdata datatype=%i not supported yet", datatype); exit(EXIT_FAILURE); case 10: /* !64-bit signed fraction */ fprintf(stderr, "offsetdata datatype=%i not supported yet", datatype); exit(EXIT_FAILURE); case 11: /* !32-bit IEEE floating point */ assert( sizeof(float) == 4); offset_malloc(fd, offset.datafloatp, float, count) break; case 12: /* !64-bit IEEE floating point */ assert( sizeof(double) == 8); offset_malloc(fd, offset.datadoublep, double, count) break; case 16: /* BigTIFF 64-bit unsigned integer */ case 18: /* BigTIFF 64-bit unsigned integer (offset) */ assert( sizeof(double) == 8); offset_malloc(fd, offset.data64p, uint64, count) break; case 17: /* BigTIFF 64-bit signed integer */ assert( sizeof(double) == 8); offset_malloc(fd, offset.datas64p, int64, count) break; default: /* should not occure */ fprintf(stderr, "offsetdata datatype=%i not supported yet", datatype); exit(EXIT_FAILURE); }; return offset; }
int vglPrintTiffInfo(char* inFilename, char* msg){ if (msg){ printf("====== %s:\n", msg); } else { printf("====== vglPrintTiffInfo:\n"); } TIFF* tif = TIFFOpen(inFilename, "r"); if (tif == NULL){ fprintf(stderr, "%s:%s: Error: File %s not found.\n", __FILE__, __FUNCTION__, inFilename); return 1; } if (tif) { uint32 w, h; uint16 bps, spp, photo, config, pageNumber, numberPages; uint32 subfileType; tdir_t dirCount; tstrip_t stripMax; tstrip_t istrip; tsize_t stripSize; tsize_t npixels; tsize_t pixelSize; tdata_t raster; tsize_t result, offset; char* rasterc; uint32 iw, ih; int i; do{ TIFFPrintDirectory(tif, stdout, 255); } while(TIFFReadDirectory(tif)); printf("TIFFScanlineSize = %ld\n", (long int) TIFFScanlineSize(tif)); printf("TIFFRasterScanlineSize = %ld\n", (long int) TIFFRasterScanlineSize(tif)); printf("TIFFStripSize = %ld\n", (long int) TIFFStripSize(tif)); printf("TIFFNumberOfStrips = %d\n", TIFFNumberOfStrips(tif)); printf("TIFFVStripSize = %ld\n", (long int) TIFFVStripSize(tif,0)); printf("TIFFTileRowSize = %ld\n", (long int) TIFFTileRowSize(tif)); printf("TIFFTileSize = %ld\n", (long int) TIFFTileSize(tif)); printf("TIFFNumberOfTiles = %d\n", TIFFNumberOfTiles(tif)); printf("TIFFVTileSize = %ld\n", (long int) TIFFVTileSize(tif,0)); printf("TIFFDefaultStripSize = %d\n", TIFFDefaultStripSize(tif,0)); printf("TIFFFileno = %d\n", TIFFFileno(tif)); printf("TIFFGetMode = %d\n", TIFFGetMode(tif)); printf("TIFFIsTiled = %d\n", TIFFIsTiled(tif)); printf("TIFFIsByteSwapped = %d\n", TIFFIsByteSwapped(tif)); printf("TIFFRGBAImageOK = %d\n", TIFFRGBAImageOK(tif, (char*)"TIFFRGBAImageOK mesg\n")); TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w); TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h); TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bps); TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &spp); TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photo); TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &config); TIFFGetField(tif, TIFFTAG_PAGENUMBER, &pageNumber, &numberPages); TIFFGetField(tif, TIFFTAG_SUBFILETYPE, &subfileType); stripSize = TIFFStripSize(tif); stripMax = TIFFNumberOfStrips(tif); switch(bps){ case 8: pixelSize = 1; break; case 16: pixelSize = 2; break; default: pixelSize = 0; break; } dirCount = tif_DirCount(tif); printf("size = %lu, w = %d, h = %d, spp = %d, bps = %d, pixelSize = %ld\n", sizeof(w), w, h, spp, bps, (long int) pixelSize); printf("Page Number = %d\n", pageNumber); printf("Number Pages = %d\n", numberPages); printf("Photometric interpretation = %d\n", photo); printf("Planar configuration = %d\n", config); printf("stripSize = %ld, stripMax = %d\n", (long int) stripSize, stripMax); printf("Number of directories = %d\n", dirCount); printf("Subfile type = %d\n", subfileType); //printbin((char*)&w, sizeof(w)); //printbin((char*)&h, sizeof(h)); //raster = tif_ReadData(tif); //tif_PrintAsc(tif, raster, (char*)"ascimg.txt"); TIFFClose(tif); } return 0; }
static x3f_return_t write_camera_profiles(x3f_t *x3f, char *wb, const camera_profile_t *profiles, int num, TIFF *tiff) { FILE *tiff_file; uint32_t *profile_offsets; int i; assert(num >= 1); if (!write_camera_profile(x3f, wb, &profiles[0], tiff)) return X3F_ARGUMENT_ERROR; TIFFSetField(tiff, TIFFTAG_ASSHOTPROFILENAME, profiles[0].name); if (num == 1) return X3F_OK; profile_offsets = alloca((num-1)*sizeof(uint32_t)); tiff_file = fdopen(dup(TIFFFileno(tiff)), "w+b"); if (!tiff_file) return X3F_OUTFILE_ERROR; for (i=1; i < num; i++) { FILE *tmp; TIFF *tmp_tiff; #define BUFSIZE 1024 char buf[BUFSIZE]; int offset, count; if (!(tmp = tmpfile())) { fclose(tiff_file); return X3F_OUTFILE_ERROR; } if (!(tmp_tiff = TIFFFdOpen(dup(fileno(tmp)), "", "wb"))) { /* Big endian */ fclose(tmp); fclose(tiff_file); return X3F_OUTFILE_ERROR; } if (!write_camera_profile(x3f, wb, &profiles[i], tmp_tiff)) { fclose(tmp); TIFFClose(tmp_tiff); fclose(tiff_file); return X3F_ARGUMENT_ERROR; } TIFFWriteDirectory(tmp_tiff); TIFFClose(tmp_tiff); fseek(tiff_file, 0, SEEK_END); offset = (ftell(tiff_file)+1) & ~1; /* 2-byte alignment */ fseek(tiff_file, offset, SEEK_SET); profile_offsets[i-1] = offset; fputs("MMCR", tiff_file); /* DNG camera profile magic in big endian */ fseek(tmp, 4, SEEK_SET); /* Skip over the standard TIFF magic */ while((count = fread(buf, 1, BUFSIZE, tmp))) fwrite(buf, 1, count, tiff_file); fclose(tmp); } fclose(tiff_file); TIFFSetField(tiff, TIFFTAG_EXTRACAMERAPROFILES, num-1, profile_offsets); return X3F_OK; }
/* obtain some values from the tiff and check if they are what was expected */ int tifgettags(Mytiff * mytiff){ int row,cval; int32_t ww=0,hh=0,bb=0; cval=TIFFGetField(mytiff->tiffp,TIFFTAG_IMAGEWIDTH,&ww); if(cval != 1 ) { fprintf(stderr,"ERROR: %s: error reading width\n",__func__); return(103); } cval=TIFFGetField(mytiff->tiffp,TIFFTAG_ROWSPERSTRIP,&hh); //printf("rowsperstrip: %i\n",hh); mytiff->stripnum=TIFFNumberOfStrips(mytiff->tiffp); mytiff->stripsize=TIFFRawStripSize(mytiff->tiffp,0); cval=TIFFGetField(mytiff->tiffp,TIFFTAG_STRIPOFFSETS,&(mytiff->offsets)); if(cval != 1 ) { fprintf(stderr,"ERROR: %s: error reading offsets\n",__func__); return(103); } cval=TIFFGetField(mytiff->tiffp,TIFFTAG_STRIPBYTECOUNTS,&(mytiff->bytecounts)); if(cval != 1 ) { fprintf(stderr,"ERROR: %s: error reading bytecounts\n",__func__); return(103); } cval=TIFFGetField(mytiff->tiffp,TIFFTAG_IMAGELENGTH,&hh); if(cval != 1 ) { fprintf(stderr,"ERROR: %s: error reading length\n",__func__); return(103); } cval=TIFFGetField(mytiff->tiffp,TIFFTAG_BITSPERSAMPLE,&bb); if(cval != 1 ) { fprintf(stderr,"ERROR: %s: error reading bitspersample\n",__func__); return(103); } /* check validity of this tiff for the job */ /* height and width should always match */ /* unless zero then it's unknown */ /* and the new value used */ if (mytiff->wd != 0) { if(ww != mytiff->wd){ fprintf(stderr,"ERROR: data mismatch in %s!\n found ww=%i hh=%i bb=%i \n",__func__,ww,hh,bb); fprintf(stderr,"expected wd=%i ht=%i bits=%i \n",mytiff->wd,mytiff->ht,mytiff->bits); return(102); } } if (mytiff->ht != 0) { if(hh != mytiff->ht){ fprintf(stderr,"ERROR: data mismatch in %s!\n found ww=%i hh=%i bb=%i \n",__func__,ww,hh,bb); fprintf(stderr,"expected wd=%i ht=%i bits=%i \n",mytiff->wd,mytiff->ht,mytiff->bits); return(102); } } if (mytiff->bits != 0) { if(bb != mytiff->bits){ fprintf(stderr,"ERROR: data mismatch in %s!\n found ww=%i hh=%i bb=%i \n",__func__,ww,hh,bb); fprintf(stderr,"expected wd=%i ht=%i bits=%i \n",mytiff->wd,mytiff->ht,mytiff->bits); return(102); } } mytiff->ht = hh; mytiff->wd = ww; mytiff->bits=(bb); mytiff->bytes=(bb/8); mytiff->ndata=mytiff->wd * mytiff->ht; mytiff->nbytes = mytiff->ndata * mytiff->bytes; /* obtain the raw file io descriptor number */ mytiff->tiffno=TIFFFileno(mytiff->tiffp); return(0); }