Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support specifying the image scaling algorithm for image resizing/caching #6986

Merged
merged 6 commits into from
Jul 13, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 10 additions & 0 deletions Kodi.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -999,6 +999,9 @@
DFD882F817DD1A5B001516FE /* AddonPythonInvoker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFD882F417DD1A5B001516FE /* AddonPythonInvoker.cpp */; };
DFD928F316384B6800709DAE /* Timer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFD928F116384B6800709DAE /* Timer.cpp */; };
DFDA3153160E34230047A626 /* DVDOverlayCodec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFDA3152160E34230047A626 /* DVDOverlayCodec.cpp */; };
DFDE5D511AE5658200EE53AD /* PictureScalingAlgorithm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFDE5D4F1AE5658200EE53AD /* PictureScalingAlgorithm.cpp */; };
DFDE5D521AE5658200EE53AD /* PictureScalingAlgorithm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFDE5D4F1AE5658200EE53AD /* PictureScalingAlgorithm.cpp */; };
DFDE5D531AE5658200EE53AD /* PictureScalingAlgorithm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFDE5D4F1AE5658200EE53AD /* PictureScalingAlgorithm.cpp */; };
DFE4095B17417FDF00473BD9 /* LegacyPathTranslation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFE4095917417FDF00473BD9 /* LegacyPathTranslation.cpp */; };
DFEB902819E9337200728978 /* AEResampleFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFEB902619E9337200728978 /* AEResampleFactory.cpp */; };
DFEB902919E9337200728978 /* AEResampleFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DFEB902619E9337200728978 /* AEResampleFactory.cpp */; };
Expand Down Expand Up @@ -4612,6 +4615,8 @@
DFD928F116384B6800709DAE /* Timer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Timer.cpp; sourceTree = "<group>"; };
DFD928F216384B6800709DAE /* Timer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Timer.h; sourceTree = "<group>"; };
DFDA3152160E34230047A626 /* DVDOverlayCodec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DVDOverlayCodec.cpp; sourceTree = "<group>"; };
DFDE5D4F1AE5658200EE53AD /* PictureScalingAlgorithm.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PictureScalingAlgorithm.cpp; sourceTree = "<group>"; };
DFDE5D501AE5658200EE53AD /* PictureScalingAlgorithm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PictureScalingAlgorithm.h; sourceTree = "<group>"; };
DFE4095917417FDF00473BD9 /* LegacyPathTranslation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LegacyPathTranslation.cpp; sourceTree = "<group>"; };
DFE4095A17417FDF00473BD9 /* LegacyPathTranslation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LegacyPathTranslation.h; sourceTree = "<group>"; };
DFEB902519E9335E00728978 /* AEResample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AEResample.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -6342,6 +6347,8 @@
E38E1DDA0D25F9FD00618676 /* PictureInfoLoader.h */,
E38E1DDB0D25F9FD00618676 /* PictureInfoTag.cpp */,
E38E1DDC0D25F9FD00618676 /* PictureInfoTag.h */,
DFDE5D4F1AE5658200EE53AD /* PictureScalingAlgorithm.cpp */,
DFDE5D501AE5658200EE53AD /* PictureScalingAlgorithm.h */,
E38E1DDD0D25F9FD00618676 /* PictureThumbLoader.cpp */,
E38E1DDE0D25F9FD00618676 /* PictureThumbLoader.h */,
E38E1E090D25F9FD00618676 /* SlideShowPicture.cpp */,
Expand Down Expand Up @@ -10691,6 +10698,7 @@
F5E1138014357F3800175026 /* PeripheralCecAdapter.cpp in Sources */,
F54BCC5F1439345300F86B0F /* HotKeyController.m in Sources */,
DF673AA51443819600A5A509 /* AddonManager.cpp in Sources */,
DFDE5D511AE5658200EE53AD /* PictureScalingAlgorithm.cpp in Sources */,
F5BD02F6148D3A7E001B5583 /* CryptThreading.cpp in Sources */,
DF5276E1151BAEDA00B5B63B /* Base64.cpp in Sources */,
DF5276E2151BAEDA00B5B63B /* HttpResponse.cpp in Sources */,
Expand Down Expand Up @@ -11447,6 +11455,7 @@
DFF0F27D17528350002DA3A4 /* GUIBorderedImage.cpp in Sources */,
DFF0F27E17528350002DA3A4 /* GUIButtonControl.cpp in Sources */,
DFF0F27F17528350002DA3A4 /* GUICheckMarkControl.cpp in Sources */,
DFDE5D531AE5658200EE53AD /* PictureScalingAlgorithm.cpp in Sources */,
DFF0F28017528350002DA3A4 /* GUIColorManager.cpp in Sources */,
DFF0F28117528350002DA3A4 /* GUIControl.cpp in Sources */,
DFF0F28217528350002DA3A4 /* GUIControlFactory.cpp in Sources */,
Expand Down Expand Up @@ -12465,6 +12474,7 @@
395C2A201A9F96A700EBC7AD /* ContextItemAddon.cpp in Sources */,
E49912CC174E5DA000741B6D /* DirectoryNodeTitleMovies.cpp in Sources */,
E49912CD174E5DA000741B6D /* DirectoryNodeTitleMusicVideos.cpp in Sources */,
DFDE5D521AE5658200EE53AD /* PictureScalingAlgorithm.cpp in Sources */,
E49912CE174E5DA000741B6D /* DirectoryNodeTitleTvShows.cpp in Sources */,
E49912CF174E5DA000741B6D /* DirectoryNodeTvShowsOverview.cpp in Sources */,
E49912D0174E5DA000741B6D /* QueryParams.cpp in Sources */,
Expand Down
2 changes: 2 additions & 0 deletions project/VS2010Express/XBMC.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -713,6 +713,7 @@
<ClCompile Include="..\..\xbmc\pictures\Picture.cpp" />
<ClCompile Include="..\..\xbmc\pictures\PictureInfoLoader.cpp" />
<ClCompile Include="..\..\xbmc\pictures\PictureInfoTag.cpp" />
<ClCompile Include="..\..\xbmc\pictures\PictureScalingAlgorithm.cpp" />
<ClCompile Include="..\..\xbmc\pictures\PictureThumbLoader.cpp" />
<ClCompile Include="..\..\xbmc\pictures\SlideShowPicture.cpp" />
<ClCompile Include="..\..\xbmc\PlayListPlayer.cpp" />
Expand Down Expand Up @@ -999,6 +1000,7 @@
<ClInclude Include="..\..\xbmc\network\NetworkServices.h" />
<ClInclude Include="..\..\xbmc\peripherals\bus\virtual\PeripheralBusCEC.h" />
<ClInclude Include="..\..\xbmc\network\upnp\UPnPSettings.h" />
<ClInclude Include="..\..\xbmc\pictures\PictureScalingAlgorithm.h" />
<ClInclude Include="..\..\xbmc\playlists\SmartPlaylistFileItemListModifier.h" />
<ClInclude Include="..\..\xbmc\profiles\dialogs\GUIDialogLockSettings.h" />
<ClInclude Include="..\..\xbmc\profiles\dialogs\GUIDialogProfileSettings.h" />
Expand Down
6 changes: 6 additions & 0 deletions project/VS2010Express/XBMC.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -3096,6 +3096,9 @@
<ClCompile Include="..\..\xbmc\addons\ImageResource.cpp">
<Filter>addons</Filter>
</ClCompile>
<ClCompile Include="..\..\xbmc\pictures\PictureScalingAlgorithm.cpp">
<Filter>pictures</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\xbmc\win32\pch.h">
Expand Down Expand Up @@ -5986,6 +5989,9 @@
<ClInclude Include="..\..\xbmc\addons\ImageResource.h">
<Filter>addons</Filter>
</ClInclude>
<ClInclude Include="..\..\xbmc\pictures\PictureScalingAlgorithm.h">
<Filter>pictures</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\..\xbmc\win32\XBMC_PC.rc">
Expand Down
16 changes: 11 additions & 5 deletions xbmc/TextureCacheJob.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ bool CTextureCacheJob::CacheTexture(CBaseTexture **out_texture)
// unwrap the URL as required
std::string additional_info;
unsigned int width, height;
std::string image = DecodeImageURL(m_url, width, height, additional_info);
CPictureScalingAlgorithm::Algorithm scalingAlgorithm;
std::string image = DecodeImageURL(m_url, width, height, scalingAlgorithm, additional_info);

