Jump to content

Recommended Posts

Hello.

I'm too stupid to see my mistake:

To investigate the internal "dictionary" of TIFF files I'd like to read in the files in binary mode and to check, if there are more than one pages "in" this TIFF.

Notepad++, "View as Hex" is presenting the first bytes as "49 49 2a 20 08 20 20 20 12" for the TIF attached to this posting

The "TIFF Header Format" is easy:

Offset 00h, 2 Byte = Byte Order, "II"=intel, "MM"=motorola. (I = 0x49)

--> II

Offset 02h, 2 Byte = Version Nr.

Offset 04h, 4 Byte = pointer to first IFD entry

Description of TIFF header: https://www.awaresystems.be/imaging/tiff/faq.html#q3

 


Howto read and analyse the binary content correctly? This is my messy, not operational code:

 

$sampleTiff="H:\daten\tif\11\11\111111.TIF"
$h=FileOpen($sampleTiff,16)
$content=FileRead($h)
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $content = ' & $content & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
FileClose($h)

$type=VarGetType($content)
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $type = ' & $type & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console


$ToString=BinaryToString($content)
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $ToString = ' & $ToString & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
ConsoleWrite(@CRLF  & @CRLF)

$content=StringTrimLeft($content,2) ; cut off the leading "0x"
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $content = ' & $content & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console


for $i = 1 to 8 step 8
    $next=StringMid($content,$i,2)
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') :     $next = ' &     $next & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    $Chr=BinaryToString($next)
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') :     $Chr = ' &  $Chr & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    ConsoleWrite(@CRLF & "---" & @CRLF)
Next

Regards, Rudi.

111111.TIF

Edited by rudi

Earth is flat, pigs can fly, and Nuclear Power is SAFE!

Link to post
Share on other sites
1 hour ago, rudi said:

Notepad++, "View as Hex" is presenting the first bytes as "49 49 2a 20 08 20 20 20 12" for the TIF attached to this posting

It's strange. I see "49 49 2A 00 08 00 00 00" in attached "111111.TIF"

$hFile = FileOpen("111111.tif", 16)
$ByteOrder = FileRead($hFile, 2)
$Version = FileRead($hFile, 2)
$FirstIFD = FileRead($hFile, 4)
FileClose($hFile)

ConsoleWrite($ByteOrder & @CRLF)
ConsoleWrite($Version & @CRLF)
ConsoleWrite($FirstIFD & @CRLF)

 

Link to post
Share on other sites

Hello,

 

thanks for your reply.

 

You are right. I copy-pasted the displayed values from Notepad++ (Hex View) and didn't notice, that they changed after beeing pasted here.

Amazing behaviour: Notepad++ can copy values to the clipboard, and when using this feature, "00" is modified to "20", no clue, why, all other values are correct. This is reproducable...

49 49 2a 00 08 00 00 00 11 00 fe 00 04 00 01 00 

 

Your code is quite exactly what I was looking for. I wasn't aware, that after opening a file in binary mode I am able to "read <offset> <ount-of-bytes>".

That should do, thanks a lot!

 

Regards, Rudi.

 

Earth is flat, pigs can fly, and Nuclear Power is SAFE!

Link to post
Share on other sites

Because If you use that notepad change 00 to 20 is to avoid end of string character (null bytes) dont care about. I suggest you to use a real hex editor. HxD is ok.

 

Saludos

 

 

Link to post
Share on other sites

Hello,

 

thanks for your reply. Notepad++ does *NOT* take the real values to the clipboard, but the "string representation". Except for "00", that's  replaced with "20", as far as I can see it right now...

 

Regards, Rudi.

Edited by rudi

Earth is flat, pigs can fly, and Nuclear Power is SAFE!

Link to post
Share on other sites

Hello.

 

somewhat modified code:

 

; $sampleTiff="H:\DATEN\tif\73\23\M000017323.tif"
; $sampleTiff="H:\daten\tif\11\11\111111.TIF"
$sampleTiff="111111.TIF"

$hFile=FileOpen($sampleTiff,16)



$Bo1=chr(FileRead($hFile,1)) ; Byte Order Info, Byte 1
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $Bo1 = ' & $Bo1 & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
$Bo2=chr(FileRead($hFile,1)) ; Byte Order Info, Byte 1
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $Bo2 = ' & $Bo2 & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
; is there a way to read the "0x4949" as "II" in one run? (I = indigo = 0x49)


