Browse files

[imageloader] adds LoadFromFileInMemory to CBaseTexture

  • Loading branch information...
1 parent cc5ed3c commit 6f4ce3e394afddf46564690538a9889237ad77ba Jonathan Marshall committed Jun 24, 2012
View
69 lib/cximage-6.0/CxImage/DllInterface.cpp
@@ -429,6 +429,75 @@ extern "C"
return SaveThumb(image, "", thumb, maxWidth, maxHeight);
};
+ __declspec(dllexport) bool LoadImageFromMemory(const BYTE *buffer, unsigned int size, const char *mime, unsigned int maxwidth, unsigned int maxheight, ImageInfo *info)
+ {
+ if (!buffer || !size || !mime || !info) return false;
+
+ // load the image
+ DWORD dwImageType = CXIMAGE_FORMAT_UNKNOWN;
+ if (strlen(mime))
+ dwImageType = GetImageType(mime);
+ if (dwImageType == CXIMAGE_FORMAT_UNKNOWN)
+ dwImageType = DetectFileType(buffer, size);
+ if (dwImageType == CXIMAGE_FORMAT_UNKNOWN)
+ {
+ printf("PICTURE::LoadImageFromMemory: Unable to determine image type.");
+ return false;
+ }
+
+ CxImage *image = new CxImage(dwImageType);
+ if (!image)
+ return false;
+
+ int actualwidth = maxwidth;
+ int actualheight = maxheight;
+
+ try
+ {
+ bool success = image->Decode((BYTE*)buffer, size, dwImageType, actualwidth, actualheight);
+ if (!success && dwImageType != CXIMAGE_FORMAT_UNKNOWN)
+ { // try to decode with unknown imagetype
+ success = image->Decode((BYTE*)buffer, size, CXIMAGE_FORMAT_UNKNOWN);
+ }
+ if (!success || !image->IsValid())
+ {
+ printf("PICTURE::LoadImageFromMemory: Unable to decode image. Error:%s\n", image->GetLastError());
+ delete image;
+ return false;
+ }
+ }
+ catch (...)
+ {
+ printf("PICTURE::LoadImageFromMemory: Unable to decode image.");
+ delete image;
+ return false;
+ }
+
+ // ok, now resample the image down if necessary
+ if (ResampleKeepAspect(*image, maxwidth, maxheight) < 0)
+ {
+ printf("PICTURE::LoadImage: Unable to resample picture\n");
+ delete image;
+ return false;
+ }
+
+ // make sure our image is 24bit minimum
+ image->IncreaseBpp(24);
+
+ // fill in our struct
+ info->width = image->GetWidth();
+ info->height = image->GetHeight();
+ info->originalwidth = actualwidth;
+ info->originalheight = actualheight;
+ memcpy(&info->exifInfo, image->GetExifInfo(), sizeof(EXIFINFO));
+
+ // create our texture
+ info->context = image;
+ info->texture = image->GetBits();
+ info->alpha = image->AlphaGetBits();
+ return (info->texture != NULL);
+ };
+
__declspec(dllexport) bool CreateFolderThumbnail(const char **file, const char *thumb, int maxWidth, int maxHeight)
{
if (!file || !file[0] || !file[1] || !file[2] || !file[3] || !thumb) return false;
View
8 lib/cximage-6.0/CxImage/ximaenc.cpp
@@ -695,11 +695,19 @@ CxImage::CxImage(BYTE * buffer, DWORD size, DWORD imagetype)
* \param imagetype: file format, see ENUM_CXIMAGE_FORMATS
* \return true if everything is ok
*/
+#ifdef XBMC
+bool CxImage::Decode(BYTE * buffer, DWORD size, DWORD imagetype, int &width, int &height)
+{
+ CxMemFile file(buffer,size);
+ return Decode(&file,imagetype,width,height);
+}
+#else
bool CxImage::Decode(BYTE * buffer, DWORD size, DWORD imagetype)
{
CxMemFile file(buffer,size);
return Decode(&file,imagetype);
}
+#endif
////////////////////////////////////////////////////////////////////////////////
/**
* Loads an image from file handle.
View
9 lib/cximage-6.0/CxImage/ximage.h
@@ -520,6 +520,7 @@ typedef struct tagCxTextInfo
bool Load(const char * filename, DWORD imagetype, int &iWidth, int &iHeight);
bool Decode(FILE * hFile, DWORD imagetype, int &iWidth, int &iHeight);
bool Decode(CxFile * hFile, DWORD imagetype, int &iWidth, int &iHeight);
+ bool Decode(BYTE *buffer, DWORD size, DWORD imagetype, int &iWidth, int &iHeight);
bool Load(const char * filename, DWORD imagetype)
{
int iWidth=0;
@@ -538,12 +539,18 @@ typedef struct tagCxTextInfo
int iHeight=0;
return Decode(hFile, imagetype, iWidth, iHeight);
};
+ bool Decode(BYTE *buffer, unsigned int size, DWORD imagetype)
+ {
+ int iWidth=0;
+ int iHeight=0;
+ return Decode(buffer, size, imagetype, iWidth, iHeight);
+ };
#else
bool Load(const char * filename, DWORD imagetype);
bool Decode(FILE * hFile, DWORD imagetype);
bool Decode(CxFile * hFile, DWORD imagetype);
-#endif
bool Decode(BYTE * buffer, DWORD size, DWORD imagetype);
+#endif
bool CheckFormat(CxFile * hFile, DWORD imagetype = 0);
bool CheckFormat(BYTE * buffer, DWORD size, DWORD imagetype = 0);
View
2 xbmc/guilib/JpegIO.h
@@ -37,6 +37,7 @@ class CJpegIO
CJpegIO();
~CJpegIO();
bool Open(const CStdString& m_texturePath, unsigned int minx=0, unsigned int miny=0, bool read=true);
+ bool Read(unsigned char* buffer, unsigned int bufSize, unsigned int minx, unsigned int miny);
bool Decode(const unsigned char *pixels, unsigned int pitch, unsigned int format);
bool CreateThumbnail(const CStdString& sourceFile, const CStdString& destFile, int minx, int miny, bool rotateExif);
bool CreateThumbnailFromMemory(unsigned char* buffer, unsigned int bufSize, const CStdString& destFile, unsigned int minx, unsigned int miny);
@@ -48,7 +49,6 @@ class CJpegIO
unsigned int Orientation() { return m_orientation; }
protected:
- bool Read(unsigned char* buffer, unsigned int bufSize, unsigned int minx, unsigned int miny);
static void jpeg_error_exit(j_common_ptr cinfo);
unsigned int GetExifOrientation(unsigned char* exif_data, unsigned int exif_data_size);
View
58 xbmc/guilib/Texture.cpp
@@ -180,6 +180,15 @@ CBaseTexture *CBaseTexture::LoadFromFile(const CStdString& texturePath, unsigned
return NULL;
}
+CBaseTexture *CBaseTexture::LoadFromFileInMemory(unsigned char *buffer, size_t bufferSize, const std::string &mimeType, unsigned int idealWidth, unsigned int idealHeight)
+{
+ CTexture *texture = new CTexture();
+ if (texture->LoadFromFileInMem(buffer, bufferSize, mimeType, idealWidth, idealHeight))
+ return texture;
+ delete texture;
+ return NULL;
+}
+
bool CBaseTexture::LoadFromFile(const CStdString& texturePath, unsigned int maxWidth, unsigned int maxHeight,
bool autoRotate, unsigned int *originalWidth, unsigned int *originalHeight)
{
@@ -243,6 +252,55 @@ bool CBaseTexture::LoadFromFile(const CStdString& texturePath, unsigned int maxW
return true;
}
+bool CBaseTexture::LoadFromFileInMem(unsigned char* buffer, size_t size, const std::string& mimeType, unsigned int maxWidth, unsigned int maxHeight)
+{
+ if (!buffer || !size)
+ return false;
+
+ //ImageLib is sooo sloow for jpegs. Try our own decoder first. If it fails, fall back to ImageLib.
+ if (mimeType == "image/jpeg")
+ {
+ CJpegIO jpegfile;
+ if (jpegfile.Read(buffer, size, maxWidth, maxHeight))
+ {
+ if (jpegfile.Width() > 0 && jpegfile.Height() > 0)
+ {
+ Allocate(jpegfile.Width(), jpegfile.Height(), XB_FMT_A8R8G8B8);
+ if (jpegfile.Decode(m_pixels, GetPitch(), XB_FMT_A8R8G8B8))
+ {
+ m_hasAlpha=false;
+ ClampToEdge();
+ return true;
+ }
+ }
+ }
+ }
+ DllImageLib dll;
+ if (!dll.Load())
+ return false;
+
+ ImageInfo image;
+ memset(&image, 0, sizeof(image));
+
+ unsigned int width = maxWidth ? std::min(maxWidth, g_Windowing.GetMaxTextureSize()) : g_Windowing.GetMaxTextureSize();
+ unsigned int height = maxHeight ? std::min(maxHeight, g_Windowing.GetMaxTextureSize()) : g_Windowing.GetMaxTextureSize();
+
+ CStdString ext = mimeType;
+ int nPos = ext.Find('/');
+ if (nPos > -1)
+ ext.Delete(0, nPos + 1);
+
+ if(!dll.LoadImageFromMemory(buffer, size, ext.c_str(), width, height, &image))
+ {
+ CLog::Log(LOGERROR, "Texture manager unable to load image from memory");
+ return false;
+ }
+ LoadFromImage(image);
+ dll.ReleaseImage(&image);
+
+ return true;
+}
+
void CBaseTexture::LoadFromImage(ImageInfo &image, bool autoRotate)
{
m_hasAlpha = NULL != image.alpha;
View
16 xbmc/guilib/Texture.h
@@ -59,6 +59,20 @@ class CBaseTexture
*/
static CBaseTexture *LoadFromFile(const CStdString& texturePath, unsigned int idealWidth = 0, unsigned int idealHeight = 0,
bool autoRotate = false);
+
+ /*! \brief Load a texture from a file in memory
+ Loads a texture from a file in memory, restricting in size if needed based on maxHeight and maxWidth.
+ Note that these are the ideal size to load at - the returned texture may be smaller or larger than these.
+ \param buffer the memory buffer holding the file.
+ \param bufferSize the size of buffer.
+ \param mimeType the mime type of the file in buffer.
+ \param idealWidth the ideal width of the texture (defaults to 0, no ideal width).
+ \param idealHeight the ideal height of the texture (defaults to 0, no ideal height).
+ \return a CBaseTexture pointer to the created texture - NULL if the texture failed to load.
+ */
+ static CBaseTexture *LoadFromFileInMemory(unsigned char* buffer, size_t bufferSize, const std::string& mimeType,
+ unsigned int idealWidth = 0, unsigned int idealHeight = 0);
+
bool LoadFromFile(const CStdString& texturePath, unsigned int maxWidth, unsigned int maxHeight,
bool autoRotate, unsigned int *originalWidth, unsigned int *originalHeight);
bool LoadFromMemory(unsigned int width, unsigned int height, unsigned int pitch, unsigned int format, bool hasAlpha, unsigned char* pixels);
@@ -89,6 +103,8 @@ class CBaseTexture
bool SwapBlueRed(unsigned char *pixels, unsigned int height, unsigned int pitch, unsigned int elements = 4, unsigned int offset=0);
protected:
+ bool LoadFromFileInMem(unsigned char* buffer, size_t size, const std::string& mimeType,
+ unsigned int maxWidth, unsigned int maxHeight);
void LoadFromImage(ImageInfo &image, bool autoRotate = false);
// helpers for computation of texture parameters for compressed textures
unsigned int GetPitch(unsigned int width) const;
View
5 xbmc/pictures/DllImageLib.h
@@ -92,10 +92,11 @@ class DllImageLibInterface
virtual ~DllImageLibInterface() {}
virtual bool ReleaseImage(ImageInfo *)=0;
virtual bool LoadImage(const char *, unsigned int, unsigned int, ImageInfo *)=0;
+ virtual bool LoadImageFromMemory(const uint8_t*, unsigned int, const char *, unsigned int, unsigned int, ImageInfo *)=0;
virtual bool CreateThumbnail(const char *, const char *, int, int, bool)=0;
virtual bool CreateThumbnailFromMemory(BYTE *, unsigned int, const char *, const char *, int, int)=0;
virtual bool CreateFolderThumbnail(const char **, const char *, int, int)=0;
- virtual bool CreateThumbnailFromSurface(BYTE *, unsigned int, unsigned intB, unsigned int, const char *)=0;
+ virtual bool CreateThumbnailFromSurface(BYTE *, unsigned int, unsigned int, unsigned int, const char *)=0;
virtual int ConvertFile(const char *, const char *, float, int, int, unsigned int, bool)=0;
};
@@ -104,6 +105,7 @@ class DllImageLib : public DllDynamic, DllImageLibInterface
DECLARE_DLL_WRAPPER(DllImageLib, DLL_PATH_IMAGELIB)
DEFINE_METHOD1(bool, ReleaseImage, (ImageInfo *p1))
DEFINE_METHOD4(bool, LoadImage, (const char * p1, unsigned int p2, unsigned int p3, ImageInfo * p4))
+ DEFINE_METHOD6(bool, LoadImageFromMemory, (const uint8_t * p1, unsigned int p2, const char *p3, unsigned int p4, unsigned int p5, ImageInfo * p6))
DEFINE_METHOD5(bool, CreateThumbnail, (const char * p1, const char * p2, int p3, int p4, bool p5))
DEFINE_METHOD6(bool, CreateThumbnailFromMemory, (BYTE *p1, unsigned int p2, const char * p3, const char * p4, int p5, int p6))
DEFINE_METHOD4(bool, CreateFolderThumbnail, (const char ** p1, const char * p2, int p3, int p4))
@@ -112,6 +114,7 @@ class DllImageLib : public DllDynamic, DllImageLibInterface
BEGIN_METHOD_RESOLVE()
RESOLVE_METHOD(ReleaseImage)
RESOLVE_METHOD(LoadImage)
+ RESOLVE_METHOD(LoadImageFromMemory)
RESOLVE_METHOD(CreateThumbnail)
RESOLVE_METHOD(CreateThumbnailFromMemory)
RESOLVE_METHOD(CreateFolderThumbnail)

0 comments on commit 6f4ce3e

Please sign in to comment.