m_details.updateable = additional_info != "music" && UpdateableURL(image);

Expand Down Expand Up @@ -112,7 +113,7 @@ bool CTextureCacheJob::CacheTexture(CBaseTexture **out_texture)

CLog::Log(LOGDEBUG, "%s image '%s' to '%s':", m_oldHash.empty() ? "Caching" : "Recaching", image.c_str(), m_details.file.c_str());

if (CPicture::CacheTexture(texture, width, height, CTextureCache::GetCachedPath(m_details.file)))
if (CPicture::CacheTexture(texture, width, height, CTextureCache::GetCachedPath(m_details.file), scalingAlgorithm))
{
m_details.width = width;
m_details.height = height;
Expand All @@ -138,26 +139,28 @@ bool CTextureCacheJob::ResizeTexture(const std::string &url, uint8_t* &result, s
// unwrap the URL as required
std::string additional_info;
unsigned int width, height;
std::string image = DecodeImageURL(url, width, height, additional_info);
CPictureScalingAlgorithm::Algorithm scalingAlgorithm;
std::string image = DecodeImageURL(url, width, height, scalingAlgorithm, additional_info);
if (image.empty())
return false;

CBaseTexture *texture = LoadImage(image, width, height, additional_info, true);
if (texture == NULL)
return false;

bool success = CPicture::ResizeTexture(image, texture, width, height, result, result_size);
bool success = CPicture::ResizeTexture(image, texture, width, height, result, result_size, scalingAlgorithm);
delete texture;

return success;
}

std::string CTextureCacheJob::DecodeImageURL(const std::string &url, unsigned int &width, unsigned int &height, std::string &additional_info)
std::string CTextureCacheJob::DecodeImageURL(const std::string &url, unsigned int &width, unsigned int &height, CPictureScalingAlgorithm::Algorithm& scalingAlgorithm, std::string &additional_info)
{
// unwrap the URL as required
std::string image(url);
additional_info.clear();
width = height = 0;
scalingAlgorithm = CPictureScalingAlgorithm::NoAlgorithm;
if (StringUtils::StartsWith(url, "image://"))
{
// format is image://[type@]<url_encoded_path>?options
Expand All @@ -182,6 +185,9 @@ std::string CTextureCacheJob::DecodeImageURL(const std::string &url, unsigned in
if (thumbURL.HasOption("height") && StringUtils::IsInteger(thumbURL.GetOption("height")))
height = strtol(thumbURL.GetOption("height").c_str(), NULL, 0);
}

if (thumbURL.HasOption("scaling_algorithm"))
scalingAlgorithm = CPictureScalingAlgorithm::FromString(thumbURL.GetOption("scaling_algorithm"));
}
return image;
}
Expand Down
5 changes: 4 additions & 1 deletion xbmc/TextureCacheJob.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
#include <stdint.h>
#include <string>
#include <vector>

#include "pictures/PictureScalingAlgorithm.h"
#include "utils/Job.h"

class CBaseTexture;
Expand Down Expand Up @@ -103,10 +105,11 @@ class CTextureCacheJob : public CJob
\param url wrapped URL of the image
\param width width derived from URL
\param height height derived from URL
\param scalingAlgorithm scaling algorithm derived from URL
\param additional_info additional information, such as "flipped" to flip horizontally
\return URL of the underlying image file.
*/
static std::string DecodeImageURL(const std::string &url, unsigned int &width, unsigned int &height, std::string &additional_info);
static std::string DecodeImageURL(const std::string &url, unsigned int &width, unsigned int &height, CPictureScalingAlgorithm::Algorithm& scalingAlgorithm, std::string &additional_info);

/*! \brief Load an image at a given target size and orientation.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@
#include "utils/StringUtils.h"
#include "utils/URIUtils.h"

#define TRANSFORMATION_OPTION_WIDTH "width"
#define TRANSFORMATION_OPTION_HEIGHT "height"
#define TRANSFORMATION_OPTION_WIDTH "width"
#define TRANSFORMATION_OPTION_HEIGHT "height"
#define TRANSFORMATION_OPTION_SCALING_ALGORITHM "scaling_algorithm"

static const std::string ImageBasePath = "/image/";

Expand Down Expand Up @@ -141,6 +142,10 @@ int CHTTPImageTransformationHandler::HandleRequest()
if (option != options.end())
urlOptions.push_back(TRANSFORMATION_OPTION_HEIGHT "=" + option->second);

option = options.find(TRANSFORMATION_OPTION_SCALING_ALGORITHM);
if (option != options.end())
urlOptions.push_back(TRANSFORMATION_OPTION_SCALING_ALGORITHM "=" + option->second);

std::string imagePath = m_url;
if (!urlOptions.empty())
{
Expand Down
1 change: 1 addition & 0 deletions xbmc/pictures/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ SRCS=GUIDialogPictureInfo.cpp \
Picture.cpp \
PictureInfoLoader.cpp \
PictureInfoTag.cpp \
PictureScalingAlgorithm.cpp \
PictureThumbLoader.cpp \
SlideShowPicture.cpp \

Expand Down
32 changes: 22 additions & 10 deletions xbmc/pictures/Picture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,16 +129,21 @@ bool CThumbnailWriter::DoWork()
return success;
}

bool CPicture::ResizeTexture(const std::string &image, CBaseTexture *texture, uint32_t &dest_width, uint32_t &dest_height, uint8_t* &result, size_t& result_size)
bool CPicture::ResizeTexture(const std::string &image, CBaseTexture *texture,
uint32_t &dest_width, uint32_t &dest_height, uint8_t* &result, size_t& result_size,
CPictureScalingAlgorithm::Algorithm scalingAlgorithm /* = CPictureScalingAlgorithm::NoAlgorithm */)
{
if (image.empty() || texture == NULL)
return false;

return ResizeTexture(image, texture->GetPixels(), texture->GetWidth(), texture->GetHeight(), texture->GetPitch(),
dest_width, dest_height, result, result_size);
dest_width, dest_height, result, result_size,
scalingAlgorithm);
}

