﻿#Region ;************ Includes ************
#include-once
#include <GDIPlus.au3>
#EndRegion ;************ Includes ************

Global $__g_iIFFE_DEBUG = True ; True = Debug-Ausgaben eingeschaltet

If $__g_hGDIPDll = 0 Then
	_GDIPlus_Startup()
	OnAutoItExitRegister('__IFFE_Exit')
EndIf
Global Const $__g_aGDIPDecoders = _GDIPlus_Decoders()
Global Const $__g_sIFFE_Version = '1.0.0.0'
Global Const $__g_sIFFE_Date = '2017-10-16 12:00:00'

Func __IFFE_Exit()
	_GDIPlus_Shutdown()
EndFunc   ;==>__IFFE_Exit

;===============================================================================
; Function Name:   _GDIPlus_ImageFixFileExtension($sFilename)
; Description:     Diese Funktion korrigiert die Dateiendung einer Bilddatei,
;                  wenn die Bilddatei eine falsche Endung aufweist.
;                  Existiert der neue Dateiname bereits, wird der neue Dateiname
;                  um einen Zaehler " (n)" erweitert.
;                  Wenn die bereits existierende Datei allerdings inhaltsgleich
;                  (gleiche CRC32-Checksumme) ist, mit der neuen Datei,
;                  dann wird die Datei mit der falschen Endung geloescht.
; Parameter(s):    $sFilename = Dateiname und -pfad der Bilddatei
; Requirement(s):  #include <GDIPlus.au3>
; Return Value(s): bei Erfolg = der neue Dateiname
;                     @extended = 0 - die Datei wurde umbenannt
;                     @extended = 1 - die Datei wurde nicht umbenannt
;                     @extended = 2 - die Datei war identisch mit einer
;                                     bereits existierenden Datei
;                  im Fehlerfall wird 0 zurueckgegeben und
;                     @error = 1 wenn FileMove fehlgeschlagen ist
;                     @error = 2 wenn PathYetAnotherMakeUniqueName fehlgeschlagen ist
;                     @error = Rueckgabe von _GDIPlus_ImageGetRawFormat, wenn
;                              Datei nicht vorhanden oder keine Bilddatei
; Author(s):       Oscar & Bitnugger (www.autoit.de)
;===============================================================================
Func _GDIPlus_ImageFixFileExtension($sFilename)
	Local $hImage, $aRet, $iFormat = -1, $iError, $aExt, $sNewFile, $aCrc32[2]
	$hImage = _GDIPlus_ImageLoadFromFile($sFilename)
	$aRet = _GDIPlus_ImageGetRawFormat($hImage)
	$iError = @error
	_GDIPlus_ImageDispose($hImage)
	If $iError Then Return SetError($iError, 0, 0)
	For $i = 1 To $__g_aGDIPDecoders[0][0]
		If $aRet[1] = $__g_aGDIPDecoders[$i][5] Then
			$iFormat = $i
			ExitLoop
		EndIf
	Next
	If $iFormat = -1 Then Return SetError(30, 0, 0)
	__IFFE_DebugPrint('> _GDIPlus_ImageFixFileExtension(): FileName   = ' & $sFilename & @CRLF)
	__IFFE_DebugPrint('> _GDIPlus_ImageFixFileExtension(): Format     = ' & $__g_aGDIPDecoders[$iFormat][5] & @CRLF)
	__IFFE_DebugPrint('> _GDIPlus_ImageFixFileExtension(): Extensions = ' & $__g_aGDIPDecoders[$iFormat][6] & @CRLF)
	$aExt = StringSplit(StringReplace(StringLower($__g_aGDIPDecoders[$iFormat][6]), '*', ''), ';', 2)
	For $sExt In $aExt
		If $sExt = StringRegExpReplace($sFilename, '(?:.+)(\..+)', '$1') Then Return SetError(0, 1, $sFilename)
	Next
	$sNewFile = StringRegExpReplace($sFilename, '(.+)\..+', '$1') & $aExt[0]
	If FileExists($sNewFile) Then
		$aCrc32[0] = __IFFE_ComputeCrc32($sFilename)
		If @error Then Return SetError(40, 0, 0)
		$aCrc32[1] = __IFFE_ComputeCrc32($sNewFile)
		If @error Then Return SetError(40, 0, 0)
		If $aCrc32[0] = $aCrc32[1] Then
			__IFFE_DebugPrint(StringFormat('! _GDIPlus_ImageFixFileExtension(): Diese Dateien sind identisch:\r' & _
					'! --> Crc32 = 0x%s  %s\t - Falsche Dateierweiterung  (wird gelöscht)\r' & _
					'+ --> Crc32 = 0x%s  %s\t - Richtige Dateierweiterung (wird behalten)\r', _
					$aCrc32[0], $sFilename, $aCrc32[1], $sNewFile))
			FileDelete($sFilename)
			Return SetError(0, 2, $sNewFile)
		EndIf
	EndIf
	$aRet = DllCall('shell32.dll', 'int', 'PathYetAnotherMakeUniqueName', 'wstr', '', 'wstr', $sNewFile, 'ptr', 0, 'ptr', 0)
	If @error Or Not $aRet[0] Then Return SetError(2, 0, 0)
	$sNewFile = $aRet[1]
	Return FileMove($sFilename, $sNewFile, 1) ? SetError(0, 0, $sNewFile) : SetError(1, 0, 0)
EndFunc   ;==>_GDIPlus_ImageFixFileExtension

Func __IFFE_DebugPrint($sString)
	If $__g_iIFFE_DEBUG Then ConsoleWrite($sString)
EndFunc   ;==>__IFFE_DebugPrint

Func __IFFE_ComputeCrc32($sFilePath)
	Local $hFile, $bData, $iLen, $tData, $aRet
	$hFile = FileOpen($sFilePath, $FO_BINARY)
	If $hFile = -1 Then Return SetError(1, 0, 0)
	$bData = FileRead($hFile)
	FileClose($hFile)
	$iLen = BinaryLen($bData)
	If $iLen = 0 Then Return SetError(2, 0, 0)
	$tData = DllStructCreate('byte[' & $iLen & ']')
	DllStructSetData($tData, 1, $bData)
	$aRet = DllCall('ntdll.dll', 'dword', 'RtlComputeCrc32', 'dword', 0, 'struct*', DllStructGetPtr($tData), 'int', $iLen)
	If @error Or Not $aRet[0] Then Return SetError(@error + 10, @extended, 0)
	Return Hex($aRet[0], 8)
EndFunc   ;==>__IFFE_ComputeCrc32