$TVer1=FileRead($hFile,2) ; zwei bytes für TIFF Version. Immer 0x2A00
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $TVer1 = ' & $TVer1 & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
; the first read value seems to be the HighByte (big/little endian???)
; 2A = 42 = Version Number for all TIFFs I can touch right now. But it's 0x2A00, not 0x002A --> again little / big endian???


$IDF1Start=FileRead($hFile,4)
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $IDF1Start = ' & $IDF1Start & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
; offset 0x08 is correct.

$IDF1Count=FileRead($hFile,2)
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $IDF1Count = ' & $IDF1Count & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
; 0x11 = 17 entries a 12 bytes --> again it's 0x1100, not 0x0011


FileClose($hFile)


$Hex17=Hex(17,4)
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $Hex17 = ' & $Hex17 & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console

This is giving these consolewrite outputs. So I assume, I need to "swap" little-endian/big-endian

Is there a funktion doing so, that I've missed?

 

Regards, Rudi.

 

@@ Debug(11) : $Bo1 = I
>Error code: 0
@@ Debug(13) : $Bo2 = I
>Error code: 0
@@ Debug(18) : $TVer1 = 0x2A00
>Error code: 0
@@ Debug(24) : $IDF1Start = 0x08000000
>Error code: 0
@@ Debug(28) : $IDF1Count = 0x1100
>Error code: 0
@@ Debug(32) : $Hex17 = 0011
>Error code: 0

Edited by rudi

Earth is flat, pigs can fly, and Nuclear Power is SAFE!

Link to post
Share on other sites

May I suggest you read the header into a struct first (see DllStructCreate), then read individual elements with DllStructGetData? See my Xbase.au3 for an example (link in my sig).

Link to post
Share on other sites

Hello.

Thanks for your reply.

I never used DllStructCreate so far ... :sweating:

 

All I need is a look at the Pointer "Next IDF". If that value is 0x0000, then this is a single page tiff. That's all I need:

 

$sampleTiff="111111.TIF"

$hFile=FileOpen($sampleTiff,16)



$Bo1=chr(FileRead($hFile,1)) ; Byte Order Info, Byte 1
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $Bo1 = ' & $Bo1 & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
$Bo2=chr(FileRead($hFile,1)) ; Byte Order Info, Byte 1
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $Bo2 = ' & $Bo2 & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
; is there a way to read the "0x4949" as "II" in one run? (I = indigo = 0x49)


$TVer1=FileRead($hFile,2) ; zwei bytes für TIFF Version. Immer 0x2A00
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $TVer1 = ' & $TVer1 & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
; the first read value seems to be the HighByte (big/little endian???)
; 2A = 42 = Version Number for all TIFFs I can touch right now. But it's 0x2A00, not 0x002A --> again little / big endian???


$IDF1Start=FileRead($hFile,4)
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $IDF1Start = ' & $IDF1Start & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
; offset 0x08 is correct.

$IDF1Count=FileRead($hFile,2)
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $IDF1Count = ' & $IDF1Count & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
; 0x11 = 17 entries a 12 bytes --> again it's 0x1100, not 0x0011


$Hex17=Hex(17,4)
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $Hex17 = ' & $Hex17 & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console


for $Skip = 1 to 17 ; due to this little / big endian issue manually set "End-Value"
    $foo=FileRead($hFile,12)
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $foo = ' & $foo & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
Next

ConsoleWrite("Skipping done" & @CRLF)

$NextIDF=FileRead($hFile,4)
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $NextIDF = ' & $NextIDF & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console

if $NextIDF=0 Then
    MsgBox(0,"Multipage TIFF check","This TIFF has just one page.")
Else
    MsgBox(64,"Multipage TIFF check","This TIFF has *MORE* than one page.")
EndIf

FileClose($hFile)

 

That's giving this output:

