Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #1109 from jmarshallnz/music_thumbs_to_cache

Music thumbs to cache
  • Loading branch information...
commit f70b7d720870f5005884f3cf9158748f564aaeb8 2 parents 9080eab + f878229
@jmarshallnz jmarshallnz authored
Showing with 1,411 additions and 2,313 deletions.
  1. +42 −308 lib/cximage-6.0/CxImage/DllInterface.cpp
  2. +8 −0 lib/cximage-6.0/CxImage/ximaenc.cpp
  3. +8 −1 lib/cximage-6.0/CxImage/ximage.h
  4. +0 −1  xbmc/Application.cpp
  5. +1 −1  xbmc/ApplicationMessenger.cpp
  6. +2 −203 xbmc/FileItem.cpp
  7. +1 −32 xbmc/FileItem.h
  8. +8 −10 xbmc/GUIInfoManager.cpp
  9. +2 −7 xbmc/GUILargeTextureManager.cpp
  10. +31 −25 xbmc/TextureCacheJob.cpp
  11. +4 −4 xbmc/TextureCacheJob.h
  12. +132 −5 xbmc/ThumbLoader.cpp
  13. +28 −0 xbmc/ThumbLoader.h
  14. +0 −162 xbmc/ThumbnailCache.cpp
  15. +0 −16 xbmc/ThumbnailCache.h
  16. +0 −21 xbmc/Util.cpp
  17. +0 −4 xbmc/Util.h
  18. +2 −2 xbmc/cores/dvdplayer/DVDFileInfo.cpp
  19. +4 −17 xbmc/dialogs/GUIDialogContextMenu.cpp
  20. +7 −109 xbmc/filesystem/DirectoryCache.cpp
  21. +0 −9 xbmc/filesystem/DirectoryCache.h
  22. +12 −4 xbmc/guilib/JpegIO.cpp
  23. +1 −1  xbmc/guilib/JpegIO.h
  24. +80 −8 xbmc/guilib/Texture.cpp
  25. +31 −2 xbmc/guilib/Texture.h
  26. +2 −2 xbmc/guilib/TextureManager.cpp
  27. +0 −1  xbmc/interfaces/AnnouncementManager.cpp
  28. +3 −83 xbmc/interfaces/http-api/XBMChttp.cpp
  29. +0 −2  xbmc/interfaces/json-rpc/AudioLibrary.cpp
  30. +18 −15 xbmc/interfaces/json-rpc/FileItemHandler.cpp
  31. +2 −0  xbmc/music/Album.h
  32. +0 −30 xbmc/music/LastFmManager.cpp
  33. +214 −241 xbmc/music/MusicDatabase.cpp
  34. +73 −9 xbmc/music/MusicDatabase.h
  35. +29 −6 xbmc/music/MusicInfoLoader.cpp
  36. +15 −3 xbmc/music/Song.cpp
  37. +13 −6 xbmc/music/Song.h
  38. +62 −104 xbmc/music/dialogs/GUIDialogMusicInfo.cpp
  39. +0 −2  xbmc/music/dialogs/GUIDialogMusicInfo.h
  40. +26 −27 xbmc/music/dialogs/GUIDialogSongInfo.cpp
  41. +214 −183 xbmc/music/infoscanner/MusicInfoScanner.cpp
  42. +41 −4 xbmc/music/infoscanner/MusicInfoScanner.h
  43. +8 −24 xbmc/music/tags/FlacTag.cpp
  44. +5 −25 xbmc/music/tags/Id3Tag.cpp
  45. +2 −1  xbmc/music/tags/ImusicInfoTagLoader.h
  46. +68 −12 xbmc/music/tags/MusicInfoTag.cpp
  47. +33 −3 xbmc/music/tags/MusicInfoTag.h
  48. +1 −1  xbmc/music/tags/MusicInfoTagLoaderASAP.cpp
  49. +1 −1  xbmc/music/tags/MusicInfoTagLoaderASAP.h
  50. +1 −1  xbmc/music/tags/MusicInfoTagLoaderApe.cpp
  51. +1 −1  xbmc/music/tags/MusicInfoTagLoaderApe.h
  52. +1 −1  xbmc/music/tags/MusicInfoTagLoaderCDDA.cpp
  53. +1 −1  xbmc/music/tags/MusicInfoTagLoaderCDDA.h
  54. +1 −1  xbmc/music/tags/MusicInfoTagLoaderDatabase.cpp
  55. +1 −1  xbmc/music/tags/MusicInfoTagLoaderDatabase.h
  56. +2 −1  xbmc/music/tags/MusicInfoTagLoaderFlac.cpp
  57. +1 −1  xbmc/music/tags/MusicInfoTagLoaderFlac.h
  58. +2 −1  xbmc/music/tags/MusicInfoTagLoaderMP3.cpp
  59. +1 −1  xbmc/music/tags/MusicInfoTagLoaderMP3.h
  60. +18 −40 xbmc/music/tags/MusicInfoTagLoaderMP4.cpp
  61. +3 −5 xbmc/music/tags/MusicInfoTagLoaderMP4.h
  62. +1 −1  xbmc/music/tags/MusicInfoTagLoaderMidi.cpp
  63. +1 −1  xbmc/music/tags/MusicInfoTagLoaderMidi.h
  64. +1 −1  xbmc/music/tags/MusicInfoTagLoaderMod.cpp
  65. +1 −1  xbmc/music/tags/MusicInfoTagLoaderMod.h
  66. +1 −1  xbmc/music/tags/MusicInfoTagLoaderNSF.cpp
  67. +1 −1  xbmc/music/tags/MusicInfoTagLoaderNSF.h
  68. +2 −1  xbmc/music/tags/MusicInfoTagLoaderOgg.cpp
  69. +1 −1  xbmc/music/tags/MusicInfoTagLoaderOgg.h
  70. +1 −1  xbmc/music/tags/MusicInfoTagLoaderSPC.cpp
  71. +1 −1  xbmc/music/tags/MusicInfoTagLoaderSPC.h
  72. +1 −1  xbmc/music/tags/MusicInfoTagLoaderShn.cpp
  73. +1 −1  xbmc/music/tags/MusicInfoTagLoaderShn.h
  74. +8 −35 xbmc/music/tags/MusicInfoTagLoaderWMA.cpp
  75. +2 −2 xbmc/music/tags/MusicInfoTagLoaderWMA.h
  76. +1 −1  xbmc/music/tags/MusicInfoTagLoaderWav.cpp
  77. +1 −1  xbmc/music/tags/MusicInfoTagLoaderWav.h
  78. +1 −1  xbmc/music/tags/MusicInfoTagLoaderYM.cpp
  79. +1 −1  xbmc/music/tags/MusicInfoTagLoaderYM.h
  80. +3 −1 xbmc/music/tags/Tag.h
  81. +8 −52 xbmc/music/windows/GUIWindowMusicBase.cpp
  82. +0 −1  xbmc/music/windows/GUIWindowMusicBase.h
  83. +14 −10 xbmc/music/windows/GUIWindowMusicNav.cpp
  84. +1 −0  xbmc/music/windows/GUIWindowMusicNav.h
  85. +0 −8 xbmc/music/windows/GUIWindowMusicPlaylist.cpp
  86. +0 −5 xbmc/music/windows/GUIWindowMusicPlaylistEditor.cpp
  87. +0 −2  xbmc/music/windows/GUIWindowMusicSongs.cpp
  88. +3 −4 xbmc/network/UPnP.cpp
  89. +4 −13 xbmc/pictures/DllImageLib.h
  90. +0 −1  xbmc/pictures/GUIWindowPictures.cpp
  91. +0 −1  xbmc/pictures/GUIWindowSlideShow.cpp
  92. +22 −128 xbmc/pictures/Picture.cpp
  93. +0 −8 xbmc/pictures/Picture.h
  94. +2 −2 xbmc/pictures/PictureThumbLoader.cpp
  95. +4 −4 xbmc/settings/AdvancedSettings.cpp
  96. +6 −2 xbmc/settings/AdvancedSettings.h
  97. +7 −1 xbmc/settings/Settings.cpp
  98. +3 −3 xbmc/settings/Settings.h
  99. +0 −26 xbmc/storage/DetectDVDType.cpp
  100. +0 −41 xbmc/utils/Fanart.cpp
  101. +0 −20 xbmc/utils/Fanart.h
  102. +9 −8 xbmc/utils/RecentlyAddedJob.cpp
  103. +0 −37 xbmc/utils/ScraperUrl.cpp
  104. +0 −1  xbmc/utils/ScraperUrl.h
  105. +3 −11 xbmc/video/VideoDatabase.cpp
  106. +0 −20 xbmc/video/VideoInfoScanner.cpp
  107. +0 −9 xbmc/video/VideoInfoScanner.h
  108. +1 −1  xbmc/video/dialogs/GUIDialogVideoBookmarks.cpp
  109. +7 −7 xbmc/video/dialogs/GUIDialogVideoInfo.cpp
  110. +20 −40 xbmc/video/windows/GUIWindowVideoNav.cpp
  111. +0 −1  xbmc/windows/GUIWindowFileManager.cpp
