﻿;-- TIME_STAMP   2017-10-14 19:15:12   v 0.1

#Region ;************ Includes ************
#include-once
#include <GDIPlus.au3>
#EndRegion ;************ Includes ************

Global $g_iGDI_DEBUG = 1

If $__g_hGDIPDll = 0 Then
	_GDIPlus_Startup()
	OnAutoItExitRegister('_GDIPlus_Exit')
EndIf

Global Const $__g_aGDIPDecoders = _GDIPlus_Decoders()

$vRet = _GDIPlus_ImageFixFileExtension('m:\Meine Bilder\AutoIt.tif')
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $vRet = ' & $vRet & @CRLF & '>Error code: ' & @error & @CRLF & '>Extended code: ' & @extended & @CRLF) ;### Debug Console

;===============================================================================
; 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.
; 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
;                  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 (www.autoit.de)
;===============================================================================
Func _GDIPlus_ImageFixFileExtension($sFilename)
	Local $hImage, $aRet, $iFormat = -1, $iError = 0, $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] Step 1
		If $aRet[1] = $__g_aGDIPDecoders[$i][5] Then
			$iFormat = $i
			ExitLoop
		EndIf
	Next
	If $iFormat = -1 Then Return SetError(30, 0, 0)

	_DebugPrint('> _GDIPlus_ImageFixFileExtension(): FileName   = ' & $sFilename & @CRLF)
	_DebugPrint('> _GDIPlus_ImageFixFileExtension(): Format     = ' & $__g_aGDIPDecoders[$iFormat][5] & @CRLF)
	_DebugPrint('> _GDIPlus_ImageFixFileExtension(): Extensions = ' & $__g_aGDIPDecoders[$iFormat][6] & @CRLF)

	If StringInStr($__g_aGDIPDecoders[$iFormat][6], StringRegExpReplace($sFilename, '(?:.+)(\..+)', '$1')) Then Return SetError(0, 1, $sFilename)

	$sNewFile = StringRegExpReplace($sFilename, '(.+)\..+', '$1') & StringSplit(StringReplace(StringLower($__g_aGDIPDecoders[$iFormat][6]), '*', ''), ';', 2)[0]
	If FileExists($sNewFile) Then
		$aCrc32[0] = _ComputeCrc32($sFilename)
		If $iError Then Return SetError(40, 0, 0)
		$aCrc32[1] = _ComputeCrc32($sNewFile)
		If $iError Then Return SetError(40, 1, 0)
		If $aCrc32[0] = $aCrc32[1] Then
			_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', Hex($aCrc32[0], 8), $sFilename, Hex($aCrc32[1],8), $sNewFile))
			FileDelete($sFilename)
			Return $sNewFile
		Else
			$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]
		EndIf
	EndIf

	Return FileMove($sFilename, $sNewFile, 1) ? SetError(0, 0, $sNewFile) : SetError(1, 0, 0)
EndFunc   ;==>_GDIPlus_ImageFixFileExtension

Func _ComputeCrc32($sFilename)
	Local $sFile = FileRead($sFilename)
	If @error Then Return SetError(1, @error, 0)
	Local $iLength = StringLen($sFile)
	If $iLength = 0 Then Return SetError(1, 2, 0)

	Local $tData = DllStructCreate('byte[' & $iLength & ']')
	DllCall('ntdll.dll', 'none', 'RtlFillMemory', 'struct*', $tData, 'ulong_ptr', $iLength, 'byte', $sFile)
	If @error Then Return SetError(@error, @extended, 0)

	Local $aRet = DllCall('ntdll.dll', 'dword', 'RtlComputeCrc32', 'dword', 0, 'struct*', $tData, 'int', $iLength)
	If @error Or Not $aRet[0] Then Return SetError(@error + 10, @extended, 0)

	Return $aRet[0]
EndFunc   ;==>_ComputeCrc32

Func _DebugPrint($sString)
	If $g_iGDI_DEBUG Then ConsoleWrite($sString)
EndFunc   ;==>_DebugPrint

Func _GDIPlus_Exit()
	_GDIPlus_Shutdown()
EndFunc