@@ Debug(11) : $Bo1 = I
>Error code: 0
@@ Debug(13) : $Bo2 = I
>Error code: 0
@@ Debug(18) : $TVer1 = 0x2A00
>Error code: 0
@@ Debug(24) : $IDF1Start = 0x08000000
>Error code: 0
@@ Debug(28) : $IDF1Count = 0x1100
>Error code: 0
@@ Debug(33) : $Hex17 = 0011
>Error code: 0
@@ Debug(38) : $foo = 0xFE0004000100000000000000
>Error code: 0
@@ Debug(38) : $foo = 0x0001040001000000480D0000
>Error code: 0
@@ Debug(38) : $foo = 0x010104000100000030110000
>Error code: 0
@@ Debug(38) : $foo = 0x020103000100000001000000
>Error code: 0
@@ Debug(38) : $foo = 0x030103000100000004000000
>Error code: 0
@@ Debug(38) : $foo = 0x060103000100000000000000
>Error code: 0
@@ Debug(38) : $foo = 0x0A0103000100000001000000
>Error code: 0
@@ Debug(38) : $foo = 0x1101040001000000F6000000
>Error code: 0
@@ Debug(38) : $foo = 0x120103000100000001000000
>Error code: 0
@@ Debug(38) : $foo = 0x150103000100000001000000
>Error code: 0
@@ Debug(38) : $foo = 0x160104000100000030110000
>Error code: 0
@@ Debug(38) : $foo = 0x17010400010000005D2D0000
>Error code: 0
@@ Debug(38) : $foo = 0x1A01050001000000DA000000
>Error code: 0
@@ Debug(38) : $foo = 0x1B01050001000000E2000000
>Error code: 0
@@ Debug(38) : $foo = 0x250104000100000000000000
>Error code: 0
@@ Debug(38) : $foo = 0x280103000100000002000000
>Error code: 0
@@ Debug(38) : $foo = 0x310102000C000000EA000000
>Error code: 0
Skipping done
@@ Debug(44) : $NextIDF = 0x00000000

Important to me is just the value $NextIDF. That's it.

 

Regards, Rudi.

Earth is flat, pigs can fly, and Nuclear Power is SAFE!

Link to post
Share on other sites

Hello InnI.

Thanks for your suggestions for ....

#include <WinAPIMisc.au3>
_WinAPI_SwapWord()
_WinAPI_SwapDWord()
_WinAPI_SwapQWord()

I fail using it correctly, as the result of reading binary from the file is binary, not hex. And so far I couldn't figure out, how to convert the "binary string" to a "hex string".

 

$sampleTiff="111111.TIF"

$hFile=FileOpen($sampleTiff,16)



$Bo1=chr(FileRead($hFile,1)) ; Byte Order Info, Byte 1
$Bo2=chr(FileRead($hFile,1)) ; Byte Order Info, Byte 1
; is there a way to read the "0x4949" as "II" in one run? (I = indigo = 0x49)


$TVer=FileRead($hFile,2) ; zwei bytes für TIFF Version. Immer 0x2A00
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $TVer = ' & $TVer & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
$Type=VarGetType($TVer)
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $Type = ' & $Type & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console

$Swapped=_WinAPI_SwapWord($TVer)
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $Swapped = ' & $Swapped & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console

$AsString=$TVer & ""
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $AsString = ' & $AsString & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
VarGetType($AsString)
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : VarGetType($AsString) = ' & VarGetType($AsString) & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console

$Swapped2=_WinAPI_SwapWord($AsString)
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $Swapped2 = ' & $Swapped2 & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
ConsoleWrite("42 is the correct Dec value" & @CRLF)
$Type=VarGetType($Swapped2)
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $Type = ' & $Type & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
ConsoleWrite("Propably here I'm done, as I just need the DEC value to get the correct numbers?"& @CRLF)

ConsoleWrite("------------------" & @CRLF)

$Back2Hex=Hex($Swapped2,4)
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $Back2Hex = ' & $Back2Hex & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
$Type=VarGetType($Back2Hex)
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $Type = ' & $Type & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
; how would I get a HEX value? What do I miss?

output is this:

@@ Debug(16) : $TVer = 0x2A00
>Error code: 0
@@ Debug(18) : $Type = Binary
>Error code: 0
@@ Debug(21) : $Swapped = 10752
>Error code: 0
@@ Debug(24) : $AsString = 0x2A00
>Error code: 0
@@ Debug(26) : VarGetType($AsString) = String
>Error code: 0
@@ Debug(29) : $Swapped2 = 42
>Error code: 0
42 is the correct Dec value
@@ Debug(32) : $Type = Int32
>Error code: 0
Propably here I'm done, as I just need the DEC value to get the correct numbers?
------------------
@@ Debug(38) : $Back2Hex = 002A
>Error code: 0
@@ Debug(40) : $Type = String
>Error code: 0

 

