Can't find the information you are looking for here? Then leave a message over on our WinBatch Tech Support Forum.
Keywords: TIF TIFF Page Count Conter Freeimage FreeImage.dll DllCall DllCallCdecl FreeImage_OpenMultiBitmap FreeImage_GetPageCount FreeImage_CloseMultiBitmap
;========================================================================================================================================== ; Create a list of all TIF files with their number of included image pages. ; ; Detlev Dalitz.20120412. ;========================================================================================================================================== ;------------------------------------------------------------------------------------------------------------------------------------------ #DefineFunction udfTIFPageCount (strFilename) IntControl (73, 1, @TRUE, "", 0) ; On error goto the label :WBERRORHANDLER and leave the function. LastError () hdlBB = BinaryAlloc (4) BinaryReadEx (hdlBB, 0, strFilename, 0, 2) intByteOrder = BinaryPeek2 (hdlBB, 0) Switch intByteOrder Case 18761 ; "II" the file is little-endian byte order (Intel). BinaryReadEx (hdlBB, 0, strFilename, 2, 2) intFileID = BinaryPeek2 (hdlBB, 0) ; These 2 header bytes are the file identifier. Version number (always 42). If intFileID != 42 ; If this is not 42, it is not a valid tif image. intPageCount = -2 Break EndIf BinaryReadEx (hdlBB, 0, strFilename, 4, 4) intPosIFD = BinaryPeek4 (hdlBB, 0) ; Offset to first IFD Image File Directory. This IFD can be located anywhere in the file. Every 'page' in a multi-page TIFF is represented by one IFD. intPageCount = 0 While intPosIFD ; Break on the null pointer. BinaryReadEx (hdlBB, 0, strFilename, intPosIFD, 2) intTags = BinaryPeek2 (hdlBB, 0) ; Number of tags in IFD. Read the first 2 bytes of the IFD header for the number of directory entries for this page. intPosNext = intPosIFD + 2 + (12 * intTags) ; Next pointer location is the number of entries at 12 bytes each plus 2 for the header. Offset to next IFD, if there is a next IFD, 0 otherwise. BinaryReadEx (hdlBB, 0, strFilename, intPosNext, 4) intPosIFD = BinaryPeek4 (hdlBB, 0) ; Read next pointer. intPageCount = intPageCount + 1 ; Increment page counter. EndWhile Break Case 19789 ; "MM" the file is big-endian byte order (Motorola). BinaryReadEx (hdlBB, 0, strFilename, 2, 2) BinaryPokeHex (hdlBB, 0, BinaryPeekHex (hdlBB, 1, 1) : BinaryPeekHex (hdlBB, 0, 1)) intFileID = BinaryPeek2 (hdlBB, 0) ; These 2 header bytes are the file identifier. Version number (always 42). If intFileID != 42 ; If this is not 42, it is not a valid tif image. intPageCount = -2 Break EndIf BinaryReadEx (hdlBB, 0, strFilename, 4, 4) BinaryPokeHex (hdlBB, 0, BinaryPeekHex (hdlBB, 3, 1) : BinaryPeekHex (hdlBB, 2, 1) : BinaryPeekHex (hdlBB, 1, 1) : BinaryPeekHex (hdlBB, 0, 1)) intPosIFD = BinaryPeek4 (hdlBB, 0) ; Offset to first IFD Image File Directory. This IFD can be located anywhere in the file. Every 'page' in a multi-page TIFF is represented by one IFD. intPageCount = 0 While intPosIFD ; Break on the null pointer. BinaryReadEx (hdlBB, 0, strFilename, intPosIFD, 2) BinaryPokeHex (hdlBB, 0, BinaryPeekHex (hdlBB, 1, 1) : BinaryPeekHex (hdlBB, 0, 1)) intTags = BinaryPeek2 (hdlBB, 0) ; Number of tags in IFD. Read the first 2 bytes of the IFD header for the number of directory entries for this page. intPosNext = intPosIFD + 2 + (12 * intTags) ; Next pointer location is the number of entries at 12 bytes each plus 2 for the header. Offset to next IFD, if there is a next IFD, 0 otherwise. BinaryReadEx (hdlBB, 0, strFilename, intPosNext, 4) BinaryPokeHex (hdlBB, 0, BinaryPeekHex (hdlBB, 3, 1) : BinaryPeekHex (hdlBB, 2, 1) : BinaryPeekHex (hdlBB, 1, 1) : BinaryPeekHex (hdlBB, 0, 1)) intPosIFD = BinaryPeek4 (hdlBB, 0) ; Read next pointer. intPageCount = intPageCount + 1 ; Increment page counter. EndWhile Break Case intByteOrder intPageCount = -1 ; Not a valid tif image. EndSwitch :WBERRORHANDLER If LastError () Then intPageCount = -3 ; Not a valid tif image. hdlBB = BinaryFree (hdlBB) Return intPageCount ;.......................................................................................................................................... ; This UDF udfTIFPageCount returns the integer number of all pages included in the given TIF file. ; ; In case of an error the function returns a negative integer value. ; -1 ... The TIF byte order mark "II" resp. "MM" cannot be found. ; -2 ... The TIF version number (always 42) cannot be found. ; -3 ... Any other error, possibly damage of the TIF file structure. ; ; See TIF specifications ... ; http://partners.adobe.com/public/developer/en/tiff/TIFF6.pdf ; http://www.awaresystems.be/imaging/tiff.html ; ; Detlev Dalitz.20120412. ;.......................................................................................................................................... #EndFunction ;------------------------------------------------------------------------------------------------------------------------------------------ ;------------------------------------------------------------------------------------------------------------------------------------------ #DefineSubRoutine udfPathFold (strPath) If !StrIndex (strPath, "\\", 0, @FWDSCAN) Then Return StrReplace (strPath, "\", "\" : @LF) Return "\\" : StrReplace (StrSub (strPath, 3, -1), "\", "\" : @LF) #EndSubRoutine ;------------------------------------------------------------------------------------------------------------------------------------------ ; Test. DirChange (DirScript ()) strFileThis = IntControl (1004, 0, 0, 0, 0) strFileListIn = ItemReplace ("TIF.List.In.txt", -1, strFileThis, ".") strFileListOut = ItemReplace ("TIF.List.Out.txt", -1, strFileThis, ".") ;---------------------------- :Step1 ; Collect TIF files. ;---------------------------- arrMasks = Arrayize ("*.tif|*.tiff", "|") intMasksLast = ArrInfo (arrMasks, 1) - 1 arrDisks = Arrayize (DiskScan (2), @TAB) intDisksLast = ArrInfo (arrDisks, 1) - 1 AddExtender ("wwfaf44i.dll") ; File and Folder Finder. fafHidden = 1 ; Include hidden files. ;fafSystem = 2 ; Include system files. ;fafFolders = 4 ; Inspect subfolder names also. ;fafFindFolders = 8 ; Only inspect subfolder names not file names. fafRecurse = 16 ; Recurse through subfolders. ;fafNoPathInfo = 32 ; Do not return path information to files or folders found. ;fafNoRedirect = 64 ; Do not turn off file redirection for x64 windows. strMsgTitle = 'Step 1 | TIF | Search for TIF files' strMsgText = "" BoxOpen (strMsgTitle, strMsgText) WinPlace (200, 200, 600, 700, "") BoxDataTag (1, 1) intCountObjects = 0 intCountItems = 0 intF = 0 arrFiles = ArrDimension (0) For intD = 0 To intDisksLast strFolderRoot = arrDisks[intD] : "\" For intM = 0 To intMasksLast strMask = arrMasks [intM] hdlFAF = fafOpen (strFolderRoot, strMask, fafRecurse|fafHidden) While @TRUE strFileFullName = fafFind (hdlFAF) If strFileFullName == "" Then Break intCountItems = intCountItems + 1 strMsgTitle1 = strMsgTitle : "|" : intCountItems : "|" : FileBaseName (strFileFullName) BoxTitle (strMsgTitle1) ArrayRedim (arrFiles, intF + 1) arrFiles[intF] = strFileFullName intF = intF + 1 intCountObjects = intCountObjects + 1 strMsgText = "Objects found: " : intCountObjects : @LF : @LF : udfPathFold (strFileFullName) BoxText (StrSub (strMsgText, 1, 2400)) ; Display only the first 2400 characters. BoxDataClear (1, 1) EndWhile fafClose (hdlFAF) Next Next If !!ArrInfo (arrFiles, 1) Then ArraySort (arrFiles) intBytesWritten = ArrayFilePut (strFileListIn, arrFiles) Drop (arrFiles) strMsgText = "Objects found: " : intCountObjects : @LF : @LF : "Ready." BoxButtonDraw (1, 1, "&OK", "50,780,950,950") BoxText (strMsgText) While !BoxButtonStat (1, 1) TimeDelay (0.2) EndWhile BoxButtonKill (1, 1) BoxShut () ;---------------------------- :Step2 ; Examine TIF files. ;---------------------------- IntControl (73, 2, @TRUE, "", 0) ; On error gosub the label :WBERRORHANDLER. strMsgTitle = "Step 2 | TIF | PageCount | ByteOrder" strMsgText = "" BoxOpen (strMsgTitle, strMsgText) WinPlace (200, 200, 600, 700, "") BoxDataTag (1, 1) arrFiles = ArrayFileGetCSV (strFileListIn, 0, "|") intFiles = ArrInfo (arrFiles, 1) intFilesLast = intFiles - 1 ArrayInsert (arrFiles, 0, 2) ; Column 0 contains PageCount. ArrayInsert (arrFiles, 0, 2) ; Column 1 contains ByteOrder. ; Column 2 contains FullFilename. intTicks1 = 0 intTicks2 = 0 hdlBB = BinaryAlloc (2) ; Buffer for ByteOrder bytes. For intF = 0 To intFilesLast arrFiles[intF, 0] = udfTIFPageCount (arrFiles[intF, 2]) BinaryReadEx (hdlBB, 0, arrFiles[intF, 2], 0, 2) ; Get ByteOrder bytes. arrFiles[intF, 1] = BinaryPeekStr (hdlBB, 0, 2) BinaryEodSet (hdlBB, 0) strMsgText = intFiles : "/" : 1 + intF : @LF : @LF : "PageCount = " : arrFiles[intF, 0] : @LF : "ByteOrder = " : arrFiles[intF, 1] : @LF : "Filename = " : @LF : udfPathFold (arrFiles[intF, 2]) BoxText (StrSub (strMsgText, 1, 2400)) ; Display only the first 2400 characters. BoxDataClear (1, 1) Next hdlBB = BinaryFree (hdlBB) intBytes = ArrayFilePutCSV (strFileListOut, arrFiles, "|") BoxButtonDraw (1, 1, "&OK", "50,780,950,950") BoxText (strMsgText) While !BoxButtonStat (1, 1) TimeDelay (0.2) EndWhile BoxButtonKill (1, 1) BoxShut () If intBytes Then Run (strFileListOut, "") :CANCEL Exit :WBERRORHANDLER IntControl (73, 2, @TRUE, "", 0) ; On error gosub the label :WBERRORHANDLER. Return ;========================================================================================================================================== ;;;
#DefineFunction GetPageCount(tiffile) ; returns number of pages in a multipage tiff file ; ; for info and downloads see http://freeimage.sourceforge.net/ ; ; KDMOYERS 2012.04.11 me = 'GetPageCount' If !FileExist(tiffile) Return -1 EndIf Terminate(StrUpper(FileExtension(tiffile)) != "TIF", me, 'only works on tiff files') FIF_BMP = 0 FIF_PCX = 10 FIF_TIFF = 18 FIF_JPEG = 2 pdllhandle = PtrPersistent(dllhandle, 0) If *pdllhandle == 0 Then *pdllhandle = DllLoad(DirScript() : "FreeImage.dll") ;DLL_API FIMULTIBITMAP * DLL_CALLCONV FreeImage_OpenMultiBitmap(FREE_IMAGE_FORMAT fif, const char *filename, BOOL create_new, BOOL read_only, BOOL keep_cache_in_memory FI_DEFAULT(FALSE), int flags FI_DEFAULT(0)); imag1 = DllCallCDecl(*pdllhandle, long : "_FreeImage_OpenMultiBitmap@24", long : FIF_TIFF, lpstr : tiffile, long : 0, long : 1, long : 0, long : 0) Terminate(imag1 == 0, me, 'Failed to load tiff' : @LF : tiffile) ;DLL_API int DLL_CALLCONV FreeImage_GetPageCount(FIMULTIBITMAP *bitmap); pages = DllCallCDecl(*pdllhandle, long : "_FreeImage_GetPageCount@4", long : imag1) ;DLL_API BOOL DLL_CALLCONV FreeImage_CloseMultiBitmap(FIMULTIBITMAP *bitmap, int flags FI_DEFAULT(0)); x = DllCallCDecl(*pdllhandle, long : "_FreeImage_CloseMultiBitmap@8", long : imag1, long : 0) Terminate(x == 0, me, 'Failed to close tiff') imag1 = 0 Return pages #EndFunction
Article ID: W18336
Filename: TIF Page Counter.txt
File Created: 2012:04:12:13:44:46
Last Updated: 2012:04:12:13:44:46