bool CPicture::ResizeTexture(const std::string &image, uint8_t *pixels, uint32_t width, uint32_t height, uint32_t pitch, uint32_t &dest_width, uint32_t &dest_height, uint8_t* &result, size_t& result_size)
bool CPicture::ResizeTexture(const std::string &image, uint8_t *pixels, uint32_t width, uint32_t height, uint32_t pitch,
uint32_t &dest_width, uint32_t &dest_height, uint8_t* &result, size_t& result_size,
CPictureScalingAlgorithm::Algorithm scalingAlgorithm /* = CPictureScalingAlgorithm::NoAlgorithm */)
{
if (image.empty() || pixels == NULL)
return false;
Expand Down Expand Up @@ -178,7 +183,7 @@ bool CPicture::ResizeTexture(const std::string &image, uint8_t *pixels, uint32_t
return false;
}

if (!ScaleImage(pixels, width, height, pitch, buffer, dest_width, dest_height, dest_width * sizeof(uint32_t)))
if (!ScaleImage(pixels, width, height, pitch, buffer, dest_width, dest_height, dest_width * sizeof(uint32_t), scalingAlgorithm))
{
delete[] buffer;
result = NULL;
Expand All @@ -198,19 +203,24 @@ bool CPicture::ResizeTexture(const std::string &image, uint8_t *pixels, uint32_t
return success;
}

bool CPicture::CacheTexture(CBaseTexture *texture, uint32_t &dest_width, uint32_t &dest_height, const std::string &dest)
bool CPicture::CacheTexture(CBaseTexture *texture, uint32_t &dest_width, uint32_t &dest_height, const std::string &dest,
CPictureScalingAlgorithm::Algorithm scalingAlgorithm /* = CPictureScalingAlgorithm::NoAlgorithm */)
{
return CacheTexture(texture->GetPixels(), texture->GetWidth(), texture->GetHeight(), texture->GetPitch(),
texture->GetOrientation(), dest_width, dest_height, dest);
texture->GetOrientation(), dest_width, dest_height, dest, scalingAlgorithm);
}

bool CPicture::CacheTexture(uint8_t *pixels, uint32_t width, uint32_t height, uint32_t pitch, int orientation, uint32_t &dest_width, uint32_t &dest_height, const std::string &dest)
bool CPicture::CacheTexture(uint8_t *pixels, uint32_t width, uint32_t height, uint32_t pitch, int orientation,
uint32_t &dest_width, uint32_t &dest_height, const std::string &dest,
CPictureScalingAlgorithm::Algorithm scalingAlgorithm /* = CPictureScalingAlgorithm::NoAlgorithm */)
{
// if no max width or height is specified, don't resize
if (dest_width == 0)
dest_width = width;
if (dest_height == 0)
dest_height = height;
if (scalingAlgorithm == CPictureScalingAlgorithm::NoAlgorithm)
scalingAlgorithm = g_advancedSettings.m_imageScalingAlgorithm;

uint32_t max_height = g_advancedSettings.m_imageRes;
if (g_advancedSettings.m_fanartRes > g_advancedSettings.m_imageRes)
Expand Down Expand Up @@ -238,7 +248,8 @@ bool CPicture::CacheTexture(uint8_t *pixels, uint32_t width, uint32_t height, ui
if (buffer)
{
if (ScaleImage(pixels, width, height, pitch,
(uint8_t *)buffer, dest_width, dest_height, dest_width * 4))
(uint8_t *)buffer, dest_width, dest_height, dest_width * 4,
scalingAlgorithm))
{
if (!orientation || OrientateImage(buffer, dest_width, dest_height, orientation))
{
Expand Down Expand Up @@ -328,11 +339,12 @@ void CPicture::GetScale(unsigned int width, unsigned int height, unsigned int &o
}

bool CPicture::ScaleImage(uint8_t *in_pixels, unsigned int in_width, unsigned int in_height, unsigned int in_pitch,
uint8_t *out_pixels, unsigned int out_width, unsigned int out_height, unsigned int out_pitch)
uint8_t *out_pixels, unsigned int out_width, unsigned int out_height, unsigned int out_pitch,
CPictureScalingAlgorithm::Algorithm scalingAlgorithm /* = CPictureScalingAlgorithm::NoAlgorithm */)
{
struct SwsContext *context = sws_getContext(in_width, in_height, PIX_FMT_BGRA,
out_width, out_height, PIX_FMT_BGRA,
SWS_FAST_BILINEAR | SwScaleCPUFlags(), NULL, NULL, NULL);
CPictureScalingAlgorithm::ToSwscale(scalingAlgorithm) | SwScaleCPUFlags(), NULL, NULL, NULL);

uint8_t *src[] = { in_pixels, 0, 0, 0 };
int srcStride[] = { (int)in_pitch, 0, 0, 0 };
Expand Down
23 changes: 17 additions & 6 deletions xbmc/pictures/Picture.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@
* <http://www.gnu.org/licenses/>.
*
*/
#include "utils/Job.h"

#include <string>
#include <vector>

#include "pictures/PictureScalingAlgorithm.h"
#include "utils/Job.h"

class CBaseTexture;

class CPicture
Expand All @@ -36,8 +39,12 @@ class CPicture
*/
static bool CreateTiledThumb(const std::vector<std::string> &files, const std::string &thumb);

static bool ResizeTexture(const std::string &image, CBaseTexture *texture, uint32_t &dest_width, uint32_t &dest_height, uint8_t* &result, size_t& result_size);
static bool ResizeTexture(const std::string &image, uint8_t *pixels, uint32_t width, uint32_t height, uint32_t pitch, uint32_t &dest_width, uint32_t &dest_height, uint8_t* &result, size_t& result_size);
static bool ResizeTexture(const std::string &image, CBaseTexture *texture,
uint32_t &dest_width, uint32_t &dest_height, uint8_t* &result, size_t& result_size,
CPictureScalingAlgorithm::Algorithm scalingAlgorithm = CPictureScalingAlgorithm::NoAlgorithm);
static bool ResizeTexture(const std::string &image, uint8_t *pixels, uint32_t width, uint32_t height, uint32_t pitch,
uint32_t &dest_width, uint32_t &dest_height, uint8_t* &result, size_t& result_size,
CPictureScalingAlgorithm::Algorithm scalingAlgorithm = CPictureScalingAlgorithm::NoAlgorithm);

/*! \brief Cache a texture, resizing, rotating and flipping as needed, and saving as a JPG or PNG
\param texture a pointer to a CBaseTexture
Expand All @@ -46,13 +53,17 @@ class CPicture
\param dest the output cache file
\return true if successful, false otherwise
*/
static bool CacheTexture(CBaseTexture *texture, uint32_t &dest_width, uint32_t &dest_height, const std::string &dest);
static bool CacheTexture(uint8_t *pixels, uint32_t width, uint32_t height, uint32_t pitch, int orientation, uint32_t &dest_width, uint32_t &dest_height, const std::string &dest);
static bool CacheTexture(CBaseTexture *texture, uint32_t &dest_width, uint32_t &dest_height, const std::string &dest,
CPictureScalingAlgorithm::Algorithm scalingAlgorithm = CPictureScalingAlgorithm::NoAlgorithm);
static bool CacheTexture(uint8_t *pixels, uint32_t width, uint32_t height, uint32_t pitch, int orientation,
uint32_t &dest_width, uint32_t &dest_height, const std::string &dest,
CPictureScalingAlgorithm::Algorithm scalingAlgorithm = CPictureScalingAlgorithm::NoAlgorithm);

private:
static void GetScale(unsigned int width, unsigned int height, unsigned int &out_width, unsigned int &out_height);
static bool ScaleImage(uint8_t *in_pixels, unsigned int in_width, unsigned int in_height, unsigned int in_pitch,
uint8_t *out_pixels, unsigned int out_width, unsigned int out_height, unsigned int out_pitch);
uint8_t *out_pixels, unsigned int out_width, unsigned int out_height, unsigned int out_pitch,
CPictureScalingAlgorithm::Algorithm scalingAlgorithm = CPictureScalingAlgorithm::NoAlgorithm);
static bool OrientateImage(uint32_t *&pixels, unsigned int &width, unsigned int &height, int orientation);

static bool FlipHorizontal(uint32_t *&pixels, unsigned int &width, unsigned int &height);
Expand Down