Thanks again!

 

Regards, Rudi.

Earth is flat, pigs can fly, and Nuclear Power is SAFE!

Link to post
Share on other sites

@RTFC

Hello,

 

thanks for your reply.

I downloaded your xbase.au3 and tried this code. It's reporting "invalid header", all files are placed in the same folder (this script, xbase.au3, 111111.tif)

 

#cs ----------------------------------------------------------------------------

 AutoIt Version: 3.3.14.2
 Author:         myName

 Script Function:
    Template AutoIt script.

#ce ----------------------------------------------------------------------------

; Script Start - Add your code below here
#include "xbase.au3"
#include <array.au3>


dim $myArr[1]

$TIFF="111111.tif"
_Xbase_ReadToArray($TIFF,$myArr)
_ArrayDisplay($myArr)

regards, Rudi.

Earth is flat, pigs can fly, and Nuclear Power is SAFE!

Link to post
Share on other sites
39 minutes ago, rudi said:

I downloaded your xbase.au3 and tried this code. It's reporting "invalid header",

Yes, of course it would,^_^ a tiff file not being an Xbase file.:blink: I suggested this as an example how to produce a struct to read in a file header, in this case an Xbase (.dbf) database file. You define all elements using the appropriate variable type, read in the entire header (or as many bytes as you need to extract the info you need), and then use dllstructGetData to access individual elements as required. Obviously, a tiff file header will have a completely different structure than an Xbase file. But if you're only interested in a single Word, then a straight binary read would suffice.

Edited by RTFC
Link to post
Share on other sites

You can use GDI+ to get the amount of pages within a TIFF file:

#include <GDIPlus.au3>

Global $sFile_TIFF = FileOpenDialog("Select a TIF image", "", "TIFF (*.tif;*.tiff)")
If @error Then Exit

_GDIPlus_Startup()
Global $hImage = _GDIPlus_ImageLoadFromFile($sFile_TIFF)
Global $tGUID = _GDIPlus_GIFAnimGetFrameDimensionsList($hImage, _GDIPlus_GIFAnimGetFrameDimensionsCount($hImage))
Global $iCount = _GDIPlus_GIFAnimGetFrameCount($hImage, $tGUID)
_GDIPlus_ImageDispose($hImage)
_GDIPlus_Shutdown()
MsgBox(0, "TIF Page Count", "Pages: " & $iCount)


; #FUNCTION# ====================================================================================================================
; Name ..........: _GDIPlus_GIFAnimGetFrameDimensionsCount
; Description ...: Gets the number of frame dimensions in this Image object.
; Syntax ........: _GDIPlus_GIFAnimGetFrameDimensionsCount($hImage)
; Parameters ....: $hImage              - A handle to an image / bitmap object
; Return values .: The number of frame dimensions in this Image object.
; Author ........: UEZ
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........:
; ===============================================================================================================================
Func _GDIPlus_GIFAnimGetFrameDimensionsCount($hImage)
    Local Const $aResult = DllCall($__g_hGDIPDll, "int", "GdipImageGetFrameDimensionsCount", "handle", $hImage, "ulong*", 0)
    If @error Then Return SetError(@error, @extended, 0)
    If $aResult[0] Then Return SetError(10, $aResult[0], 0)
    Return $aResult[2]
EndFunc   ;==>_GDIPlus_GIFAnimGetFrameDimensionsCount

; #FUNCTION# ====================================================================================================================
; Name ..........: _GDIPlus_GIFAnimGetFrameCount
; Description ...: Gets the frame count of the loaded gif by passing the GUID struct
; Syntax ........: _GDIPlus_GIFAnimGetFrameCount($hImage, $tGUID)
; Parameters ....: $hImage              - A handle to an image / bitmap object
;                  $tGUID               - A struct to a GUID that specifies the frame dimension.
; Return values .: The amount of frames from a GIF animated image handle
; Author ........: UEZ
; Modified ......:
; Remarks .......:
; Related .......: _GDIPlus_ImageLoadFromFile _GDIPlus_BitmapCreateFromFile
; Link ..........:
; ===============================================================================================================================
Func _GDIPlus_GIFAnimGetFrameCount($hImage, $tGUID)
    Local Const $aResult = DllCall($__g_hGDIPDll, "int", "GdipImageGetFrameCount", "handle", $hImage, "struct*", $tGUID, "ptr*", 0)
    If @error Then Return SetError(@error, @extended, 0)
    If $aResult[0] Then Return SetError(10, $aResult[0], 0)
    Return Int($aResult[3])