View
350 lib/cximage-6.0/CxImage/DllInterface.cpp
@@ -17,12 +17,6 @@
#define RESAMPLE_QUALITY 0
#undef USE_EXIF_THUMBS
-// MS DirectX routines don't like loading .jpg less than 8x8 pixels.
-#define MIN_THUMB_WIDTH 8
-#define MIN_THUMB_HEIGHT 8
-#define MAX_WIDTH 4096
-#define MAX_HEIGHT 4096
-
extern "C" struct ImageInfo
{
unsigned int width;
@@ -35,13 +29,6 @@ extern "C" struct ImageInfo
BYTE *alpha;
};
-#if defined(_LINUX) || defined(__APPLE__)
-static void DeleteFile(const char* name)
-{
- unlink(name);
-}
-#endif
-
// helper functions
// determines based on file extension the type of file
@@ -110,45 +97,7 @@ int DetectFileType(const BYTE* pBuffer, int nBufSize)
return CXIMAGE_FORMAT_UNKNOWN;
}
-bool CopyFile(const char *src, const char *dest)
-{
- const unsigned int bufferSize = 16384;
- char buffer[bufferSize];
- FILE *hSrc = fopen(src, "rb");
- if (!hSrc) return false;
- FILE *hDest = fopen(dest, "wb");
- if (!hDest)
- {
- fclose(hSrc);
- return false;
- }
- bool ret = true;
- while (ret)
- {
- int sizeRead = fread(buffer, 1, bufferSize, hSrc);
- if (sizeRead > 0)
- {
- int sizeWritten = fwrite(buffer, 1, sizeRead, hDest);
- if (sizeWritten != sizeRead)
- {
- printf("PICTURE:Error writing file in copy");
- ret = false;
- }
- }
- else if (sizeRead < 0)
- {
- printf("PICTURE:Error reading file for copy");
- ret = false;
- }
- else
- break; // we're done
- }
- fclose(hSrc);
- fclose(hDest);
- return ret;
-}
-
-int ResampleKeepAspect(CxImage &image, unsigned int width, unsigned int height, bool checkTooSmall = false)
+int ResampleKeepAspect(CxImage &image, unsigned int width, unsigned int height)
{
bool bResize = false;
float fAspect = ((float)image.GetWidth()) / ((float)image.GetHeight());
@@ -166,18 +115,6 @@ int ResampleKeepAspect(CxImage &image, unsigned int width, unsigned int height,
newheight = height;
newwidth = (DWORD)( fAspect * ( (float)newheight) );
}
- if (checkTooSmall && newwidth < MIN_THUMB_WIDTH)
- {
- bResize = true;
- newwidth = MIN_THUMB_HEIGHT;
- newheight = (DWORD)( ( (float)newwidth) / fAspect);
- }
- if (checkTooSmall && newheight < MIN_THUMB_HEIGHT)
- {
- bResize = true;
- newheight = MIN_THUMB_HEIGHT;
- newwidth = (DWORD)( fAspect * ( (float)newheight) );
- }
if (bResize)
{
if (!image.Resample(newwidth, newheight, RESAMPLE_QUALITY) || !image.IsValid())
@@ -189,70 +126,6 @@ int ResampleKeepAspect(CxImage &image, unsigned int width, unsigned int height,
return bResize ? 1 : 0;
}
-int ResampleKeepAspectArea(CxImage &image, unsigned int area)
-{
- float fAspect = ((float)image.GetWidth()) / ((float)image.GetHeight());
- unsigned int width = (unsigned int)sqrt(area * fAspect);
- unsigned int height = (unsigned int)sqrt(area / fAspect);
- if (width > MAX_WIDTH) width = MAX_WIDTH;
- if (height > MAX_HEIGHT) height = MAX_HEIGHT;
- return ResampleKeepAspect(image, width, height, true);
-}
-
-bool SaveThumb(CxImage &image, const char *file, const char *thumb, int maxWidth, int maxHeight, bool bNeedToConvert = true, bool autoRotate = true)
-{
- // ok, now resample the image down if necessary
- int ret = ResampleKeepAspectArea(image, maxWidth * maxHeight);
- if (ret < 0) return false;
- if (ret) bNeedToConvert = true;
-
- // if we don't have a png but have a < 24 bit image, then convert to 24bits
- if ( image.GetNumColors())
- {
- if (!image.IncreaseBpp(24) || !image.IsValid())
- {
- printf("PICTURE::SaveThumb: Unable to convert to 24bpp: Error:%s\n", image.GetLastError());
- return false;
- }
- bNeedToConvert = true;
- }
-
- if ( autoRotate && image.GetExifInfo()->Orientation > 1)
- {
- image.RotateExif(image.GetExifInfo()->Orientation);
- bNeedToConvert = true;
- }
-
-#ifndef _LINUX
- ::DeleteFile(thumb);
-#else
- unlink(thumb);
-#endif
-
- // only resave the image if we have to (quality of the JPG saver isn't too hot!)
- if (bNeedToConvert)
- {
- // May as well have decent quality thumbs
- image.SetJpegQuality(90);
- if (!image.Save(thumb, image.AlphaIsValid() ? CXIMAGE_FORMAT_PNG : CXIMAGE_FORMAT_JPG))
- {
- printf("PICTURE::SaveThumb: Unable to save image: %s Error:%s\n", thumb, image.GetLastError());
- ::DeleteFile(thumb);
- return false;
- }
- }
- else
- { // Don't need to convert the file - copy it instead
- if (!CopyFile(file, thumb))
- {
- printf("PICTURE::SaveThumb: Unable to copy file %s\n", file);
- ::DeleteFile(thumb);
- return false;
- }
- }
- return true;
-}
-
#ifdef LoadImage
#undef LoadImage
#endif
@@ -344,166 +217,74 @@ extern "C"
return (info->texture != NULL);
};
-
- __declspec(dllexport) bool CreateThumbnail(const char *file, const char *thumb, int maxWidth, int maxHeight, bool rotateExif)
+ __declspec(dllexport) bool LoadImageFromMemory(const BYTE *buffer, unsigned int size, const char *mime, unsigned int maxwidth, unsigned int maxheight, ImageInfo *info)
{
- if (!file || !thumb) return false;
-
- if (IsDir(file))
- return false;
+ if (!buffer || !size || !mime || !info) return false;
// load the image
- DWORD dwImageType = GetImageType(file);
- CxImage image(dwImageType);
- int actualwidth = maxWidth * maxHeight;
- int actualheight = 0;
- try
- {
- // jpeg's may contain an EXIF preview image
- // we don't use it though, as the resolution is normally too low
-#ifdef USE_EXIF_THUMBS
- if ((dwImageType == CXIMAGE_FORMAT_JPG || dwImageType == CXIMAGE_FORMAT_RAW) && image.GetExifThumbnail(file, thumb, dwImageType))
- {
- return true;
- }
-#endif
-
- if (!image.Load(file, dwImageType, actualwidth, actualheight) || !image.IsValid())
- {
- printf("PICTURE::CreateThumbnail: Unable to open image: %s Error:%s\n", file, image.GetLastError());
- return false;
- }
- }
- catch (...)
- {
- printf("PICTURE::CreateThumbnail: Unable to open image: %s\n", file);
- return false;
- }
-
- // we need to convert if we don't have a jpeg or png.
- bool bNeedToConvert = (dwImageType != CXIMAGE_FORMAT_JPG && dwImageType != CXIMAGE_FORMAT_PNG);
- if (actualwidth > maxWidth || actualheight > maxHeight)
- bNeedToConvert = true;
-
- // save png thumbs as png, but all others as jpeg
- return SaveThumb(image, file, thumb, maxWidth, maxHeight, bNeedToConvert, rotateExif);
- };
-
- __declspec(dllexport) bool CreateThumbnailFromMemory(BYTE *buffer, unsigned int size, const char *ext, const char *thumb, int maxWidth, int maxHeight)
- {
- if (!buffer || !size || !ext || !thumb) return false;
- // load the image
DWORD dwImageType = CXIMAGE_FORMAT_UNKNOWN;
- if (strlen(ext)) {
- dwImageType = GetImageType(ext);
- if (dwImageType == CXIMAGE_FORMAT_UNKNOWN)
- dwImageType = DetectFileType(buffer, size);
- }
- else
+ if (strlen(mime))
+ dwImageType = GetImageType(mime);
+ if (dwImageType == CXIMAGE_FORMAT_UNKNOWN)
dwImageType = DetectFileType(buffer, size);
if (dwImageType == CXIMAGE_FORMAT_UNKNOWN)
{
- printf("PICTURE::CreateThumbnailFromMemory: Unable to determine image type.");
+ printf("PICTURE::LoadImageFromMemory: Unable to determine image type.");
return false;
}
- CxImage image(dwImageType);
+
+ CxImage *image = new CxImage(dwImageType);
+ if (!image)
+ return false;
+
+ int actualwidth = maxwidth;
+ int actualheight = maxheight;
+
try
{
- bool success = image.Decode(buffer, size, dwImageType);
+ 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(buffer, size, CXIMAGE_FORMAT_UNKNOWN);
+ success = image->Decode((BYTE*)buffer, size, CXIMAGE_FORMAT_UNKNOWN);
}
- if (!success || !image.IsValid())
+ if (!success || !image->IsValid())
{
- printf("PICTURE::CreateThumbnailFromMemory: Unable to decode image. Error:%s\n", image.GetLastError());
+ printf("PICTURE::LoadImageFromMemory: Unable to decode image. Error:%s\n", image->GetLastError());
+ delete image;
return false;
}
}
catch (...)
{
- printf("PICTURE::CreateThumbnailFromMemory: Unable to decode image.");
+ printf("PICTURE::LoadImageFromMemory: Unable to decode image.");
+ delete image;
return false;
}
- return SaveThumb(image, "", thumb, maxWidth, maxHeight);
- };
-
- __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;
-
- CxImage folderimage(maxWidth, maxHeight, 32, CXIMAGE_FORMAT_PNG);
- folderimage.AlphaCreate();
- int iWidth = maxWidth / 2;
- int iHeight = maxHeight / 2;
- for (int i = 0; i < 2; i++)
- {
- for (int j = 0; j < 2; j++)
- {
- int width = iWidth;
- int height = iHeight;
- bool bBlank = false;
- if (strlen(file[i*2 + j]) == 0)
- bBlank = true;
- if (!bBlank)
- {
- CxImage image;
- if (image.Load(file[i*2 + j], CXIMAGE_FORMAT_JPG, width, height))
- {
- // resize image to iWidth
- if (ResampleKeepAspect(image, iWidth - 2, iHeight - 2) >= 0)
- {
- int iOffX = (iWidth - 2 - image.GetWidth()) / 2;
- int iOffY = (iHeight - 2 - image.GetHeight()) / 2;
- for (int x = 0; x < iWidth; x++)
- {
- for (int y = 0; y < iHeight; y++)
- {
- RGBQUAD rgb;
- if (x < iOffX || x >= iOffX + (int)image.GetWidth() || y < iOffY || y >= iOffY + (int)image.GetHeight())
- {
- rgb.rgbBlue = 0; rgb.rgbGreen = 0; rgb.rgbRed = 0; rgb.rgbReserved = 0;
- }
- else
- {
- rgb = image.GetPixelColor(x - iOffX, y - iOffY);
- rgb.rgbReserved = 255;
- }
- folderimage.SetPixelColor(x + j*iWidth, y + (1 - i)*iHeight, rgb, true);
- }
- }
- }
- else
- bBlank = true;
- }
- else
- bBlank = true;
- }
- if (bBlank)
- { // no image - just fill with black alpha
- for (int x = 0; x < iWidth; x++)
- {
- for (int y = 0; y < iHeight; y++)
- {
- RGBQUAD rgb;
- rgb.rgbBlue = 0; rgb.rgbGreen = 0; rgb.rgbRed = 0; rgb.rgbReserved = 0;
- folderimage.SetPixelColor(x + j*iWidth, y + (1 - i)*iHeight, rgb, true);
- }
- }
- }
- }
- }
- ::DeleteFile(thumb);
- if (!folderimage.Save(thumb, CXIMAGE_FORMAT_PNG))
+ // ok, now resample the image down if necessary
+ if (ResampleKeepAspect(*image, maxwidth, maxheight) < 0)
{
- printf("Unable to save thumb file");
- ::DeleteFile(thumb);
+ printf("PICTURE::LoadImage: Unable to resample picture\n");
+ delete image;
return false;
}
- return true;
- };
+ // 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 CreateThumbnailFromSurface(BYTE *buffer, unsigned int width, unsigned int height, unsigned int stride, const char *thumb)
{
@@ -549,53 +330,6 @@ extern "C"
}
return true;
};
- __declspec(dllexport) int ConvertFile(const char *srcfile, const char *destfile, float rotateDegrees, int destwidth, int destheight, unsigned int destquality, bool mirror)
- {
- if (!srcfile || !destfile || (destwidth ==-1 && destheight==-1)) return false;
- DWORD dwImageType = GetImageType(srcfile);
- DWORD dwDestImageType = GetImageType(destfile);
- CxImage image(dwImageType);
- try
- {
- if (!image.Load(srcfile, dwImageType) || !image.IsValid())
- {
- printf("PICTURE::ConvertFile: Unable to open image: %s Error:%s\n", srcfile, image.GetLastError());
- return 7;
- }
- }
- catch (...)
- {
- printf("PICTURE::ConvertFile: Unable to open image: %s\n", srcfile);
- return 2;
- }
- if (destheight==-1) {
- destheight = (int) ((float)destwidth * ((float)image.GetHeight()/ (float)image.GetWidth())) ;
- }
- if (destwidth==-1)
- destwidth = (int) ((float)destheight * ((float)image.GetWidth()/(float)image.GetHeight())) ;
- if (!image.Resample(destwidth, destheight, RESAMPLE_QUALITY) || !image.IsValid())
- {
- printf("PICTURE::ConvertFile: Unable to resample picture: Error:%s\n", image.GetLastError());
- return 3;
- }
- if (!rotateDegrees==0.0)
- if (!image.Rotate(rotateDegrees) || !image.IsValid())
- {
- printf("PICTURE::ConvertFile: Unable to rotate picture: Error:%s\n", image.GetLastError());
- return 4;
- }
- if (mirror)
- image.Mirror(false,false);
- if (dwDestImageType==CXIMAGE_FORMAT_JPG)
- image.SetJpegQuality(destquality);
- if (!image.Save(destfile, dwDestImageType))
- {
- printf("PICTURE::ConvertFile: Unable to save image: %s Error:%s\n", destfile, image.GetLastError());
- ::DeleteFile(destfile);
- return 5;
- }
- return 0;
- };
}
#endif
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
1  xbmc/Application.cpp
@@ -28,7 +28,6 @@
#include "input/KeyboardLayoutConfiguration.h"
#include "LangInfo.h"
#include "Util.h"
-#include "pictures/Picture.h"
#include "guilib/TextureManager.h"
#include "cores/dvdplayer/DVDFileInfo.h"
#include "cores/AudioEngine/AEFactory.h"
View
2  xbmc/ApplicationMessenger.cpp
@@ -828,7 +828,7 @@ void CApplicationMessenger::MediaPlay(string filename)
{
CFileItem item(filename, false);
if (item.IsAudio())
- item.SetMusicThumb();
+ CMusicThumbLoader::FillThumb(item);
else
CVideoThumbLoader::FillThumb(item);
item.FillInDefaultIcon();
View
205 xbmc/FileItem.cpp
@@ -24,7 +24,6 @@
#include "utils/StringUtils.h"
#include "utils/URIUtils.h"
#include "Util.h"
-#include "pictures/Picture.h"
#include "playlists/PlayListFactory.h"
#include "utils/Crc32.h"
#include "filesystem/DirectoryCache.h"
@@ -55,7 +54,6 @@
#include "utils/log.h"
#include "utils/Variant.h"
#include "music/karaoke/karaokelyricsfactory.h"
-#include "ThumbnailCache.h"
#include "utils/Mime.h"
#include "utils/CharsetConverter.h"
@@ -91,10 +89,6 @@ CFileItem::CFileItem(const CStdString &path, const CAlbum& album)
m_strLabel2 = StringUtils::Join(album.artist, g_advancedSettings.m_musicItemSeparator);
URIUtils::AddSlashAtEnd(m_strPath);
GetMusicInfoTag()->SetAlbum(album);
- if (album.thumbURL.m_url.size() > 0)
- m_strThumbnailImage = album.thumbURL.m_url[0].m_url;
- else
- m_strThumbnailImage.clear();
m_bIsAlbum = true;
CMusicDatabase::SetPropertiesFromAlbum(*this,album);
}
@@ -110,7 +104,6 @@ CFileItem::CFileItem(const CMusicInfoTag& music)
m_bIsFolder = URIUtils::HasSlashAtEnd(m_strPath);
*GetMusicInfoTag() = music;
FillInDefaultIcon();
- SetCachedMusicThumb();
}
CFileItem::CFileItem(const CVideoInfoTag& movie)
@@ -1013,31 +1006,6 @@ void CFileItem::FillInDefaultIcon()
}
}
-CStdString CFileItem::GetCachedArtistThumb() const
-{
- return CThumbnailCache::GetArtistThumb(*this);
-}
-
-void CFileItem::SetCachedArtistThumb()
-{
- CStdString thumb(GetCachedArtistThumb());
- if (CFile::Exists(thumb))
- {
- // found it, we are finished.
- SetThumbnailImage(thumb);
- }
-}
-
-// set the album thumb for a file or folder
-void CFileItem::SetMusicThumb(bool alwaysCheckRemote /* = true */)
-{
- if (HasThumbnail()) return;
-
- SetCachedMusicThumb();
- if (!HasThumbnail())
- SetUserMusicThumb(alwaysCheckRemote);
-}
-
void CFileItem::RemoveExtension()
{
if (m_bIsFolder)
@@ -1829,21 +1797,6 @@ void CFileItemList::FillInDefaultIcons()
}
}
-void CFileItemList::SetMusicThumbs()
-{
- CSingleLock lock(m_lock);
- //cache thumbnails directory
- g_directoryCache.InitMusicThumbCache();
-
- for (int i = 0; i < (int)m_items.size(); ++i)
- {
- CFileItemPtr pItem = m_items[i];
- pItem->SetMusicThumb();
- }
-
- g_directoryCache.ClearMusicThumbCache();
-}
-
int CFileItemList::GetFolderCount() const
{
CSingleLock lock(m_lock);
@@ -1992,6 +1945,8 @@ void CFileItemList::FilterCueItems()
SYSTEMTIME dateTime;
tag.GetReleaseDate(dateTime);
if (dateTime.wYear) song.iYear = dateTime.wYear;
+ if (song.embeddedArt.empty() && !tag.GetCoverArtInfo().empty())
+ song.embeddedArt = tag.GetCoverArtInfo();
}
if (!song.iDuration && tag.GetDuration() > 0)
{ // must be the last song
@@ -2444,84 +2399,6 @@ bool CFileItemList::AlwaysCache() const
return false;
}
-void CFileItemList::SetCachedMusicThumbs()
-{
- CSingleLock lock(m_lock);
- // TODO: Investigate caching time to see if it speeds things up
- for (unsigned int i = 0; i < m_items.size(); ++i)
- {
- CFileItemPtr pItem = m_items[i];
- pItem->SetCachedMusicThumb();
- }
-}
-
-void CFileItem::SetCachedMusicThumb()
-{
- // if it already has a thumbnail, then return
- if (HasThumbnail() || m_bIsShareOrDrive) return ;
-
- // streams do not have thumbnails
- if (IsInternetStream()) return ;
-
- // music db items already have thumbs or there is no thumb available
- if (IsMusicDb()) return;
-
- // ignore the parent dir items
- if (IsParentFolder()) return;
-
- CStdString cachedThumb(GetPreviouslyCachedMusicThumb());
- if (!cachedThumb.IsEmpty())
- SetThumbnailImage(cachedThumb);
- // SetIconImage(cachedThumb);
-}
-
-CStdString CFileItem::GetPreviouslyCachedMusicThumb() const
-{
- // look if an album thumb is available,
- // could be any file with tags loaded or
- // a directory in album window
- CStdString strAlbum, strArtist;
- if (HasMusicInfoTag() && m_musicInfoTag->Loaded())
- {
- strAlbum = m_musicInfoTag->GetAlbum();
- if (!m_musicInfoTag->GetAlbumArtist().empty())
- strArtist = StringUtils::Join(m_musicInfoTag->GetAlbumArtist(), g_advancedSettings.m_musicItemSeparator);
- else
- strArtist = StringUtils::Join(m_musicInfoTag->GetArtist(), g_advancedSettings.m_musicItemSeparator);
- }
- if (!strAlbum.IsEmpty() && !strArtist.IsEmpty())
- {
- // try permanent album thumb using "album name + artist name"
- CStdString thumb(CThumbnailCache::GetAlbumThumb(strAlbum, strArtist));
- if (CFile::Exists(thumb))
- return thumb;
- }
-
- // if a file, try to find a cached filename.tbn
- if (!m_bIsFolder)
- {
- // look for locally cached tbn
- CStdString thumb(CThumbnailCache::GetMusicThumb(m_strPath));
- if (CFile::Exists(thumb))
- return thumb;
- }
-
- // try and find a cached folder thumb (folder.jpg or folder.tbn)
- CStdString strPath;
- if (!m_bIsFolder)
- URIUtils::GetDirectory(m_strPath, strPath);
- else
- strPath = m_strPath;
- // music thumbs are cached without slash at end
- URIUtils::RemoveSlashAtEnd(strPath);
-
- CStdString thumb(CThumbnailCache::GetMusicThumb(strPath));
- if (CFile::Exists(thumb))
- return thumb;
-
- return "";
-}
-
CStdString CFileItem::GetUserMusicThumb(bool alwaysCheckRemote /* = false */) const
{
if (m_strPath.IsEmpty()
@@ -2554,37 +2431,10 @@ CStdString CFileItem::GetUserMusicThumb(bool alwaysCheckRemote /* = false */) co
}
}
}
- // this adds support for files which inherit a folder.jpg icon which has not been cached yet.
- // this occurs when queueing a top-level folder which has not been traversed yet.
- else if (!IsRemote() || alwaysCheckRemote || g_guiSettings.GetBool("musicfiles.findremotethumbs"))
- {
- CStdString strFolder, strFile;
- URIUtils::Split(m_strPath, strFolder, strFile);
- if (!m_strPath.Equals(strFolder)) // any more parents to inherit from?
- {
- CFileItem folderItem(strFolder, true);
- folderItem.SetMusicThumb(alwaysCheckRemote);
- if (folderItem.HasThumbnail())
- return folderItem.GetThumbnailImage();
- }
- }
// No thumb found
return "";
}
-void CFileItem::SetUserMusicThumb(bool alwaysCheckRemote /* = false */)
-{
- // caches as the local thumb
- CStdString thumb(GetUserMusicThumb(alwaysCheckRemote));
- if (!thumb.IsEmpty())
- {
- CStdString cachedThumb(CThumbnailCache::GetMusicThumb(m_strPath));
- CPicture::CreateThumbnail(thumb, cachedThumb);
- }
-
- SetCachedMusicThumb();
-}
-
// Gets the .tbn filename from a file or folder name.
// <filename>.ext -> <filename>.tbn
// <foldername>/ -> <foldername>.tbn
@@ -2798,20 +2648,6 @@ bool CFileItem::testGetBaseMoviePath()
}
#endif
-bool CFileItem::CacheLocalFanart() const
-{
- // first check for an already cached fanart image
- CStdString cachedFanart(GetCachedFanart());
- if (CFile::Exists(cachedFanart))
- return true;
-
- // we don't have a cached image, so let's see if the user has a local image, and cache it if so
- CStdString localFanart(GetLocalFanart());
- if (!localFanart.IsEmpty())
- return CPicture::CacheFanart(localFanart, cachedFanart);
- return false;
-}
-
CStdString CFileItem::GetLocalFanart() const
{
if (IsVideoDb())
@@ -2912,43 +2748,6 @@ CStdString CFileItem::GetLocalMetadataPath() const
return parent;
}
-CStdString CFileItem::GetCachedFanart() const
-{
- return CThumbnailCache::GetFanart(*this);
-}
-
-CStdString CFileItem::GetCachedThumb(const CStdString &path, const CStdString &path2, bool split)
-{
- return CThumbnailCache::GetThumb(path, path2, split);
-}
-
-/*void CFileItem::SetThumb()
-{
- // we need to know the type of file at this point
- // as differing views have differing inheritance rules for thumbs:
-
- // Videos:
- // Folders only use <foldername>/folder.jpg or <foldername>.tbn
- // Files use <filename>.tbn
- // * Thumbs are cached from here using file or folder path
-
- // Music:
- // Folders only use <foldername>/folder.jpg or <foldername>.tbn
- // Files use <filename>.tbn or the album/path cached thumb or inherit from the folder
- // * Thumbs are cached from here using file or folder path
-
- // Programs:
- // Folders only use <foldername>/folder.jpg or <foldername>.tbn
- // Files use <filename>.tbn or the embedded xbe. Shortcuts have the additional step of the <thumbnail> tag to check
- // * Thumbs are cached from here using file or folder path
-
- // Pictures:
- // Folders use <foldername>/folder.jpg or <foldername>.tbn, or auto-generated from 4 images in the folder
- // Files use <filename>.tbn or a resized version of the picture
- // * Thumbs are cached from here using file or folder path
-
-}*/
-
bool CFileItem::LoadMusicTag()
{
// not audio
View
33 xbmc/FileItem.h
@@ -153,7 +153,6 @@ class CFileItem :
void RemoveExtension();
void CleanString();
void FillInDefaultIcon();
- void SetMusicThumb(bool alwaysCheckRemote = false);
void SetFileSizeLabel();
virtual void SetLabel(const CStdString &strLabel);
CURL GetAsUrl() const;
@@ -200,33 +199,13 @@ class CFileItem :
CPictureInfoTag* GetPictureInfoTag();
- // Gets the cached thumb filename (no existence checks)
- CStdString GetCachedArtistThumb() const;
- /*!
- \brief Get the cached fanart path for this item if it exists
- \return path to the cached fanart for this item, or empty if none exists
- \sa CacheLocalFanart, GetLocalFanart
- */
- CStdString GetCachedFanart() const;
- static CStdString GetCachedThumb(const CStdString &path, const CStdString& strPath2, bool split=false);
-
- /*!
- \brief Cache a copy of the local fanart for this item if we don't already have an image cached
- \return true if we already have cached fanart or if the caching was successful, false if no image is cached.
- \sa GetLocalFanart, GetCachedFanart
- */
- bool CacheLocalFanart() const;
/*!
\brief Get the local fanart for this item if it exists
\return path to the local fanart for this item, or empty if none exists
- \sa CacheLocalFanart, GetCachedFanart
+ \sa GetFolderThumb, GetTBNFile
*/
CStdString GetLocalFanart() const;
- // Sets the cached thumb for the item if it exists
- void SetCachedArtistThumb();
- void SetCachedMusicThumb();
-
// Gets the .tbn file associated with this item
CStdString GetTBNFile() const;
// Gets the folder image associated with this item (defaults to folder.jpg)
@@ -251,9 +230,6 @@ class CFileItem :
CStdString GetUserVideoThumb() const;
CStdString GetUserMusicThumb(bool alwaysCheckRemote = false) const;
- // Caches the user thumb and assigns it to the item
- void SetUserMusicThumb(bool alwaysCheckRemote = false);
-
/*! \brief Get the path where we expect local metadata to reside.
For a folder, this is just the existing path (eg tvshow folder)
For a file, this is the parent path, with exceptions made for VIDEO_TS and BDMV files
@@ -296,11 +272,7 @@ class CFileItem :
bool IsSamePath(const CFileItem *item) const;
bool IsAlbum() const;
-private:
- // Gets the previously cached thumb file (with existence checks)
- CStdString GetPreviouslyCachedMusicThumb() const;
-public:
bool m_bIsShareOrDrive; ///< is this a root share/drive
int m_iDriveType; ///< If \e m_bIsShareOrDrive is \e true, use to get the share type. Types see: CMediaSource::m_iDriveType
CDateTime m_dateTime; ///< file creation date & time
@@ -405,7 +377,6 @@ class CFileItemList : public CFileItem
void Reserve(int iCount);
void Sort(SORT_METHOD sortMethod, SortOrder sortOrder);
void Randomize();
- void SetMusicThumbs();
void FillInDefaultIcons();
int GetFolderCount() const;
int GetFileCount() const;
@@ -464,8 +435,6 @@ class CFileItemList : public CFileItem
void RemoveDiscCache(int windowID = 0) const;
bool AlwaysCache() const;
- void SetCachedMusicThumbs();
-
void Swap(unsigned int item1, unsigned int item2);
/*! \brief Update an item in the item list
View
18 xbmc/GUIInfoManager.cpp
@@ -75,6 +75,7 @@
#include "addons/AddonManager.h"
#include "interfaces/info/InfoBool.h"
#include "TextureCache.h"
+#include "ThumbLoader.h"
#include "cores/AudioEngine/Utils/AEUtil.h"
#define SYSHEATUPDATEINTERVAL 60000
@@ -3118,8 +3119,8 @@ const CStdString CGUIInfoManager::GetMusicPlaylistInfo(const GUIInfo& info)
// try to set a thumbnail
if (!playlistItem->HasThumbnail())
{
- playlistItem->SetMusicThumb();
- // still no thumb? then just the set the default cover
+ CMusicThumbLoader::FillThumb(*playlistItem);
+ // still no thumb? then just the set the default cover TODO: remove me?
if (!playlistItem->HasThumbnail())
playlistItem->SetThumbnailImage("DefaultAlbumCover.png");
}
@@ -3544,18 +3545,15 @@ void CGUIInfoManager::SetCurrentSong(CFileItem &item)
{
CLog::Log(LOGDEBUG,"Streaming media detected... using %s to find a thumb", g_application.m_strPlayListFile.c_str());
CFileItem streamingItem(g_application.m_strPlayListFile,false);
- streamingItem.SetMusicThumb();
- CStdString strThumb = streamingItem.GetThumbnailImage();
- if (CFile::Exists(strThumb))
- m_currentFile->SetThumbnailImage(strThumb);
+ CMusicThumbLoader::FillThumb(streamingItem);
+ if (streamingItem.HasThumbnail())
+ m_currentFile->SetThumbnailImage(streamingItem.GetThumbnailImage());
}
}
else
- m_currentFile->SetMusicThumb();
- if (!m_currentFile->HasProperty("fanart_image"))
{
- if (m_currentFile->CacheLocalFanart())
- m_currentFile->SetProperty("fanart_image", m_currentFile->GetCachedFanart());
+ CMusicThumbLoader loader;
+ loader.LoadItem(m_currentFile);
}
m_currentFile->FillInDefaultIcon();
View
9 xbmc/GUILargeTextureManager.cpp
@@ -21,7 +21,6 @@
#include "threads/SystemClock.h"
#include "GUILargeTextureManager.h"
-#include "pictures/Picture.h"
#include "settings/GUISettings.h"
#include "FileItem.h"
#include "guilib/Texture.h"
@@ -64,14 +63,10 @@ bool CImageLoader::DoWork()
if (!loadPath.IsEmpty())
{
// direct route - load the image
- m_texture = new CTexture();
unsigned int start = XbmcThreads::SystemClockMillis();
- if (!m_texture->LoadFromFile(loadPath, g_graphicsContext.GetWidth(), g_graphicsContext.GetHeight(), g_guiSettings.GetBool("pictures.useexifrotation")))
- {
- delete m_texture;
- m_texture = NULL;
+ m_texture = CBaseTexture::LoadFromFile(loadPath, g_graphicsContext.GetWidth(), g_graphicsContext.GetHeight(), g_guiSettings.GetBool("pictures.useexifrotation"));
+ if (!m_texture)
return false;
- }
if (XbmcThreads::SystemClockMillis() - start > 100)
CLog::Log(LOGDEBUG, "%s - took %u ms to load %s", __FUNCTION__, XbmcThreads::SystemClockMillis() - start, loadPath.c_str());
View
56 xbmc/TextureCacheJob.cpp
@@ -33,6 +33,8 @@
#include "utils/StringUtils.h"
#include "URL.h"
#include "FileItem.h"
+#include "ThumbLoader.h"
+#include "music/tags/MusicInfoTag.h"
CTextureCacheJob::CTextureCacheJob(const CStdString &url, const CStdString &oldHash)
{
@@ -74,11 +76,11 @@ bool CTextureCacheJob::DoWork()
bool CTextureCacheJob::CacheTexture(CBaseTexture **out_texture)
{
// unwrap the URL as required
- bool flipped;
+ std::string additional_info;
unsigned int width, height;
- CStdString image = DecodeImageURL(m_url, width, height, flipped);
+ CStdString image = DecodeImageURL(m_url, width, height, additional_info);
- m_details.updateable = UpdateableURL(image);
+ m_details.updateable = additional_info != "music" && UpdateableURL(image);
// generate the hash
m_details.hash = GetImageHash(image);
@@ -87,7 +89,7 @@ bool CTextureCacheJob::CacheTexture(CBaseTexture **out_texture)
else if (m_details.hash == m_oldHash)
return true;
- CBaseTexture *texture = LoadImage(image, width, height, flipped);
+ CBaseTexture *texture = LoadImage(image, width, height, additional_info);
if (texture)
{
if (texture->HasAlpha())
@@ -95,12 +97,7 @@ bool CTextureCacheJob::CacheTexture(CBaseTexture **out_texture)
else
m_details.file = m_cachePath + ".jpg";
- if (width > 0 && height > 0)
- CLog::Log(LOGDEBUG, "%s image '%s' at %dx%d with orientation %d as '%s'", m_oldHash.IsEmpty() ? "Caching" : "Recaching", image.c_str(),
- width, height, texture->GetOrientation(), m_details.file.c_str());
- else
- CLog::Log(LOGDEBUG, "%s image '%s' fullsize with orientation %d as '%s'", m_oldHash.IsEmpty() ? "Caching" : "Recaching", image.c_str(),
- texture->GetOrientation(), m_details.file.c_str());
+ CLog::Log(LOGDEBUG, "%s image '%s' to '%s':", m_oldHash.IsEmpty() ? "Caching" : "Recaching", image.c_str(), m_details.file.c_str());
if (CPicture::CacheTexture(texture, width, height, CTextureCache::GetCachedPath(m_details.file)))
{
@@ -117,20 +114,24 @@ bool CTextureCacheJob::CacheTexture(CBaseTexture **out_texture)
return false;
}
-CStdString CTextureCacheJob::DecodeImageURL(const CStdString &url, unsigned int &width, unsigned int &height, bool &flipped)
+CStdString CTextureCacheJob::DecodeImageURL(const CStdString &url, unsigned int &width, unsigned int &height, std::string &additional_info)
{
// unwrap the URL as required
CStdString image(url);
- flipped = false;
- width = g_advancedSettings.m_fanartHeight * 16/9;
- height = g_advancedSettings.m_fanartHeight;
+ additional_info.clear();
+ width = height = 0;
if (url.compare(0, 8, "image://") == 0)
{
// format is image://[type@]<url_encoded_path>?options
CURL thumbURL(url);
if (!thumbURL.GetUserName().IsEmpty())
- return ""; // we don't re-cache special images (eg picturefolder/video embedded thumbs)
+ {
+ if (thumbURL.GetUserName() == "music")
+ additional_info = "music";
+ else
+ return ""; // we don't re-cache special images (eg picturefolder/video embedded thumbs)
+ }
image = thumbURL.GetHostName();
CURL::Decode(image);
@@ -156,35 +157,40 @@ CStdString CTextureCacheJob::DecodeImageURL(const CStdString &url, unsigned int
}
if (option == "size" && value == "thumb")
{
- width = height = g_advancedSettings.m_thumbSize;
+ width = height = g_advancedSettings.GetThumbSize();
}
else if (option == "flipped")
{
- flipped = true;
+ additional_info = "flipped";
}
}
}
return image;
}
-CBaseTexture *CTextureCacheJob::LoadImage(const CStdString &image, unsigned int width, unsigned int height, bool flipped)
+CBaseTexture *CTextureCacheJob::LoadImage(const CStdString &image, unsigned int width, unsigned int height, const std::string &additional_info)
{
+ if (additional_info == "music")
+ { // special case for embedded music images
+ MUSIC_INFO::EmbeddedArt art;
+ if (CMusicThumbLoader::GetEmbeddedThumb(image, art))
+ return CBaseTexture::LoadFromFileInMemory(&art.data[0], art.size, art.mime, width, height);
+ }
+
// Validate file URL to see if it is an image
CFileItem file(image, false);
if (!(file.IsPicture() && !(file.IsZIP() || file.IsRAR() || file.IsCBR() || file.IsCBZ() ))
&& !file.GetMimeType().Left(6).Equals("image/")) // ignore non-pictures
return NULL;
- CTexture *texture = new CTexture();
- if (!texture->LoadFromFile(image, width, height, g_guiSettings.GetBool("pictures.useexifrotation")))
- {
- delete texture;
+ CBaseTexture *texture = CBaseTexture::LoadFromFile(image, width, height, g_guiSettings.GetBool("pictures.useexifrotation"));
+ if (!texture)
return NULL;
- }
+
// EXIF bits are interpreted as: <flipXY><flipY*flipX><flipX>
// where to undo the operation we apply them in reverse order <flipX>*<flipY*flipX>*<flipXY>
- // When flipped = true we have an additional <flipX> on the left, which is equivalent to toggling the last bit
- if (flipped)
+ // When flipped we have an additional <flipX> on the left, which is equivalent to toggling the last bit
+ if (additional_info == "flipped")
texture->SetOrientation(texture->GetOrientation() ^ 1);
return texture;
View
8 xbmc/TextureCacheJob.h
@@ -100,10 +100,10 @@ class CTextureCacheJob : public CJob
\param url wrapped URL of the image
\param width width derived from URL
\param height height derived from URL
- \param flipped whether the image is flipped horizontally
+ \param additional_info additional information, such as "flipped" to flip horizontally
\return URL of the underlying image file.
*/
- static CStdString DecodeImageURL(const CStdString &url, unsigned int &width, unsigned int &height, bool &flipped);
+ static CStdString DecodeImageURL(const CStdString &url, unsigned int &width, unsigned int &height, std::string &additional_info);
/*! \brief Load an image at a given target size and orientation.
@@ -113,10 +113,10 @@ class CTextureCacheJob : public CJob
\param image the URL of the image file.
\param width the desired maximum width.
\param height the desired maximum height.
- \param flipped whether the image should be flipped horizontally.
+ \param additional_info extra info for loading, such as whether to flip horizontally.
\return a pointer to a CBaseTexture object, NULL if failed.
*/
- static CBaseTexture *LoadImage(const CStdString &image, unsigned int width, unsigned int height, bool flipped);
+ static CBaseTexture *LoadImage(const CStdString &image, unsigned int width, unsigned int height, const std::string &additional_info);
CStdString m_cachePath;
};
View
137 xbmc/ThumbLoader.cpp
@@ -23,7 +23,6 @@
#include "ThumbLoader.h"
#include "utils/URIUtils.h"
#include "URL.h"
-#include "pictures/Picture.h"
#include "filesystem/File.h"
#include "filesystem/DirectoryCache.h"
#include "FileItem.h"
@@ -37,10 +36,15 @@
#include "video/VideoDatabase.h"
#include "cores/dvdplayer/DVDFileInfo.h"
#include "video/VideoInfoScanner.h"
+#include "music/tags/MusicInfoTag.h"
+#include "music/tags/MusicInfoTagLoaderFactory.h"
+#include "music/infoscanner/MusicInfoScanner.h"
+#include "music/Artist.h"
using namespace XFILE;
using namespace std;
using namespace VIDEO;
+using namespace MUSIC_INFO;
CThumbLoader::CThumbLoader(int nThreads) :
CBackgroundInfoLoader(nThreads)
@@ -295,6 +299,22 @@ bool CVideoThumbLoader::FillLibraryArt(CFileItem *pItem)
m_database->Open();
if (m_database->GetArtForItem(tag.m_iDbId, tag.m_type, artwork))
pItem->SetArt(artwork);
+ else if (pItem->GetVideoInfoTag()->m_type == "artist")
+ { // we retrieve music video art from the music database (no backward compat)
+ CMusicDatabase database;
+ database.Open();
+ int idArtist = database.GetArtistByName(pItem->GetLabel());
+ if (database.GetArtForItem(idArtist, "artist", artwork))
+ pItem->SetArt(artwork);
+ }
+ else if (pItem->GetVideoInfoTag()->m_type == "album")
+ { // we retrieve music video art from the music database (no backward compat)
+ CMusicDatabase database;
+ database.Open();
+ int idAlbum = database.GetAlbumByName(pItem->GetLabel(), pItem->GetVideoInfoTag()->m_artist);
+ if (database.GetArtForItem(idAlbum, "album", artwork))
+ pItem->SetArt(artwork);
+ }
else
{
if (tag.m_type == "movie" || tag.m_type == "episode" ||
@@ -321,7 +341,7 @@ bool CVideoThumbLoader::FillLibraryArt(CFileItem *pItem)
pItem->SetArt(items[0]->GetArt());
}
}
- else if (tag.m_type == "actor" || tag.m_type == "artist" ||
+ else if (tag.m_type == "actor" ||
tag.m_type == "writer" || tag.m_type == "director")
{
// We can't realistically get the local thumbs (as we'd need to check every movie that contains this actor)
@@ -485,19 +505,126 @@ CStdString CProgramThumbLoader::GetLocalThumb(const CFileItem &item)
return "";
}
-CMusicThumbLoader::CMusicThumbLoader()
+CMusicThumbLoader::CMusicThumbLoader() : CThumbLoader(1)
{
+ m_database = new CMusicDatabase;
}
CMusicThumbLoader::~CMusicThumbLoader()
{
+ delete m_database;
+}
+
+void CMusicThumbLoader::OnLoaderStart()
+{
+ m_database->Open();
+}
+
+void CMusicThumbLoader::OnLoaderFinish()
+{
+ m_database->Close();
}
bool CMusicThumbLoader::LoadItem(CFileItem* pItem)
{
- if (pItem->m_bIsShareOrDrive) return true;
+ if (pItem->m_bIsShareOrDrive)
+ return true;
+
+ if (pItem->HasMusicInfoTag() && pItem->GetArt().empty())
+ {
+ if (FillLibraryArt(*pItem))
+ return true;
+ if (pItem->GetMusicInfoTag()->GetType() == "artist")
+ return true; // no fallback
+ }
+
+ if (!pItem->HasProperty("fanart_image"))
+ {
+ if (pItem->HasMusicInfoTag() && !pItem->GetMusicInfoTag()->GetArtist().empty())
+ {
+ std::string artist = pItem->GetMusicInfoTag()->GetArtist()[0];
+ m_database->Open();
+ int idArtist = m_database->GetArtistByName(artist);
+ if (idArtist >= 0)
+ {
+ string fanart = m_database->GetArtForItem(idArtist, "artist", "fanart");
+ if (!fanart.empty())
+ pItem->SetProperty("fanart_image", fanart);
+ }
+ m_database->Close();
+ }
+ }
+
if (!pItem->HasThumbnail())
- pItem->SetUserMusicThumb();
+ FillThumb(*pItem);
+
return true;
}
+bool CMusicThumbLoader::FillThumb(CFileItem &item)
+{
+ if (item.HasThumbnail())
+ return true;
+ CStdString thumb = GetCachedImage(item, "thumb");
+ if (thumb.IsEmpty())
+ {
+ thumb = item.GetUserMusicThumb();
+ if (!thumb.IsEmpty())
+ SetCachedImage(item, "thumb", thumb);
+ }
+ item.SetThumbnailImage(thumb);
+ return !thumb.IsEmpty();
+}
+
+bool CMusicThumbLoader::FillLibraryArt(CFileItem &item)
+{
+ CMusicInfoTag &tag = *item.GetMusicInfoTag();
+ if (tag.GetDatabaseId() > -1 && !tag.GetType().empty())
+ {
+ m_database->Open();
+ map<string, string> artwork;
+ if (m_database->GetArtForItem(tag.GetDatabaseId(), tag.GetType(), artwork))
+ item.SetArt(artwork);
+ else if (tag.GetType() == "song")
+ { // no art for the song, try the album
+ if (m_database->GetArtForItem(tag.GetAlbumId(), "album", artwork))
+ item.SetArt(artwork);
+ }
+ else if (tag.GetType() == "artist")
+ {
+ { // Need the artist thumb/fanart which isn't grabbed during normal directory fetches
+ CArtist artist;
+ m_database->GetArtistInfo(tag.GetDatabaseId(), artist, false);
+ CMusicInfoScanner scanner;
+ artwork = scanner.GetArtistArtwork(tag.GetDatabaseId(), &artist);
+ item.SetArt(artwork);
+ }
+ // add to the database for next time around
+ map<string, string> artwork = item.GetArt();
+ if (!artwork.empty())
+ {
+ m_database->SetArtForItem(tag.GetDatabaseId(), tag.GetType(), artwork);
+ for (map<string, string>::iterator i = artwork.begin(); i != artwork.end(); ++i)
+ CTextureCache::Get().BackgroundCacheImage(i->second);
+ }
+ else // nothing found - set an empty thumb so that next time around we don't hit here again
+ m_database->SetArtForItem(tag.GetDatabaseId(), tag.GetType(), "thumb", "");
+ }
+ if (tag.GetType() == "song" || tag.GetType() == "album")
+ { // fanart from the artist
+ item.SetProperty("fanart_image", m_database->GetArtistArtForItem(tag.GetDatabaseId(), tag.GetType(), "fanart"));
+ }
+ m_database->Close();
+ }
+ return !item.GetArt().empty();
+}
+
+bool CMusicThumbLoader::GetEmbeddedThumb(const std::string &path, EmbeddedArt &art)
+{
+ auto_ptr<IMusicInfoTagLoader> pLoader (CMusicInfoTagLoaderFactory::CreateLoader(path));
+ CMusicInfoTag tag;
+ if (NULL != pLoader.get())
+ pLoader->Load(path, tag, &art);
+
+ return !art.empty();
+}
View
28 xbmc/ThumbLoader.h
@@ -30,6 +30,7 @@
class CStreamDetails;
class IStreamDetailsObserver;
class CVideoDatabase;
+class CMusicDatabase;
/*!
\ingroup thumbs,jobs
@@ -155,11 +156,38 @@ class CProgramThumbLoader : public CThumbLoader
static CStdString GetLocalThumb(const CFileItem &item);
};
+namespace MUSIC_INFO
+{
+ class EmbeddedArt;
+};
+
class CMusicThumbLoader : public CThumbLoader
{
public:
CMusicThumbLoader();
virtual ~CMusicThumbLoader();
virtual bool LoadItem(CFileItem* pItem);
+
+ /*! \brief helper function to fill the art for a video library item
+ \param item a video CFileItem
+ \return true if we fill art, false otherwise
+ */
+ bool FillLibraryArt(CFileItem &item);
+
+ /*! \brief Fill the thumb of a music file/folder item
+ First uses a cached thumb from a previous run, then checks for a local thumb
+ and caches it for the next run
+ \param item the CFileItem object to fill
+ \return true if we fill the thumb, false otherwise
+ */
+ static bool FillThumb(CFileItem &item);
+
+ static bool GetEmbeddedThumb(const std::string &path, MUSIC_INFO::EmbeddedArt &art);
+
+protected:
+ virtual void OnLoaderStart();
+ virtual void OnLoaderFinish();
+
+ CMusicDatabase *m_database;
};
#endif
View
162 xbmc/ThumbnailCache.cpp
@@ -60,165 +60,3 @@ CThumbnailCache* CThumbnailCache::GetThumbnailCache()
return m_pCacheInstance;
}
-
-bool CThumbnailCache::ThumbExists(const CStdString& strFileName, bool bAddCache /*=false*/)
-{
- CSingleLock lock (m_cs);
-
- if (strFileName.size() == 0) return false;
- map<CStdString, bool>::iterator it;
- it = m_Cache.find(strFileName);
- if (it != m_Cache.end())
- return it->second;
-
- bool bExists = CFile::Exists(strFileName);
-
- if (bAddCache)
- Add(strFileName, bExists);
- return bExists;
-}
-
-bool CThumbnailCache::IsCached(const CStdString& strFileName)
-{
- CSingleLock lock (m_cs);
-
- map<CStdString, bool>::iterator it;
- it = m_Cache.find(strFileName);
- return it != m_Cache.end();
-}
-
-void CThumbnailCache::Clear()
-{
- CSingleLock lock (m_cs);
-
- if (m_pCacheInstance != NULL)
- {
- m_Cache.erase(m_Cache.begin(), m_Cache.end());
- delete m_pCacheInstance;
- }
-
- m_pCacheInstance = NULL;
-}
-
-void CThumbnailCache::Add(const CStdString& strFileName, bool bExists)
-{
- CSingleLock lock (m_cs);
-
- map<CStdString, bool>::iterator it;
- it = m_Cache.find(strFileName);
- if (it != m_Cache.end())
- it->second = bExists;
- else
- m_Cache.insert(pair<CStdString, bool>(strFileName, bExists));
-}
-
-CStdString CThumbnailCache::GetAlbumThumb(const CFileItem &item)
-{
- return GetAlbumThumb(item.GetMusicInfoTag());
-}
-
-CStdString CThumbnailCache::GetAlbumThumb(const CMusicInfoTag *musicInfo)
-{
- if (!musicInfo)
- return CStdString();
-
- return GetAlbumThumb(musicInfo->GetAlbum(), StringUtils::Join(!musicInfo->GetAlbumArtist().empty() ? musicInfo->GetAlbumArtist() : musicInfo->GetArtist(), g_advancedSettings.m_musicItemSeparator));
-}
-
-CStdString CThumbnailCache::GetAlbumThumb(const CAlbum &album)
-{
- return GetAlbumThumb(album.strAlbum, StringUtils::Join(album.artist, g_advancedSettings.m_musicItemSeparator));
-}
-
-CStdString CThumbnailCache::GetAlbumThumb(const CStdString& album, const CStdString& artist)
-{
- if (album.IsEmpty())
- return GetMusicThumb("unknown" + artist);
- if (artist.IsEmpty())
- return GetMusicThumb(album + "unknown");
- return GetMusicThumb(album + artist);
-}
-
-CStdString CThumbnailCache::GetArtistThumb(const CFileItem &item)
-{
- return GetArtistThumb(item.GetLabel());
-}
-
-CStdString CThumbnailCache::GetArtistThumb(const CArtist &artist)
-{
- return GetArtistThumb(artist.strArtist);
-}
-
-CStdString CThumbnailCache::GetArtistThumb(const CStdString &label)
-{
- return GetThumb("artist" + label, g_settings.GetMusicArtistThumbFolder());
-}
-
-CStdString CThumbnailCache::GetFanart(const CFileItem &item)
-{
- // get the locally cached thumb
- if (item.IsVideoDb() || (item.HasVideoInfoTag() && !item.GetVideoInfoTag()->IsEmpty()))
- {
- if (!item.HasVideoInfoTag())
- return "";
- if (!item.GetVideoInfoTag()->m_artist.empty())
- return GetThumb(StringUtils::Join(item.GetVideoInfoTag()->m_artist, g_advancedSettings.m_videoItemSeparator),g_settings.GetMusicFanartFolder());
- if (!item.m_bIsFolder && !item.GetVideoInfoTag()->m_strShowTitle.IsEmpty())
- {
- CStdString showPath;
- if (!item.GetVideoInfoTag()->m_strShowPath.IsEmpty())
- showPath = item.GetVideoInfoTag()->m_strShowPath;
- else
- {
- CVideoDatabase database;
- database.Open();
- int iShowId = item.GetVideoInfoTag()->m_iIdShow;
- if (iShowId <= 0)
- iShowId = database.GetTvShowId(item.GetVideoInfoTag()->m_strPath);
- CStdString showPath;
- database.GetFilePathById(iShowId,showPath,VIDEODB_CONTENT_TVSHOWS);
- }
- return GetThumb(showPath,g_settings.GetVideoFanartFolder());
- }
- CStdString path = item.GetVideoInfoTag()->GetPath();
- if (path.empty())
- return "";
- return GetThumb(path,g_settings.GetVideoFanartFolder());
- }
- if (item.HasMusicInfoTag())
- return GetThumb(StringUtils::Join(item.GetMusicInfoTag()->GetArtist(), g_advancedSettings.m_musicItemSeparator),g_settings.GetMusicFanartFolder());
-
- return GetThumb(item.GetPath(),g_settings.GetVideoFanartFolder());
-}
-
-CStdString CThumbnailCache::GetThumb(const CStdString &path, const CStdString &path2, bool split /* = false */)
-{
- // get the locally cached thumb
- Crc32 crc;
- crc.ComputeFromLowerCase(path);
-
- CStdString thumb;
- if (split)
- {
- CStdString hex;
- hex.Format("%08x", (__int32)crc);
- thumb.Format("%c\\%08x.tbn", hex[0], (unsigned __int32)crc);
- }
- else
- thumb.Format("%08x.tbn", (unsigned __int32)crc);
-
- return URIUtils::AddFileToFolder(path2, thumb);
-}
-
-CStdString CThumbnailCache::GetMusicThumb(const CStdString& path)
-{
- Crc32 crc;
- CStdString noSlashPath(path);
- URIUtils::RemoveSlashAtEnd(noSlashPath);
- crc.ComputeFromLowerCase(noSlashPath);
- CStdString hex;
- hex.Format("%08x", (unsigned __int32) crc);
- CStdString thumb;
- thumb.Format("%c/%s.tbn", hex[0], hex.c_str());
- return URIUtils::AddFileToFolder(g_settings.GetMusicThumbFolder(), thumb);
-}
View
16 xbmc/ThumbnailCache.h
@@ -42,26 +42,10 @@ class CThumbnailCache
virtual ~CThumbnailCache();
static CThumbnailCache* GetThumbnailCache();
- bool ThumbExists(const CStdString& strFileName, bool bAddCache = false);
- void Add(const CStdString& strFileName, bool bExists);
- void Clear();
- bool IsCached(const CStdString& strFileName);
- static CStdString GetMusicThumb(const CStdString &path);
- static CStdString GetAlbumThumb(const CFileItem &item);
- static CStdString GetAlbumThumb(const MUSIC_INFO::CMusicInfoTag *musicInfo);
- static CStdString GetAlbumThumb(const CAlbum &album);
- static CStdString GetAlbumThumb(const CStdString &album, const CStdString &artist);
- static CStdString GetArtistThumb(const CArtist &artist);
- static CStdString GetArtistThumb(const CFileItem &item);
- static CStdString GetArtistThumb(const CStdString &label);
- static CStdString GetFanart(const CFileItem &item);
- static CStdString GetThumb(const CStdString &path, const CStdString &path2, bool split = false);
protected:
static CThumbnailCache* m_pCacheInstance;
- std::map<CStdString, bool> m_Cache;
-
static CCriticalSection m_cs;
};
View
21 xbmc/Util.cpp
@@ -48,7 +48,6 @@
#include "filesystem/DirectoryCache.h"
#include "filesystem/SpecialProtocol.h"
#include "filesystem/RSSDirectory.h"
-#include "ThumbnailCache.h"
#ifdef HAS_FILESYSTEM_RAR
#include "filesystem/RarManager.h"
#endif
@@ -771,26 +770,6 @@ int64_t CUtil::ToInt64(uint32_t high, uint32_t low)
return n;
}
-bool CUtil::ThumbExists(const CStdString& strFileName, bool bAddCache)
-{
- return CThumbnailCache::GetThumbnailCache()->ThumbExists(strFileName, bAddCache);
-}
-
-void CUtil::ThumbCacheAdd(const CStdString& strFileName, bool bFileExists)
-{
- CThumbnailCache::GetThumbnailCache()->Add(strFileName, bFileExists);
-}
-
-void CUtil::ThumbCacheClear()
-{
- CThumbnailCache::GetThumbnailCache()->Clear();
-}
-
-bool CUtil::ThumbCached(const CStdString& strFileName)
-{
- return CThumbnailCache::GetThumbnailCache()->IsCached(strFileName);
-}
-
CStdString CUtil::GetNextFilename(const CStdString &fn_template, int max)
{
if (!fn_template.Find("%03d"))
View
4 xbmc/Util.h
@@ -87,10 +87,6 @@ class CUtil
static bool FindVobSubPair( const std::vector<CStdString>& vecSubtitles, const CStdString& strIdxPath, CStdString& strSubPath );
static bool IsVobSub( const std::vector<CStdString>& vecSubtitles, const CStdString& strSubPath );
static int64_t ToInt64(uint32_t high, uint32_t low);
- static bool ThumbExists(const CStdString& strFileName, bool bAddCache = false);
- static bool ThumbCached(const CStdString& strFileName);
- static void ThumbCacheAdd(const CStdString& strFileName, bool bFileExists);
- static void ThumbCacheClear();
static CStdString GetNextFilename(const CStdString &fn_template, int max);
static CStdString GetNextPathname(const CStdString &path_template, int max);
static void TakeScreenshot();
View
4 xbmc/cores/dvdplayer/DVDFileInfo.cpp
@@ -219,11 +219,11 @@ bool CDVDFileInfo::ExtractThumb(const CStdString &strPath, CTextureDetails &deta
if (iDecoderState & VC_PICTURE && !(picture.iFlags & DVP_FLAG_DROPPED))
{
{
- unsigned int nWidth = g_advancedSettings.m_thumbSize;
+ unsigned int nWidth = g_advancedSettings.GetThumbSize();
double aspect = (double)picture.iDisplayWidth / (double)picture.iDisplayHeight;
if(hint.forced_aspect && hint.aspect != 0)
aspect = hint.aspect;
- unsigned int nHeight = (unsigned int)((double)g_advancedSettings.m_thumbSize / aspect);
+ unsigned int nHeight = (unsigned int)((double)g_advancedSettings.GetThumbSize() / aspect);
DllSwScale dllSwScale;
dllSwScale.Load();
View
21 xbmc/dialogs/GUIDialogContextMenu.cpp
@@ -44,7 +44,6 @@
#include "guilib/LocalizeStrings.h"
#include "TextureCache.h"
#include "video/windows/GUIWindowVideoBase.h"
-#include "ThumbnailCache.h"
#ifdef _WIN32
#include "WIN32Util.h"
@@ -544,22 +543,10 @@ bool CGUIDialogContextMenu::OnContextButton(const CStdString &type, const CFileI
g_settings.SaveSources();
}
else if (!strThumb.IsEmpty())
- { // this is some sort of an auto-share, so we have to cache it based on the criteria we use to retrieve them
- CStdString cachedThumb;
- if (type == "music")
- {
- cachedThumb = item->GetPath();
- URIUtils::RemoveSlashAtEnd(cachedThumb);
- cachedThumb = CThumbnailCache::GetMusicThumb(cachedThumb);
- }
- else // programs, video, pictures
- { // store the thumb for this share
- CTextureDatabase db;
- if (db.Open())
- db.SetTextureForPath(item->GetPath(), "thumb", strThumb);
- }
- if (!cachedThumb.IsEmpty())
- XFILE::CFile::Cache(strThumb, cachedThumb);
+ { // this is some sort of an auto-share, so store in the texture database
+ CTextureDatabase db;
+ if (db.Open())
+ db.SetTextureForPath(item->GetPath(), "thumb", strThumb);
}
CGUIMessage msg(GUI_MSG_NOTIFY_ALL,0,0,GUI_MSG_UPDATE_SOURCES);
View
116 xbmc/filesystem/DirectoryCache.cpp
@@ -50,8 +50,6 @@ void CDirectoryCache::CDir::SetLastAccess(unsigned int &accessCounter)
CDirectoryCache::CDirectoryCache(void)
{
- m_iThumbCacheRefCount = 0;
- m_iMusicThumbCacheRefCount = 0;
m_accessCounter = 0;
#ifdef _DEBUG
m_cacheHits = 0;
@@ -202,17 +200,12 @@ bool CDirectoryCache::FileExists(const CStdString& strFile, bool& bInCache)
void CDirectoryCache::Clear()
{
- // this routine clears everything except things we always cache
+ // this routine clears everything
CSingleLock lock (m_cs);
iCache i = m_cache.begin();
while (i != m_cache.end() )
- {
- if (!IsCacheDir(i->first))
- Delete(i++);
- else
- i++;
- }
+ Delete(i++);
}
void CDirectoryCache::InitCache(set<CStdString>& dirs)
@@ -239,98 +232,6 @@ void CDirectoryCache::ClearCache(set<CStdString>& dirs)
}
}
-bool CDirectoryCache::IsCacheDir(const CStdString &strPath) const
-{
- if (m_thumbDirs.find(strPath) == m_thumbDirs.end())
- return false;
- if (m_musicThumbDirs.find(strPath) == m_musicThumbDirs.end())
- return false;
-
- return true;
-}
-
-void CDirectoryCache::InitThumbCache()
-{
- CSingleLock lock (m_cs);
-
- if (m_iThumbCacheRefCount > 0)
- {
- m_iThumbCacheRefCount++;
- return ;
- }
- m_iThumbCacheRefCount++;
-
- // Init video, pictures cache directories
- if (m_thumbDirs.size() == 0)
- {
- // thumbnails directories
-/* m_thumbDirs.insert(g_settings.GetThumbnailsFolder());
- for (unsigned int hex=0; hex < 16; hex++)
- {
- CStdString strHex;
- strHex.Format("\\%x",hex);
- m_thumbDirs.insert(g_settings.GetThumbnailsFolder() + strHex);
- }*/
- }
-
- InitCache(m_thumbDirs);
-}
-
-void CDirectoryCache::ClearThumbCache()
-{
- CSingleLock lock (m_cs);
-
- if (m_iThumbCacheRefCount > 1)
- {
- m_iThumbCacheRefCount--;
- return ;
- }
-
- m_iThumbCacheRefCount--;
- ClearCache(m_thumbDirs);
-}
-
-void CDirectoryCache::InitMusicThumbCache()
-{
- CSingleLock lock (m_cs);
-
- if (m_iMusicThumbCacheRefCount > 0)
- {
- m_iMusicThumbCacheRefCount++;
- return ;
- }
- m_iMusicThumbCacheRefCount++;
-
- // Init music cache directories
- if (m_musicThumbDirs.size() == 0)
- {
- // music thumbnails directories
- for (int i = 0; i < 16; i++)
- {
- CStdString hex, folder;
- hex.Format("%x", i);
- URIUtils::AddFileToFolder(g_settings.GetMusicThumbFolder(), hex, folder);
- m_musicThumbDirs.insert(folder);
- }
- }
-
- InitCache(m_musicThumbDirs);
-}
-
-void CDirectoryCache::ClearMusicThumbCache()
-{
- CSingleLock lock (m_cs);
-
- if (m_iMusicThumbCacheRefCount > 1)
- {
- m_iMusicThumbCacheRefCount--;
- return ;
- }
-
- m_iMusicThumbCacheRefCount--;
- ClearCache(m_musicThumbDirs);
-}
-
void CDirectoryCache::CheckIfFull()
{
CSingleLock lock (m_cs);
@@ -342,7 +243,7 @@ void CDirectoryCache::CheckIfFull()
for (iCache i = m_cache.begin(); i != m_cache.end(); i++)
{
// ensure dirs that are always cached aren't cleared
- if (!IsCacheDir(i->first) && i->second->m_cacheType != DIR_CACHE_ALWAYS)
+ if (i->second->m_cacheType != DIR_CACHE_ALWAYS)
{
if (lastAccessed == m_cache.end() || i->second->GetLastAccess() < lastAccessed->second->GetLastAccess())
lastAccessed = i;
@@ -371,13 +272,10 @@ void CDirectoryCache::PrintStats() const
unsigned int numDirs = 0;
for (ciCache i = m_cache.begin(); i != m_cache.end(); i++)
{
- if (!IsCacheDir(i->first))
- {
- CDir *dir = i->second;
- oldest = min(oldest, dir->GetLastAccess());
- numItems += dir->m_Items->Size();
- numDirs++;
- }
+ CDir *dir = i->second;
+ oldest = min(oldest, dir->GetLastAccess());
+ numItems += dir->m_Items->Size();
+ numDirs++;
}
CLog::Log(LOGDEBUG, "%s - %u folders cached, with %u items total. Oldest is %u, current is %u", __FUNCTION__, numDirs, numItems, oldest, m_accessCounter);
}
View
9 xbmc/filesystem/DirectoryCache.h
@@ -58,17 +58,12 @@ namespace XFILE
void Clear();
void AddFile(const CStdString& strFile);
bool FileExists(const CStdString& strPath, bool& bInCache);
- void InitThumbCache();
- void ClearThumbCache();
- void InitMusicThumbCache();
- void ClearMusicThumbCache();
#ifdef _DEBUG
void PrintStats() const;
#endif
protected:
void InitCache(std::set<CStdString>& dirs);
void ClearCache(std::set<CStdString>& dirs);
- bool IsCacheDir(const CStdString &strPath) const;
void CheckIfFull();
std::map<CStdString, CDir*> m_cache;
@@ -77,10 +72,6 @@ namespace XFILE
void Delete(iCache i);
CCriticalSection m_cs;
- std::set<CStdString> m_thumbDirs;
- std::set<CStdString> m_musicThumbDirs;
- int m_iThumbCacheRefCount;
- int m_iMusicThumbCacheRefCount;
unsigned int m_accessCounter;
View
16 xbmc/guilib/JpegIO.cpp
@@ -23,8 +23,7 @@
#include "lib/libexif/libexif.h"
#include "windowing/WindowingFactory.h"
-#include "settings/GUISettings.h"
-#include "settings/Settings.h"
+#include "settings/AdvancedSettings.h"
#include "filesystem/File.h"
#include "utils/log.h"
#include "XBTF.h"
@@ -312,9 +311,18 @@ bool CJpegIO::Read(unsigned char* buffer, unsigned int bufSize, unsigned int min
the gpu can hold, use the previous one.*/
if (minx == 0 || miny == 0)
{
- minx = g_settings.m_ResInfo[g_guiSettings.m_LookAndFeelResolution].iWidth;
- miny = g_settings.m_ResInfo[g_guiSettings.m_LookAndFeelResolution].iHeight;
+ miny = g_advancedSettings.m_imageRes;
+ if (g_advancedSettings.m_fanartRes > g_advancedSettings.m_imageRes)
+ { // a separate fanart resolution is specified - check if the image is exactly equal to this res
+ if (m_cinfo.image_width == (unsigned int)g_advancedSettings.m_fanartRes * 16/9 &&
+ m_cinfo.image_height == (unsigned int)g_advancedSettings.m_fanartRes)
+ { // special case for fanart res
+ miny = g_advancedSettings.m_fanartRes;
+ }
+ }
+ minx = miny * 16/9;
}
+
m_cinfo.scale_denom = 8;
m_cinfo.out_color_space = JCS_RGB;
unsigned int maxtexsize = g_Windowing.GetMaxTextureSize();
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
88 xbmc/guilib/Texture.cpp
@@ -171,6 +171,24 @@ void CBaseTexture::ClampToEdge()
}
}
+CBaseTexture *CBaseTexture::LoadFromFile(const CStdString& texturePath, unsigned int idealWidth, unsigned int idealHeight, bool autoRotate)
+{
+ CTexture *texture = new CTexture();
+ if (texture->LoadFromFile(texturePath, idealWidth, idealHeight, autoRotate, NULL, NULL))
+ return texture;
+ delete texture;
+ 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)
{
@@ -223,15 +241,73 @@ bool CBaseTexture::LoadFromFile(const CStdString& texturePath, unsigned int maxW
return false;
}
+ if (originalWidth)
+ *originalWidth = image.originalwidth;
+ if (originalHeight)
+ *originalHeight = image.originalheight;
+
+ LoadFromImage(image, autoRotate);
+ dll.ReleaseImage(&image);
+
+ 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;
Allocate(image.width, image.height, XB_FMT_A8R8G8B8);
if (autoRotate && image.exifInfo.Orientation)
m_orientation = image.exifInfo.Orientation - 1;
- if (originalWidth)
- *originalWidth = image.originalwidth;
- if (originalHeight)
- *originalHeight = image.originalheight;
unsigned int dstPitch = GetPitch();
unsigned int srcPitch = ((image.width + 1)* 3 / 4) * 4; // bitmap row length is aligned to 4 bytes
@@ -270,11 +346,7 @@ bool CBaseTexture::LoadFromFile(const CStdString& texturePath, unsigned int maxW
dst += dstPitch;
}
}
- dll.ReleaseImage(&image);
-
ClampToEdge();
-
- return true;
}
bool CBaseTexture::LoadFromMemory(unsigned int width, unsigned int height, unsigned int pitch, unsigned int format, bool hasAlpha, unsigned char* pixels)
View
33 xbmc/guilib/Texture.h
@@ -33,6 +33,7 @@ struct COLOR {unsigned char b,g,r,x;}; // Windows GDI expects 4bytes per color
class CTexture;
class CGLTexture;
class CDXTexture;
+struct ImageInfo;
/*!
\ingroup textures
@@ -47,8 +48,33 @@ class CBaseTexture
virtual ~CBaseTexture();
- bool LoadFromFile(const CStdString& texturePath, unsigned int maxHeight = 0, unsigned int maxWidth = 0,
- bool autoRotate = false, unsigned int *originalWidth = NULL, unsigned int *originalHeight = NULL);
+ /*! \brief Load a texture from a file
+ Loads a texture from a file, 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 texturePath the path of the texture to load.
+ \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).
+ \param autoRotate whether the textures should be autorotated based on EXIF information (defaults to false).
+ \return a CBaseTexture pointer to the created texture - NULL if the texture failed to load.
+ */
+ 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);