Permalink
Browse files

added: (POC) Use libjpeg to decode jpegs directly into an rgb texture.

Gives a significant speedup.
  • Loading branch information...
1 parent a2984ad commit 4676b62ccfc64d3996bc9e199efcc3796e911d96 theuni committed Jul 8, 2011
Showing with 85 additions and 0 deletions.
  1. +84 −0 xbmc/guilib/Texture.cpp
  2. +1 −0 xbmc/guilib/Texture.h
View
@@ -26,6 +26,9 @@
#include "pictures/DllImageLib.h"
#include "DDSImage.h"
#include "filesystem/SpecialProtocol.h"
+#include "jpeglib.h"
+#include "utils/fastmemcpy.h"
+#include "filesystem/File.h"
#if defined(__APPLE__) && defined(__arm__)
#include <ImageIO/ImageIO.h>
#include "filesystem/File.h"
@@ -297,6 +300,13 @@ bool CBaseTexture::LoadFromFile(const CStdString& texturePath, unsigned int maxW
CFRelease(cfdata);
delete [] imageBuff;
#else
+
+ if (URIUtils::GetExtension(texturePath).Equals(".jpg"))
+ {
+ if (DecodeJPEG(texturePath))
+ return true;
+ }
+
DllImageLib dll;
if (!dll.Load())
return false;
@@ -469,3 +479,77 @@ bool CBaseTexture::HasAlpha() const
{
return m_hasAlpha;
}
+
+
+bool CBaseTexture::DecodeJPEG(const char* texturePath)
+{
+
+ struct jpeg_decompress_struct cinfo;
+ struct jpeg_error_mgr jerr;
+ JSAMPROW row_pointer[1];
+ XFILE::CFile file;
+ uint8_t *imageBuff = NULL;
+ int64_t imageBuffSize = 0;
+
+ if (file.Open(texturePath, 0))
+ {
+ int64_t imgsize;
+ imgsize = file.GetLength();
+ imageBuff = new uint8_t[imgsize];
+ imageBuffSize = file.Read(imageBuff, imgsize);
+ file.Close();
+
+ if (imgsize != imageBuffSize)
+ CLog::Log(LOGERROR,"CBaseTexture::LoadHWAccelerated:imgsize(%llu) != imageBuffSize(%llu)",
+ imgsize, imageBuffSize);
@davilla

davilla Jul 8, 2011

LoadHWAccelerated :)

+
+ if (imageBuffSize <= 0)
+ {
+ delete [] imageBuff;
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+
+ cinfo.err = jpeg_std_error( &jerr );
+ jpeg_create_decompress( &cinfo );
+ jpeg_mem_src(&cinfo, imageBuff, imageBuffSize);
+ jpeg_read_header( &cinfo, TRUE );
+
+ //need rgb output
+ cinfo.out_color_space=JCS_RGB;
+
+ jpeg_start_decompress( &cinfo );
+
+ //jpegs don't have alpha so we only need rgb. we can use an rbg texture
+ //directly. It won't be byte aligned, but we make up for it by not having
+ //to set dummy alpha values.
+ Allocate(cinfo.image_width, cinfo.image_height, XB_FMT_R8G8B8);
+ m_hasAlpha = false;
+
+ unsigned int dstPitch = GetPitch();
+ unsigned int srcPitch = cinfo.output_width * cinfo.num_components;
+ unsigned char *dst = m_pixels;
+ unsigned char *src = imageBuff;
+
+ //pad rows to the destination texture size
+ row_pointer[0] = (unsigned char *)malloc( dstPitch );
+ memset(row_pointer[0],'\0',sizeof(dstPitch));
+
+ /* read one scan line at a time */
+ while( cinfo.output_scanline < cinfo.image_height )
+ {
+ jpeg_read_scanlines( &cinfo, row_pointer, 1 );
+ fast_memcpy(dst, row_pointer[0], dstPitch);
+ dst+=dstPitch;
+ }
+
+jpeg_finish_decompress( &cinfo );
+jpeg_destroy_decompress( &cinfo );
+free( row_pointer[0] );
+
+return true;
+}
View
@@ -96,6 +96,7 @@ class CBaseTexture
unsigned int GetPitch(unsigned int width) const;
unsigned int GetRows(unsigned int height) const;
unsigned int GetBlockSize() const;
+ bool DecodeJPEG(const char *);
unsigned int m_imageWidth;
unsigned int m_imageHeight;

0 comments on commit 4676b62

Please sign in to comment.