EndFunc   ;==>_GDIPlus_GIFAnimGetFrameCount

; #FUNCTION# ====================================================================================================================
; Name ..........: _GDIPlus_GIFAnimGetFrameDimensionsList
; Description ...: Gets the identifiers for the frame dimensions of this Image object which fills the GUID struct.
; Syntax ........: _GDIPlus_GIFAnimGetFrameDimensionsList($hImage, $iFramesCount)
; Parameters ....: $hImage              - A handle to an image / bitmap object
;                  $iFramesCount        - An integer value.
; Return values .: tagGUID struct
; Author ........: UEZ
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........:
; ===============================================================================================================================
Func _GDIPlus_GIFAnimGetFrameDimensionsList($hImage, $iFramesCount)
    Local Const $tGUID = DllStructCreate($tagGUID)
    Local Const $aResult = DllCall($__g_hGDIPDll, "int", "GdipImageGetFrameDimensionsList", "handle", $hImage, "struct*", $tGUID, "uint", $iFramesCount)
    If @error Then Return SetError(@error, @extended, 0)
    If $aResult[0] Then Return SetError(10, $aResult[0], 0)
    Return $tGUID
EndFunc   ;==>_GDIPlus_GIFAnimGetFrameDimensionsList

 

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to post
Share on other sites

@rudi Try this code for TIFF frame count

#include <WinAPIMisc.au3>

$hFile = FileOpen("111111.tif", 16)
If $hFile = -1 Then Exit ConsoleWrite("File not found" & @CRLF)

$ByteOrder = FileRead($hFile, 2)
$Version = FileRead($hFile, 2)
If ($ByteOrder <> 0x4949 And $Version <> 0x2A00) _
Or ($ByteOrder <> 0x4D4D And $Version <> 0x002A) Then Exit ConsoleWrite("No TIFF" & @CRLF)

$FirstIFD = FileRead($hFile, 4)
If $ByteOrder = 0x4949 Then $FirstIFD = _WinAPI_SwapDWord(String($FirstIFD))
FileSetPos($hFile, $FirstIFD, 0)

$Count = 0
Do
  $Count += 1
  $NumTags = FileRead($hFile, 2)
  If $ByteOrder = 0x4949 Then $NumTags = _WinAPI_SwapWord(String($NumTags))
  FileSetPos($hFile, $NumTags * 12, 1)
  $NextIFD = FileRead($hFile, 4)
  If $ByteOrder = 0x4949 Then $NextIFD = _WinAPI_SwapDWord(String($NextIFD))
  FileSetPos($hFile, $NextIFD, 0)
Until Not $NextIFD

FileClose($hFile)
ConsoleWrite($Count & @CRLF)

 

Link to post
Share on other sites

@InnI

Hello.

 

That's exactly, what I was looking for! :thumbsup:

 

I have to admit, that I didn't really get the _WinApi_SwapDword() function so far ... :mad2:

I'll do further tries later on to get it :)

 

Thanks a lot !!!

 

Regards, Rudi.

Edited by rudi

Earth is flat, pigs can fly, and Nuclear Power is SAFE!

Link to post
Share on other sites

Here another version:

;Coded by UEZ build 2017-10-20 beta
#include <WinAPI.au3>

Global $sFile_TIFF = FileOpenDialog("Select a TIF image", "", "TIFF (*.tif;*.tiff)")
If @error Then Exit
ConsoleWrite("Pages found: " & TIFFPageCount($sFile_TIFF) & @CRLF)

