stbLoadImage :: FilePath -> IO Image
stbLoadImage path = do
    cPath <- newCString path
    widthPtr <- new 0
    heightPtr <- new 0
    nComponentsPtr <- new 0

    dataPtr <- stbi_load cPath widthPtr heightPtr nComponentsPtr 3 -- 3 bytes per pixel (assumption!)
    dataForeignPtr <- newForeignPtr stbi_image_free dataPtr

    width  <- fromIntegral <$> peek widthPtr :: IO Int
    height <- fromIntegral <$> peek heightPtr :: IO Int

    let storage = V.unsafeFromForeignPtr0 dataForeignPtr (width * height * 3)

    free cPath
    free widthPtr
    free heightPtr
    free nComponentsPtr

    return $ Image (V.unsafeCast storage :: V.Vector RGBColor) width height
stbLoadImage :: FilePath -> IO Image
stbLoadImage path = do
    cPath <- newCString path
    widthPtr <- new 0
    heightPtr <- new 0
    nComponentsPtr <- new 0

    dataPtr <- stbi_load cPath widthPtr heightPtr nComponentsPtr 3 -- 3 bytes per pixel (assumption!)
    dataForeignPtr <- newForeignPtr stbi_image_free dataPtr

    width  <- fromIntegral <$> peek widthPtr :: IO Int
    height <- fromIntegral <$> peek heightPtr :: IO Int

    let storage = V.unsafeFromForeignPtr0 dataForeignPtr (width * height * 3)

    free cPath
    free widthPtr
    free heightPtr
    free nComponentsPtr

    return $ Image (V.unsafeCast storage :: V.Vector RGBColor) width height
stbLoadImage path = do
    cPath <- newCString path
    widthPtr <- new 0
    heightPtr <- new 0
    nComponentsPtr <- new 0

    dataPtr <- stbi_load cPath widthPtr heightPtr nComponentsPtr 3 -- 3 bytes per pixel (assumption!)
    dataForeignPtr <- newForeignPtr stbi_image_free dataPtr

    width  <- fromIntegral <$> peek widthPtr :: IO Int
    height <- fromIntegral <$> peek heightPtr :: IO Int

    let storage = V.unsafeFromForeignPtr0 dataForeignPtr (width * height * 3)

    free cPath
    free widthPtr
    free heightPtr
    free nComponentsPtr

    return $ Image (V.unsafeCast storage :: V.Vector RGBColor) width height