Jump to content
Mbee

Need help with FreeImage

Recommended Posts

I want an application I'm developing to be able to display more file/image types than the basics, so I've turned to FreeImage and @ProgAndy's and now @Iczer's FreeImage UDF (thanks again, you two!).  Here's my image conversion function...

;
;   =   =   =   =   =   =   =   =   =   =   =   =   =   =   =   =   =   =   =
;
;   Func _MyConvertPic() -- Use FreeImage to convert file to displayable BMP file
;
;   Input:      $arg_SrcPath - Full path to image file to be converted
;
;   Output:     $arg_FIBmpHdl   - Handle to FIBitmap which must eventually be unloaded
;               $arg_OutWidth   - Width in pixels of converted image, scaled to fit the image display area
;               $arg_OutHeight  - Height in pixels of converted image, also scaled
;
;   Side Effects:
;
;               Global variable $G_BinaryPicData -- Will hold resulting converted binary image
;               Global variable $G_PicDataIsFreeImage -- Will be set True to indicate that $arg_FIBmpHdl must eventually be unloaded

;
;   Return Values:  >0  Number of pages in successfully converted image
;                   -1  Unknown File/Image Type (FreeImage GetFIFType() call failed to identify FIF Type)
;                   -2  Unable to read specified file (FIF doesn't support reading)
;                   -3  File with no image data passed
;                   -4  Not found in File Type Translation Table; MIGHT mean that no conversion is necessary
;                   -5  _ArrayBinarySearch() Error
;                   -6  Layered Image Passed - Undisplayable
;                   -7  Multi-Page Image has less than 1 page, or _MyGetPageCount() call failed
;                   -8  _FreeImage_LoadU() call failed
;                   -9  _FreeImage_GetBPP() call failed
;                   -10 _FreeImage_ConvertTo24Bits() call failed
;                   -11 _FreeImage_ConvertTo24Bits returned null handle
;                   -12 _FreeImage_Unload() of first bitmap failed
;                   -13 _FreeImage_Rescale() call failed
;                   -14 _FreeImage_Unload() of second bitmap failed
;                   -15 _FreeImage_GetMemorySize() call failed
;                   -16 _FreeImage_OpenMemory() call failed
;                   -17 _FreeImage_SaveToMemory() call failed
;                   -18 _FreeImage_Unload() of third bitmap failed
;                   -19 _FreeImage_LoadFromMemory() call failed, or null handle returned
;                   -20 _FreeImage_GetBits() call failed, or null returned
;
Func _MyConvertPic( $arg_SrcPath, ByRef $arg_FIBmpHdl, ByRef $arg_OutWidth, ByRef $arg_OutHeight )
;
    Local $Lf_Stat, $Lf_FIFcode, $Lf_FIFtype, $Lf_IsValidImage, $Lf_PageCount, $Lf_FI_BPP, $Lf_TempImgPath
    Local $Lf_FIFx_BmpHdl, $Lf_FIF24_BmpHdl, $LF_FIF_Rescaled_BmpHdl, $Lf_FIBitmapNumBytes, $Lf_NewFIF_Bmp_Hdl
    Local $Lf_PicWidth, $Lf_PicHeight, $Lf_NewWidth, $Lf_NewHeight, $Lf_PicRatio, $Lf_MustReduce, $Lf_MustEnlarge
    Local $Lf_Drv, $Lf_Dir, $Lf_RealFileName, $Lf_ExtWithDot, $Lf_ExtNoDot, $Lf_TransIndex, $Lf_Error
    Local $Lf_FIMemHdl


    $Lf_Stat = _MyGetFIFType( $arg_SrcPath, $Lf_FIFcode )
    If $Lf_Stat <> 1 Then
        Return SetError(-1, 0, -1)
    EndIf

    If Not _FreeImage_FIFSupportsReading( $Lf_FIFcode ) Then
        Return SetError(-2, 0, -2)
    EndIf

    If FileGetSize($arg_SrcPath) < 128 Then                     ; Surely a valid, viewable image would have at least this many bytes!
        Return SetError(-3, 0, -3)
    EndIf

    _CustomPathSplit($arg_SrcPath, $Lf_Drv, $Lf_Dir, $Lf_RealFileName, $Lf_ExtWithDot)
    $Lf_ExtNoDot = StringUpper(StringRight($Lf_ExtWithDot, StringLen($Lf_ExtWithDot) - 1))

    $Lf_TransIndex = _ArrayBinarySearch( $G_TranslateFileTypesAra, $Lf_ExtNoDot, 0, 0, 0 )
    $Lf_Error = @error
    If $Lf_Error <> 0 Then
        If $Lf_Error = 3 Then                                   ; 3 = Not found in array
            Return SetError( -4, 0, -4)                         ; Might mean file needs no conversion
        Else
            Return SetError($Lf_Error, 0, -5)
        EndIf
    EndIf

    $Lf_FIFtype = $G_TranslateFileTypesAra[$Lf_TransIndex][1]

    If $Lf_FIFcode = $FIF_PSD Then
        If _IsLayeredPSD( $arg_SrcPath ) Then
            Return SetError(-6, 0, -6)
        EndIf
    EndIf

    $Lf_PageCount = 1                                           ; Assume normal, single-page image
    If ($Lf_FIFcode = $FIF_ICO) Or ($Lf_FIFcode = $FIF_TIFF) Then
        $Lf_PageCount = _MyGetPageCount( $Lf_FIFcode, $arg_SrcPath )
        If $Lf_PageCount < 1 Then
            Return SetError(-7, 0, -7)
        EndIf
        If $Lf_PageCount > 1 Then                               ; We won't try to display multiple pages
            $Lf_PageCount = 1
        EndIf
    EndIf

;
;   Start of main FreeImage processing
;

    $Lf_FIFx_BmpHdl = _FreeImage_LoadU( $Lf_FIFcode, $arg_SrcPath )
    If @error <> 0 Then
        $Lf_Error = @error
        Return SetError($Lf_Error, 0, -8)
    EndIf

    $Lf_FI_BPP = _FreeImage_GetBPP( $Lf_FIFx_BmpHdl )
    If @error <> 0 Then
        $Lf_Error = @error
        Return SetError($Lf_Error, 0, -9)
    EndIf

    If $Lf_FI_BPP <> 24 Then
        $Lf_FIF24_BmpHdl = _FreeImage_ConvertTo24Bits( $Lf_FIFx_BmpHdl )
        If @error <> 0 Then
            $Lf_Error = @error
            Return SetError($Lf_Error, 0, -10)
        EndIf

        If $Lf_FIF24_BmpHdl = 0 Then
            Return SetError(-11, 0, -11)
        EndIf

        _FreeImage_Unload( $Lf_FIFx_BmpHdl )
        If @error <> 0 Then
            $Lf_Error = @error
            Return SetError($Lf_Error, 0, -12)
        EndIf
    Else
        $Lf_FIF24_BmpHdl = $Lf_FIFx_BmpHdl
    EndIf

    $Lf_PicWidth = _FreeImage_GetWidth( $Lf_FIF24_BmpHdl )
    $Lf_PicHeight = _FreeImage_GetHeight( $Lf_FIF24_BmpHdl )

    $Lf_MustReduce = False
    $Lf_MustEnlarge = False

    If $G_InDual Then
        If $Lf_PicWidth > $G_DualImageAreaWidth Then
            $Lf_MustReduce = True
        EndIf
        If $Lf_PicHeight > $G_DualImageAreaHeight Then
            $Lf_MustReduce = True
        EndIf
    Else
        If $Lf_PicWidth > $Gc_SinglePicDisplayWidth Then
            $Lf_MustReduce = True
        EndIf
        If $Lf_PicHeight > $Gc_SinglePicDisplayHeight Then
            $Lf_MustReduce = True
        EndIf
    EndIf

    If $Lf_MustReduce Or $Lf_MustEnlarge Then

        $Lf_PicRatio = $Lf_PicWidth / $Lf_PicHeight
        If $Lf_MustReduce Then
            If $G_RealDispRatio > $Lf_PicRatio Then
                $Lf_NewWidth = Floor( ($Lf_PicWidth * $Gc_SinglePicDisplayHeight) / $Lf_PicHeight )
                $Lf_NewHeight = $Gc_SinglePicDisplayHeight
            Else
                $Lf_NewWidth = $G_DualImageAreaWidth
                $Lf_NewHeight = Floor( ($Lf_PicHeight * $G_DualImageAreaWidth) / $Lf_PicWidth )
            EndIf
        Else                        ; Must enlarge
            If $Lf_PicWidth > $Lf_PicHeight Then
                $Lf_NewWidth = $G_DualImageAreaWidth
                $Lf_NewHeight = Floor( ( $Lf_NewWidth / $Lf_PicWidth ) * $Lf_PicHeight )
            Else
                $Lf_NewHeight = $Gc_SinglePicDisplayHeight
                $Lf_NewWidth = Floor( ( $Lf_NewHeight / $Lf_PicHeight ) * $Lf_PicWidth )
            EndIf
        EndIf

        $LF_FIF_Rescaled_BmpHdl = _FreeImage_Rescale( $Lf_FIF24_BmpHdl, $Lf_NewWidth, $Lf_NewHeight, $FILTER_BICUBIC )
        If @error <> 0 Then
            $Lf_Error = @error
            Return SetError($Lf_Error, 0, -13)
        EndIf

        _FreeImage_Unload( $Lf_FIF24_BmpHdl )
        If @error <> 0 Then
            $Lf_Error = @error
            Return SetError($Lf_Error, 0, -14)
        EndIf

        $Lf_FIF24_BmpHdl = $LF_FIF_Rescaled_BmpHdl

        $Lf_PicWidth = _FreeImage_GetWidth( $Lf_FIF24_BmpHdl )
        $Lf_PicHeight = _FreeImage_GetHeight( $Lf_FIF24_BmpHdl )

    EndIf


    $Lf_FIBitmapNumBytes = _FreeImage_GetMemorySize( $Lf_FIF24_BmpHdl )
    If (@error <> 0) Or ($Lf_FIBitmapNumBytes = 0) Then
        $Lf_Error = @extended                                   ; The AutoIt FreeImage UDF returns @error into @extended
        Return SetError($Lf_Error, 0, -15)
    EndIf

    $Lf_FIMemHdl = _FreeImage_OpenMemory( $Lf_FIF24_BmpHdl, $Lf_FIBitmapNumBytes )
    If @error <> 0 Then
        $Lf_Error = @extended
        Return SetError($Lf_Error, 0, -16)
    EndIf

    _FreeImage_SaveToMemory( $FIF_BMP, $Lf_FIF24_BmpHdl, $Lf_FIMemHdl, $BMP_DEFAULT )
    If @error <> 0 Then
        $Lf_Error = @extended
        Return SetError($Lf_Error, 0, -17)
    EndIf

    _FreeImage_Unload( $Lf_FIF24_BmpHdl )
    If @error <> 0 Then
        $Lf_Error = @extended
        Return SetError($Lf_Error, 0, -18)
    EndIf

    $Lf_NewFIF_Bmp_Hdl =_FreeImage_LoadFromMemory( $FIF_BMP, $Lf_FIMemHdl, $BMP_DEFAULT )
    If (@error <> 0) Or ($Lf_NewFIF_Bmp_Hdl = 0) Then
        $Lf_Error = @extended
        Return SetError($Lf_Error, 0, -19)
    EndIf

    $G_BinaryPicData = _FreeImage_GetBits( $Lf_NewFIF_Bmp_Hdl )
    If (@error <> 0) Or ($G_BinaryPicData = 0) Then
        $Lf_Error = @extended
        Return SetError($Lf_Error, 0, -20)
    EndIf

    $arg_FIBmpHdl = $Lf_NewFIF_Bmp_Hdl
    $G_PicDataIsFreeImage = True
    Return SetError( 0, 0, $Lf_PageCount )

EndFunc

 

The problem is that every time I call this, the UDF function _FreeImage_LoadFromMemory() returns a null pointer, for no reason that I can understand. Everything works perfect, that is, not only is @error always zero, but all the returns and handles are correct (no null handles/pointers until then).

This is my first full attempt to convert image types using FreeImage, so I'm not at all certain I've done things correctly. But I don't see a mistake on my part, either. Perhaps someone with more experience with FreeImage would be willing to guide me?

Thanks!

Share this post


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

×
×
  • Create New...