Func TIFFPageCount($sFile_TIFF)
    Local $hFile = _WinAPI_CreateFile($sFile_TIFF, 2, 2), $Bytes
    Local $iFilesize = FileGetSize($sFile_TIFF)
    Local $tData = DllStructCreate("ushort Order;ushort Type;dword IFD")
    _WinAPI_ReadFile($hFile, DllStructGetPtr($tData), 8, $Bytes)
    If Not BitOR($tData.Order = 0x4949, $tData.Order = 0x4D4D) Then
        _WinAPI_CloseHandle($hFile)
        Return SetError(1, 0, 0)
    EndIf
    Local $IFD = $tData.IFD
    Local $tData2 = DllStructCreate("ushort NumDirEntries")
    Local $iTags, $iPages = 0
    Do
        _WinAPI_SetFilePointer($hFile, $IFD)
        _WinAPI_ReadFile($hFile, DllStructGetPtr($tData2), 2, $Bytes)
        If $tData2.NumDirEntries > 256 Then ExitLoop
        $iTags = $tData2.NumDirEntries * 12 + 2
        _WinAPI_SetFilePointer($hFile, $IFD + $iTags)
        _WinAPI_ReadFile($hFile, DllStructGetPtr($tData, "IFD"), 4, $Bytes)
        $IFD = $tData.IFD
        $iPages += 1
    Until $IFD = 0 or $IFD > $iFilesize - 4
    _WinAPI_CloseHandle($hFile)
    Return $iPages
EndFunc

 

I don't know if it is working also for TIFs multi page MM encoded.

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By AutoitMike
      A process of mine opens a HML file, modifies it and then saves, closes it.
      I then need to run an.exe that opens this file right after this.. However, nothing that I find on this forum works that supposedly tests to see if the fie is still open, ready to be used by another process.
      Right now, I just Sleep(2000) .
      I would like something cleaner than this.
      This function, for example, returns False when nothing has it opened or if I open the file with notepad or any other editor.
      I am running on a win7 laptop, if that has any bearing.
      $File="C:\Utilities\test\report.hr5" MsgBox(0,"", _FileInUse($File)) Exit Func _FileInUse($sFilePath) ; By Nessie. Modified by guinness. Local Const $hFileOpen = _WinAPI_CreateFile($sFilePath, $CREATE_ALWAYS, $FILE_SHARE_WRITE) If $hFileOpen Then _WinAPI_CloseHandle($hFileOpen) Return False EndIf Local $fReturn = False If _WinAPI_GetLastError() = 32 Then $fReturn = True Return $fReturn EndFunc  
    • By Pickpocketz88
      Func _Binary($Int) ;Uncomment To Only Accept Integers #cs If IsInt($Int) = 0 Then Return 0 EndIf #ce If $Int < 0 Then ;Negative Numbers Will Break The Function Return 0000 EndIf Local $Integer = $Int Dim $Bin[1] = [Mod($Integer, 2)] Local $Counter = 1 Do $Integer = Floor($Integer / 2) _ArrayAdd($Bin, Mod($Integer, 2)) Until $Integer = 0 _ArrayReverse($Bin) ;Reverses The Array Because As Is, The Product Is Backwards ;A Loop To Remove Any Preceding 0's or Add 0's To Keep At Least Four Digits Select Case $Int <= 1 $Integer = "00" & _ArrayToString($Bin, "") Case $Int = 2 Or $Int = 3 $Integer = "0" & _ArrayToString($Bin, "") Case $Int >= 8 $Integer = StringTrimLeft(_ArrayToString($Bin, ""), 1) Case Else $Integer = _ArrayToString($Bin, "") EndSelect ;You Can Comment It Out Without Anything Else Having A Problem Return $Integer EndFunc I made this because I was writing something that I could use to play with Bitwise Operations and using Binary() by itself wasn't helping.
      It's very basic and will only take positive integers because that's all I needed but I'm sure with a little tweaking you could make it fit with negative and float types.
      It returns a string essentially but doesn't pose a problem when just changing numbers into binary digits.
      Example: If you were to do _Binary(5) you would get "0101" and _Binary(8) would return "1000"
      Between this last sentence and here I've changed this about a half dozen times to refine it a bit because without it checking if your number is < 0 it would break if a negative number was inserted and it wouldn't even have a problem if you put in Float Values, Regular or Special Characters but that negative value will do the trick lol.
      Anyway, I hope someone finds some use of this and thank you for reading!
      -Pick
    • By Colduction
      Hi AutoIt Programmers, i wanna figure out how to use Binary functions in C# like:

      BinaryMid
      BinaryLen
      IsBinary and other basic ones were too ez, but those two were hard to noob like me.

      I appreciate for your helps/hints.
    • By lIlIIlIllIIIIlI
      $input = $CmdLine[1] $bytes = 1000000 ; 1000000 for 1 MB, 1000 for 1 KB $size = FileGetSize($input) $file = fileopen($input, 16) $max = ceiling($size / $bytes) for $i = 1 to $max $data = fileread($file, $bytes) $output = $input & '_' & $i & 'of' & $max filewrite($output, $data) next ^file split
      file path for a 20MB "video.mp4" is input, it will be output as "video.mp4_1of20", "video.mp4_2of20", etc. change $bytes to affect the split files size, this example made them 1MB (10^6 bytes)
       
      $input = $CmdLine[1] $name = stringtrimright($input, 1 + stringlen($input) - stringinstr($input, '_', 0, -1)) $split = stringsplit($input, 'of', 3) $max = $split[ubound($split) - 1] for $i = 1 to $max $in = $name & '_' & $i & 'of' & $max $file = fileopen($in, 16) $data = fileread($file) fileclose($file) filedelete($in) filewrite($name, $data) next ^ file join
      file path for any of the "video.mp4_Xof20" segments is input. the "video.mp4_Xof20" segments are read and written to "video.mp4" and then deleted, leaving the newly joined "video.mp4" in the end
       
      i made this today because i had a big file that i couldn't really open. i split it into 1000 chunks to make processing and stuff easier. i've also used it to split files to just under 25MB segments so i can attach and mail big files over gmail which is silly but it worked
    • By TheSaint
      I like and have been using TeraCopy, a third party program, for many years. Mostly it is a great program, but it does have some issues. On Windows XP for instance, Thumbs.db files could often hold up a copy or move process until the user manually responded to the error prompt. Some other issues I discuss below.
      PLEASE NOTE - I am not related to or affiliated in any way with the 3rd party TeraCopy program developers.
      ALSO NOTE - I myself have only tested TeraCopy Cure at this point, on Windows 7 (32 bit), and only with the free version of TeraCopy 2.27.
      This program, TeraCopy Cure, is related to another one of my TeraCopy assistant programs, TeraCopy Timer, but aims at being simpler and quicker to use ... if lacking its more advanced features.
      TeraCopy Cure is a frontend for TeraCopy and sets out to make up for its flaws and limitations.
      One of those flaws is queuing order, and the limitation relates to a same destination issue.
      You would think that queue order would be the same as add order, but that is not the case, and if you are doing a mix of COPY and MOVE then the COPY process could easily fail. It could fail with some source items, even if the  COPY process has already started before the same source MOVE process begins ... especially if the destination folder is on the source drive ... only the currently copying file is locked to that process.
      If you drag and drop another source for a same destination as an existing or impending COPY or MOVE process, then usually TeraCopy nicely adds it for you to that existing job. However, you might wish to avoid that, or it might occur during the testing phase of that active process, and then not be properly processed etc. But you are not given a choice and it just gets added.
       
           
      HOW TO USE
      See the right-click menu of the 'Batch List' (lowest field) and the right-click menu of the Tree field, for some useful options.
      (1) If desired, enable 'Auto Start'. NOTE - Even if enabled, this can be bypassed.
      (2) Set the destination folder, either by browsing on the tree or by dragging a folder to the Destination input field or label. Right-clicking on a folder in Explorer will also work, if enabled. The destination folder path will also show in the Tree if that right-click option is enabled.
      (3) Then drag & drop source file or folder onto one of three five areas - Folder (Drive) Tree field, or COPY or MOVE buttons ... this now also includes the source input and label.
      NOTE - If the Folder (Drive) Tree field is used, then you will additionally need to click either the COPY or MOVE button, to have that job added to the Batch List ... but this avoids 'Auto Start' if it is enabled. Drag & dropping to the buttons instead, saves on clicking, but starts the first job etc immediately if 'Auto Start' is enabled.
      (4) If needed and ready, click the START button to run the first job and those that follow.
      More information is included in program and in the NOTES etc sections below.
         
      WARNING - Depending on the amount of content on your destination drive, and folder level depth, and the speed of your PC, display of the full path in the Folder (Drive) Tree can take a while to show ... if you have that (right-click) option enabled ... it isn't by default. I found this feature quite tricky to get right, and I'm still not 100% sure it is now full-proof.
      TeraCopy Cure v1.5.zip  (source is included)
      TeraCopy Cure v1.6.zip  (source is included)
      NOTES
      UPDATES INFORMATION
      OLDER DOWNLOADS
       
×
×
  • Create New...