Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

added an imagefactory to XBMC. The only libs currently are libjpeg-tu…

…rbo and cximage.
  • Loading branch information...
commit 4d1bea980280cb522c4fc9f183b3558f56dd0882 1 parent 156eb79
wsoltys authored
View
12 XBMC-ATV2.xcodeproj/project.pbxproj
@@ -123,6 +123,8 @@
DF402A95164462FC001C56B8 /* swig.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F502C09C160F421600C96C76 /* swig.cpp */; };
DF402A96164462FC001C56B8 /* XBPython.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F502C09E160F421600C96C76 /* XBPython.cpp */; };
DF402A97164462FC001C56B8 /* XBPyThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F502C0A0160F421600C96C76 /* XBPyThread.cpp */; };
+ DF404AA716B98E6300D8023E /* cximage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF404AA316B98E6300D8023E /* cximage.cpp */; };
+ DF404AA816B98E6300D8023E /* imagefactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF404AA516B98E6300D8023E /* imagefactory.cpp */; };
DF4485351400651B0069344B /* PipesManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF4485321400651B0069344B /* PipesManager.cpp */; };
DF4485381400654A0069344B /* AirTunesServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF4485361400654A0069344B /* AirTunesServer.cpp */; };
DF527780151BAFD600B5B63B /* WebSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF527777151BAFD600B5B63B /* WebSocket.cpp */; };
@@ -1317,6 +1319,10 @@
DF33C2AC15509C5A0046CDCB /* ilog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ilog.h; sourceTree = "<group>"; };
DF34890713FD96390026A711 /* GUIAction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUIAction.cpp; sourceTree = "<group>"; };
DF34890813FD96390026A711 /* GUIAction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUIAction.h; sourceTree = "<group>"; };
+ DF404AA316B98E6300D8023E /* cximage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cximage.cpp; sourceTree = "<group>"; };
+ DF404AA416B98E6300D8023E /* cximage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cximage.h; sourceTree = "<group>"; };
+ DF404AA516B98E6300D8023E /* imagefactory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = imagefactory.cpp; sourceTree = "<group>"; };
+ DF404AA616B98E6300D8023E /* imagefactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imagefactory.h; sourceTree = "<group>"; };
DF4485321400651B0069344B /* PipesManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PipesManager.cpp; sourceTree = "<group>"; };
DF4485331400651B0069344B /* PipesManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PipesManager.h; sourceTree = "<group>"; };
DF4485361400654A0069344B /* AirTunesServer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AirTunesServer.cpp; sourceTree = "<group>"; };
@@ -5027,6 +5033,8 @@
children = (
F56C74FE131EC152000AD0F6 /* AnimatedGif.cpp */,
F56C74A0131EC152000AD0F6 /* AnimatedGif.h */,
+ DF404AA316B98E6300D8023E /* cximage.cpp */,
+ DF404AA416B98E6300D8023E /* cximage.h */,
F56C7500131EC152000AD0F6 /* D3DResource.cpp */,
F56C74A2131EC152000AD0F6 /* D3DResource.h */,
F56C7501131EC152000AD0F6 /* DDSImage.cpp */,
@@ -5171,6 +5179,8 @@
F56C7543131EC152000AD0F6 /* GUIWrappingListContainer.cpp */,
F56C74E9131EC152000AD0F6 /* GUIWrappingListContainer.h */,
F56C74EA131EC152000AD0F6 /* IAudioDeviceChangedCallback.h */,
+ DF404AA516B98E6300D8023E /* imagefactory.cpp */,
+ DF404AA616B98E6300D8023E /* imagefactory.h */,
F56C74EB131EC152000AD0F6 /* IMsgTargetCallback.h */,
F56C7544131EC152000AD0F6 /* IWindowManagerCallback.cpp */,
F56C74EC131EC152000AD0F6 /* IWindowManagerCallback.h */,
@@ -7659,6 +7669,8 @@
DFB02E0816629E1900F37752 /* PyContext.cpp in Sources */,
DF07255216873553008DCAAD /* karaokevideobackground.cpp in Sources */,
DF07255516873565008DCAAD /* FFmpegVideoDecoder.cpp in Sources */,
+ DF404AA716B98E6300D8023E /* cximage.cpp in Sources */,
+ DF404AA816B98E6300D8023E /* imagefactory.cpp in Sources */,
5500731516A75A2700097786 /* UPnPPlayer.cpp in Sources */,
DF64FE6C16C07B2C00D028FB /* GUIViewControl.cpp in Sources */,
DF64FE6D16C07B2C00D028FB /* GUIViewState.cpp in Sources */,
View
16 XBMC-IOS.xcodeproj/project.pbxproj
@@ -124,6 +124,8 @@
DF402A83164462C3001C56B8 /* swig.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F502C076160F417B00C96C76 /* swig.cpp */; };
DF402A84164462C3001C56B8 /* XBPython.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F502C078160F417B00C96C76 /* XBPython.cpp */; };
DF402A85164462C3001C56B8 /* XBPyThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F502C07A160F417B00C96C76 /* XBPyThread.cpp */; };
+ DF404A9416B98E4A00D8023E /* cximage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF404A8F16B98E4A00D8023E /* cximage.cpp */; };
+ DF404A9516B98E4A00D8023E /* imagefactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF404A9216B98E4A00D8023E /* imagefactory.cpp */; };
DF448572140065E10069344B /* PipesManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF44856F140065E10069344B /* PipesManager.cpp */; };
DF4485751400662D0069344B /* AirTunesServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF4485731400662D0069344B /* AirTunesServer.cpp */; };
DF527757151BAF8200B5B63B /* WebSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF52774E151BAF8200B5B63B /* WebSocket.cpp */; };
@@ -1322,6 +1324,11 @@
DF33C29215509BF50046CDCB /* ilog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ilog.h; sourceTree = "<group>"; };
DF3488F613FD961A0026A711 /* GUIAction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUIAction.cpp; sourceTree = "<group>"; };
DF3488F713FD961A0026A711 /* GUIAction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUIAction.h; sourceTree = "<group>"; };
+ DF404A8F16B98E4A00D8023E /* cximage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cximage.cpp; sourceTree = "<group>"; };
+ DF404A9016B98E4A00D8023E /* cximage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cximage.h; sourceTree = "<group>"; };
+ DF404A9116B98E4A00D8023E /* iimage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iimage.h; sourceTree = "<group>"; };
+ DF404A9216B98E4A00D8023E /* imagefactory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = imagefactory.cpp; sourceTree = "<group>"; };
+ DF404A9316B98E4A00D8023E /* imagefactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imagefactory.h; sourceTree = "<group>"; };
DF44856F140065E10069344B /* PipesManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PipesManager.cpp; sourceTree = "<group>"; };
DF448570140065E10069344B /* PipesManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PipesManager.h; sourceTree = "<group>"; };
DF4485731400662D0069344B /* AirTunesServer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AirTunesServer.cpp; sourceTree = "<group>"; };
@@ -5386,6 +5393,8 @@
children = (
F56C84E1131F42E9000AD0F6 /* AnimatedGif.cpp */,
F56C8483131F42E9000AD0F6 /* AnimatedGif.h */,
+ DF404A8F16B98E4A00D8023E /* cximage.cpp */,
+ DF404A9016B98E4A00D8023E /* cximage.h */,
F56C84E3131F42E9000AD0F6 /* D3DResource.cpp */,
F56C8485131F42E9000AD0F6 /* D3DResource.h */,
F56C84E4131F42E9000AD0F6 /* DDSImage.cpp */,
@@ -5452,9 +5461,9 @@
F56C84A4131F42E9000AD0F6 /* GUIIncludes.h */,
F56C84FF131F42E9000AD0F6 /* GUIInfoTypes.cpp */,
F56C84A5131F42E9000AD0F6 /* GUIInfoTypes.h */,
+ DF02A831153373EC0084754E /* GUIKeyboard.h */,
DF830C9C15BB215500602BE6 /* GUIKeyboardFactory.cpp */,
DF830C9D15BB215500602BE6 /* GUIKeyboardFactory.h */,
- DF02A831153373EC0084754E /* GUIKeyboard.h */,
F56C8500131F42E9000AD0F6 /* GUILabel.cpp */,
F56C84A6131F42E9000AD0F6 /* GUILabel.h */,
F56C8501131F42E9000AD0F6 /* GUILabelControl.cpp */,
@@ -5530,6 +5539,9 @@
F56C8526131F42E9000AD0F6 /* GUIWrappingListContainer.cpp */,
F56C84CC131F42E9000AD0F6 /* GUIWrappingListContainer.h */,
F56C84CD131F42E9000AD0F6 /* IAudioDeviceChangedCallback.h */,
+ DF404A9116B98E4A00D8023E /* iimage.h */,
+ DF404A9216B98E4A00D8023E /* imagefactory.cpp */,
+ DF404A9316B98E4A00D8023E /* imagefactory.h */,
F56C84CE131F42E9000AD0F6 /* IMsgTargetCallback.h */,
F56C8527131F42E9000AD0F6 /* IWindowManagerCallback.cpp */,
F56C84CF131F42E9000AD0F6 /* IWindowManagerCallback.h */,
@@ -7688,6 +7700,8 @@
DFB02DFB16629DF200F37752 /* PyContext.cpp in Sources */,
DF07254116873517008DCAAD /* karaokevideobackground.cpp in Sources */,
DF0725441687352C008DCAAD /* FFmpegVideoDecoder.cpp in Sources */,
+ DF404A9416B98E4A00D8023E /* cximage.cpp in Sources */,
+ DF404A9516B98E4A00D8023E /* imagefactory.cpp in Sources */,
5500730E16A759D800097786 /* UPnPPlayer.cpp in Sources */,
DF64FE5616C07AF700D028FB /* GUIViewControl.cpp in Sources */,
DF64FE5716C07AF700D028FB /* GUIViewState.cpp in Sources */,
View
14 XBMC.xcodeproj/project.pbxproj
@@ -397,6 +397,8 @@
DF402A65164461B9001C56B8 /* swig.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F502BFF0160F36AD00C96C76 /* swig.cpp */; };
DF402A66164461B9001C56B8 /* XBPython.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F502BFE6160F34FE00C96C76 /* XBPython.cpp */; };
DF402A67164461B9001C56B8 /* XBPyThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F502BFE8160F34FE00C96C76 /* XBPyThread.cpp */; };
+ DF404A3916B9896C00D8023E /* cximage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF404A3416B9896C00D8023E /* cximage.cpp */; };
+ DF404A3A16B9896C00D8023E /* imagefactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF404A3716B9896C00D8023E /* imagefactory.cpp */; };
DF448457140048A60069344B /* AirTunesServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF448455140048A60069344B /* AirTunesServer.cpp */; };
DF44845E140048C80069344B /* PipesManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF44845B140048C80069344B /* PipesManager.cpp */; };
DF5276E1151BAEDA00B5B63B /* Base64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF52769A151BAEDA00B5B63B /* Base64.cpp */; };
@@ -1915,6 +1917,11 @@
DF34892913FD9C780026A711 /* AirPlayServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AirPlayServer.h; sourceTree = "<group>"; };
DF34897A13FDAA270026A711 /* HttpParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HttpParser.h; sourceTree = "<group>"; };
DF34898113FDAAF60026A711 /* HttpParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HttpParser.cpp; sourceTree = "<group>"; };
+ DF404A3416B9896C00D8023E /* cximage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cximage.cpp; sourceTree = "<group>"; };
+ DF404A3516B9896C00D8023E /* cximage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cximage.h; sourceTree = "<group>"; };
+ DF404A3616B9896C00D8023E /* iimage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iimage.h; sourceTree = "<group>"; };
+ DF404A3716B9896C00D8023E /* imagefactory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = imagefactory.cpp; sourceTree = "<group>"; };
+ DF404A3816B9896C00D8023E /* imagefactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imagefactory.h; sourceTree = "<group>"; };
DF448455140048A60069344B /* AirTunesServer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AirTunesServer.cpp; sourceTree = "<group>"; };
DF448456140048A60069344B /* AirTunesServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AirTunesServer.h; sourceTree = "<group>"; };
DF44845B140048C80069344B /* PipesManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PipesManager.cpp; sourceTree = "<group>"; };
@@ -3418,6 +3425,8 @@
children = (
18B7C7541294222E009E7A26 /* AnimatedGif.cpp */,
18B7C6F61294222D009E7A26 /* AnimatedGif.h */,
+ DF404A3416B9896C00D8023E /* cximage.cpp */,
+ DF404A3516B9896C00D8023E /* cximage.h */,
18B7C7561294222E009E7A26 /* D3DResource.cpp */,
18B7C6F81294222D009E7A26 /* D3DResource.h */,
18B7C7571294222E009E7A26 /* DDSImage.cpp */,
@@ -3562,6 +3571,9 @@
18B7C7991294222E009E7A26 /* GUIWrappingListContainer.cpp */,
18B7C73F1294222D009E7A26 /* GUIWrappingListContainer.h */,
18B7C7401294222D009E7A26 /* IAudioDeviceChangedCallback.h */,
+ DF404A3616B9896C00D8023E /* iimage.h */,
+ DF404A3716B9896C00D8023E /* imagefactory.cpp */,
+ DF404A3816B9896C00D8023E /* imagefactory.h */,
18B7C7411294222D009E7A26 /* IMsgTargetCallback.h */,
18B7C79A1294222E009E7A26 /* IWindowManagerCallback.cpp */,
18B7C7421294222D009E7A26 /* IWindowManagerCallback.h */,
@@ -7720,6 +7732,8 @@
DF64FE3D16C07AAA00D028FB /* GUIViewControl.cpp in Sources */,
DF64FE3E16C07AAA00D028FB /* GUIViewState.cpp in Sources */,
DF64FE4016C07AAA00D028FB /* ViewDatabase.cpp in Sources */,
+ DF404A3916B9896C00D8023E /* cximage.cpp in Sources */,
+ DF404A3A16B9896C00D8023E /* imagefactory.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
View
55 lib/cximage-6.0/CxImage/DllInterface.cpp
@@ -330,6 +330,61 @@ extern "C"
}
return true;
};
+
+ __declspec(dllexport) bool CreateThumbnailFromSurface2(BYTE * bufferin, unsigned int width, unsigned int height, unsigned int stride, const char *thumb,
+ BYTE * &bufferout, unsigned int &bufferoutSize)
+ {
+ if (!bufferin) return false;
+ // creates an image, and copies the surface data into it.
+ CxImage image(width, height, 24, CXIMAGE_FORMAT_PNG);
+ if (!image.IsValid()) return false;
+ image.AlphaCreate();
+ if (!image.AlphaIsValid()) return false;
+ bool fullyTransparent(true);
+ bool fullyOpaque(true);
+ for (unsigned int y = 0; y < height; y++)
+ {
+ BYTE *ptr = bufferin + (y * stride);
+ for (unsigned int x = 0; x < width; x++)
+ {
+ BYTE b = *ptr++;
+ BYTE g = *ptr++;
+ BYTE r = *ptr++;
+ BYTE a = *ptr++; // alpha
+ if (a)
+ fullyTransparent = false;
+ if (a != 0xff)
+ fullyOpaque = false;
+ image.SetPixelColor(x, height - 1 - y, RGB(r, g, b));
+ image.AlphaSet(x, height - 1 - y, a);
+ }
+ }
+ if (fullyTransparent || fullyOpaque)
+ image.AlphaDelete();
+ image.SetJpegQuality(90);
+
+ DWORD type;
+ if (image.AlphaIsValid() || GetImageType(thumb) == CXIMAGE_FORMAT_PNG)
+ type = CXIMAGE_FORMAT_PNG;
+ else
+ type = CXIMAGE_FORMAT_JPG;
+
+ long buffout=0;
+
+ if (!image.Encode(bufferout, buffout, type))
+ {
+ printf("PICTURE::CreateThumbnailFromSurface: Unable to save thumb to %s", thumb);
+ return false;
+ }
+ bufferoutSize = buffout;
+ return true;
+ };
+
+ __declspec(dllexport) void FreeMemory(void* memblock)
+ {
+ if (memblock)
+ free(memblock);
+ };
}
#endif
View
5 project/VS2010Express/XBMC.vcxproj
@@ -583,6 +583,7 @@
<ClCompile Include="..\..\xbmc\GUIInfoManager.cpp" />
<ClCompile Include="..\..\xbmc\GUILargeTextureManager.cpp" />
<ClCompile Include="..\..\xbmc\guilib\AnimatedGif.cpp" />
+ <ClCompile Include="..\..\xbmc\guilib\cximage.cpp" />
<ClCompile Include="..\..\xbmc\guilib\D3DResource.cpp" />
<ClCompile Include="..\..\xbmc\guilib\DDSImage.cpp" />
<ClCompile Include="..\..\xbmc\guilib\DirectXGraphics.cpp" />
@@ -668,6 +669,7 @@
<ClCompile Include="..\..\xbmc\guilib\GUIWindow.cpp" />
<ClCompile Include="..\..\xbmc\guilib\GUIWindowManager.cpp" />
<ClCompile Include="..\..\xbmc\guilib\GUIWrappingListContainer.cpp" />
+ <ClCompile Include="..\..\xbmc\guilib\imagefactory.cpp" />
<ClCompile Include="..\..\xbmc\guilib\IWindowManagerCallback.cpp" />
<ClCompile Include="..\..\xbmc\guilib\JpegIO.cpp" />
<ClCompile Include="..\..\xbmc\guilib\Key.cpp" />
@@ -1035,8 +1037,11 @@
<ClInclude Include="..\..\xbmc\filesystem\VideoDatabaseDirectory\DirectoryNodeTags.h" />
<ClInclude Include="..\..\xbmc\filesystem\windows\WINFileSMB.h" />
<ClInclude Include="..\..\xbmc\filesystem\windows\WINSMBDirectory.h" />
+ <ClInclude Include="..\..\xbmc\guilib\cximage.h" />
<ClInclude Include="..\..\xbmc\guilib\GUIKeyboard.h" />
<ClInclude Include="..\..\xbmc\guilib\GUIKeyboardFactory.h" />
+ <ClInclude Include="..\..\xbmc\guilib\iimage.h" />
+ <ClInclude Include="..\..\xbmc\guilib\imagefactory.h" />
<ClInclude Include="..\..\xbmc\input\windows\WINJoystick.h" />
<ClInclude Include="..\..\xbmc\interfaces\json-rpc\PVROperations.h" />
<ClInclude Include="..\..\xbmc\interfaces\legacy\Addon.h" />
View
18 project/VS2010Express/XBMC.vcxproj.filters
@@ -2969,6 +2969,12 @@
<ClCompile Include="..\..\xbmc\view\ViewDatabase.cpp">
<Filter>view</Filter>
</ClCompile>
+ <ClCompile Include="..\..\xbmc\guilib\imagefactory.cpp">
+ <Filter>guilib</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\xbmc\guilib\cximage.cpp">
+ <Filter>guilib</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\xbmc\win32\pch.h">
@@ -5781,6 +5787,16 @@
<ClInclude Include="..\..\xbmc\interfaces\python\PyContext.h">
<Filter>interfaces\python</Filter>
</ClInclude>
+
+ <ClInclude Include="..\..\xbmc\guilib\iimage.h">
+ <Filter>guilib</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\xbmc\guilib\imagefactory.h">
+ <Filter>guilib</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\xbmc\guilib\cximage.h">
+ <Filter>guilib</Filter>
+ </ClInclude>
<ClInclude Include="..\..\xbmc\music\karaoke\karaokevideobackground.h">
<Filter>music\karaoke</Filter>
</ClInclude>
@@ -5830,4 +5846,4 @@
<Filter>interfaces\swig</Filter>
</None>
</ItemGroup>
-</Project>
+</Project>
View
115 xbmc/guilib/JpegIO.cpp
@@ -237,6 +237,7 @@ CJpegIO::CJpegIO()
m_inputBuff = NULL;
m_texturePath = "";
memset(&m_cinfo, 0, sizeof(m_cinfo));
+ m_thumbnailbuffer = NULL;
}
CJpegIO::~CJpegIO()
@@ -248,6 +249,7 @@ void CJpegIO::Close()
{
free(m_inputBuff);
m_inputBuffSize = 0;
+ ReleaseThumbnailBuffer();
}
bool CJpegIO::Open(const CStdString &texturePath, unsigned int minx, unsigned int miny, bool read)
@@ -724,3 +726,116 @@ unsigned int CJpegIO::GetExifOrientation(unsigned char* exif_data, unsigned int
return orientation;//done
}
+
+bool CJpegIO::LoadImageFromMemory(unsigned char* buffer, unsigned int bufSize, unsigned int width, unsigned int height)
+{
+ return Read(buffer, bufSize, width, height);
+}
+
+bool CJpegIO::CreateThumbnailFromSurface(unsigned char* bufferin, unsigned int width, unsigned int height, unsigned int format, unsigned int pitch, const CStdString& destFile,
+ unsigned char* &bufferout, unsigned int &bufferoutSize)
+{
+ //Encode raw data from buffer, save to destbuffer
+ struct jpeg_compress_struct cinfo;
+ struct my_error_mgr jerr;
+ JSAMPROW row_pointer[1];
+ long unsigned int outBufSize = width * height;
+ unsigned char* src = bufferin;
+ unsigned char* rgbbuf, *src2, *dst2;
+
+ if(bufferin == NULL)
+ {
+ CLog::Log(LOGERROR, "JpegIO::CreateThumbnailFromSurface no buffer");
+ return false;
+ }
+
+ m_thumbnailbuffer = (unsigned char*) malloc(outBufSize); //Initial buffer. Grows as-needed.
+ if (m_thumbnailbuffer == NULL)
+ {
+ CLog::Log(LOGERROR, "JpegIO::CreateThumbnailFromSurface error allocating memory for image buffer");
+ return false;
+ }
+
+ if(format == XB_FMT_RGB8)
+ {
+ rgbbuf = bufferin;
+ }
+ else if(format == XB_FMT_A8R8G8B8)
+ {
+ // create a copy for bgra -> rgb.
+ rgbbuf = new unsigned char [(width * height * 3)];
+ unsigned char* dst = rgbbuf;
+ for (unsigned int y = 0; y < height; y++)
+ {
+ dst2 = dst;
+ src2 = src;
+ for (unsigned int x = 0; x < width; x++, src2 += 4)
+ {
+ *dst2++ = src2[2];
+ *dst2++ = src2[1];
+ *dst2++ = src2[0];
+ }
+ dst += width * 3;
+ src += pitch;
+ }
+ }
+ else
+ {
+ CLog::Log(LOGWARNING, "JpegIO::CreateThumbnailFromSurface Unsupported format");
+ free(m_thumbnailbuffer);
+ return false;
+ }
+
+ cinfo.err = jpeg_std_error(&jerr.pub);
+ jerr.pub.error_exit = jpeg_error_exit;
+ jpeg_create_compress(&cinfo);
+
+ if (setjmp(jerr.setjmp_buffer))
+ {
+ jpeg_destroy_compress(&cinfo);
+ free(m_thumbnailbuffer);
+ if(format != XB_FMT_RGB8)
+ delete [] rgbbuf;
+ return false;
+ }
+ else
+ {
+#if JPEG_LIB_VERSION < 80
+ x_jpeg_mem_dest(&cinfo, &m_thumbnailbuffer, &outBufSize);
+#else
+ jpeg_mem_dest(&cinfo, &m_thumbnailbuffer, &outBufSize);
+#endif
+ cinfo.image_width = width;
+ cinfo.image_height = height;
+ cinfo.input_components = 3;
+ cinfo.in_color_space = JCS_RGB;
+ jpeg_set_defaults(&cinfo);
+ jpeg_set_quality(&cinfo, 90, TRUE);
+ jpeg_start_compress(&cinfo, TRUE);
+
+ while (cinfo.next_scanline < cinfo.image_height)
+ {
+ row_pointer[0] = &rgbbuf[cinfo.next_scanline * width * 3];
+ jpeg_write_scanlines(&cinfo, row_pointer, 1);
+ }
+
+ jpeg_finish_compress(&cinfo);
+ jpeg_destroy_compress(&cinfo);
+ }
+ if(format != XB_FMT_RGB8)
+ delete [] rgbbuf;
+
+ bufferout = m_thumbnailbuffer;
+ bufferoutSize = outBufSize;
+
+ return true;
+}
+
+void CJpegIO::ReleaseThumbnailBuffer()
+{
+ if(m_thumbnailbuffer != NULL)
+ {
+ free(m_thumbnailbuffer);
+ m_thumbnailbuffer = NULL;
+ }
+}
View
19 xbmc/guilib/JpegIO.h
@@ -28,8 +28,9 @@
#include <jpeglib.h>
#include "utils/StdString.h"
+#include "iimage.h"
-class CJpegIO
+class CJpegIO : public IImage
{
public:
@@ -37,15 +38,16 @@ class 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);
bool CreateThumbnailFromSurface(unsigned char* buffer, unsigned int width, unsigned int height, unsigned int format, unsigned int pitch, const CStdString& destFile);
void Close();
-
- unsigned int Width() { return m_width; }
- unsigned int Height() { return m_height; }
- unsigned int Orientation() { return m_orientation; }
+ // methods for the imagefactory
+ virtual bool Decode(const unsigned char *pixels, unsigned int pitch, unsigned int format);
+ virtual bool LoadImageFromMemory(unsigned char* buffer, unsigned int bufSize, unsigned int width, unsigned int height);
+ virtual bool CreateThumbnailFromSurface(unsigned char* bufferin, unsigned int width, unsigned int height, unsigned int format, unsigned int pitch, const CStdString& destFile,
+ unsigned char* &bufferout, unsigned int &bufferoutSize);
+ virtual void ReleaseThumbnailBuffer();
protected:
static void jpeg_error_exit(j_common_ptr cinfo);
@@ -56,10 +58,7 @@ class CJpegIO
unsigned int m_inputBuffSize;
struct jpeg_decompress_struct m_cinfo;
CStdString m_texturePath;
-
- unsigned int m_width;
- unsigned int m_height;
- unsigned int m_orientation;
+ unsigned char* m_thumbnailbuffer;
};
#endif
View
2  xbmc/guilib/Makefile.in
@@ -3,6 +3,7 @@ SRCS += DDSImage.cpp
SRCS += DirectXGraphics.cpp
SRCS += DirtyRegionSolvers.cpp
SRCS += DirtyRegionTracker.cpp
+SRCS += cximage.cpp
SRCS += FrameBufferObject.cpp
SRCS += GraphicContext.cpp
SRCS += GUIAction.cpp
@@ -61,6 +62,7 @@ SRCS += GUIVisualisationControl.cpp
SRCS += GUIWindow.cpp
SRCS += GUIWindowManager.cpp
SRCS += GUIWrappingListContainer.cpp
+SRCS += imagefactory.cpp
SRCS += IWindowManagerCallback.cpp
SRCS += JpegIO.cpp
SRCS += Key.cpp
View
209 xbmc/guilib/Texture.cpp
@@ -22,10 +22,9 @@
#include "windowing/WindowingFactory.h"
#include "utils/log.h"
#include "utils/URIUtils.h"
-#include "pictures/DllImageLib.h"
#include "DDSImage.h"
#include "filesystem/SpecialProtocol.h"
-#include "JpegIO.h"
+#include "filesystem/File.h"
#if defined(TARGET_DARWIN_IOS)
#include <ImageIO/ImageIO.h>
#include "filesystem/File.h"
@@ -293,48 +292,87 @@ bool CBaseTexture::LoadFromFileInternal(const CStdString& texturePath, unsigned
return false;
}
- //ImageLib is sooo sloow for jpegs. Try our own decoder first. If it fails, fall back to ImageLib.
- CStdString Ext = URIUtils::GetExtension(texturePath);
- Ext.ToLower(); // Ignore case of the extension
- if (Ext.Equals(".jpg") || Ext.Equals(".jpeg") || Ext.Equals(".tbn"))
+ 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();
+
+ // Read image into memory to use our vfs
+ unsigned char *inputBuff = NULL;
+ unsigned int inputBuffSize = 0;
+
+ XFILE::CFile file;
+ if (file.Open(texturePath.c_str(), READ_TRUNCATED))
{
- CJpegIO jpegfile;
- if (jpegfile.Open(texturePath, maxWidth, maxHeight))
+ /*
+ GetLength() will typically return values that fall into three cases:
+ 1. The real filesize. This is the typical case.
+ 2. Zero. This is the case for some http:// streams for example.
+ 3. Some value smaller than the real filesize. This is the case for an expanding file.
+
+ In order to handle all three cases, we read the file in chunks, relying on Read()
+ returning 0 at EOF. To minimize (re)allocation of the buffer, the chunksize in
+ cases 1 and 3 is set to one byte larger** than the value returned by GetLength().
+ The chunksize in case 2 is set to the larger of 64k and GetChunkSize().
+
+ We fill the buffer entirely before reallocation. Thus, reallocation never occurs in case 1
+ as the buffer is larger than the file, so we hit EOF before we hit the end of buffer.
+
+ To minimize reallocation, we double the chunksize each time up to a maxchunksize of 2MB.
+ */
+ unsigned int filesize = (unsigned int)file.GetLength();
+ unsigned int chunksize = filesize ? (filesize + 1) : std::max(65536U, (unsigned int)file.GetChunkSize());
+ unsigned int maxchunksize = 2048*1024U; /* max 2MB chunksize */
+ unsigned char *tempinputBuff = NULL;
+
+ unsigned int total_read = 0, free_space = 0;
+ while (true)
{
- if (jpegfile.Width() > 0 && jpegfile.Height() > 0)
- {
- Allocate(jpegfile.Width(), jpegfile.Height(), XB_FMT_A8R8G8B8);
- if (jpegfile.Decode(m_pixels, GetPitch(), XB_FMT_A8R8G8B8))
+ if (!free_space)
+ { // (re)alloc
+ inputBuffSize += chunksize;
+ tempinputBuff = (unsigned char *)realloc(inputBuff, inputBuffSize);
+ if (!tempinputBuff)
{
- if (autoRotate && jpegfile.Orientation())
- m_orientation = jpegfile.Orientation() - 1;
- m_hasAlpha=false;
- ClampToEdge();
- return true;
+ CLog::Log(LOGERROR, "%s unable to allocate buffer of size %u", __FUNCTION__, inputBuffSize);
+ free(inputBuff);
+ file.Close();
+ return false;
}
+ inputBuff = tempinputBuff;
+ free_space = chunksize;
+ chunksize = std::min(chunksize*2, maxchunksize);
}
+ unsigned int read = file.Read(inputBuff + total_read, free_space);
+ free_space -= read;
+ total_read += read;
+ if (!read)
+ break;
}
- CLog::Log(LOGDEBUG, "%s - Load of %s failed. Falling back to ImageLib", __FUNCTION__, texturePath.c_str());
- }
+ inputBuffSize = total_read;
+ file.Close();
- DllImageLib dll;
- if (!dll.Load())
+ if (inputBuffSize == 0)
+ return false;
+ }
+ else
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();
-
- if(!dll.LoadImage(texturePath.c_str(), width, height, &image))
+ CURL url(texturePath);
+ IImage* pImage = ImageFactory::CreateLoader(url);
+ if(!LoadIImage(pImage, inputBuff, inputBuffSize, width, height, autoRotate))
{
- CLog::Log(LOGERROR, "Texture manager unable to load file: %s", texturePath.c_str());
- return false;
+ delete pImage;
+ pImage = NULL;
+ pImage = ImageFactory::CreateFallbackLoader(texturePath);
+ if(!LoadIImage(pImage, inputBuff, inputBuffSize, width, height))
+ {
+ CLog::Log(LOGDEBUG, "%s - Load of %s failed.", __FUNCTION__, texturePath.c_str());
+ delete pImage;
+ free(inputBuff);
+ return false;
+ }
}
-
- LoadFromImage(image, autoRotate);
- dll.ReleaseImage(&image);
+ delete pImage;
+ free(inputBuff);
return true;
}
@@ -344,98 +382,45 @@ bool CBaseTexture::LoadFromFileInMem(unsigned char* buffer, size_t size, const s
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))
+ IImage* pImage = ImageFactory::CreateLoaderFromMimeType(mimeType);
+ if(!LoadIImage(pImage, buffer, size, width, height))
{
- CLog::Log(LOGERROR, "Texture manager unable to load image from memory");
- return false;
+ delete pImage;
+ pImage = NULL;
+ pImage = ImageFactory::CreateFallbackLoader(mimeType);
+ if(!LoadIImage(pImage, buffer, size, width, height))
+ {
+ delete pImage;
+ return false;
+ }
}
- LoadFromImage(image);
- dll.ReleaseImage(&image);
-
+ delete pImage;
return true;
}
-void CBaseTexture::LoadFromImage(ImageInfo &image, bool autoRotate)
+bool CBaseTexture::LoadIImage(IImage *pImage, unsigned char* buffer, unsigned int bufSize, unsigned int width, unsigned int height, 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;
- m_originalWidth = image.originalwidth;
- m_originalHeight = image.originalheight;
-
- unsigned int dstPitch = GetPitch();
- unsigned int srcPitch = ((image.width + 1)* 3 / 4) * 4; // bitmap row length is aligned to 4 bytes
-
- unsigned char *dst = m_pixels;
- unsigned char *src = image.texture + (m_imageHeight - 1) * srcPitch;
-
- for (unsigned int y = 0; y < m_imageHeight; y++)
- {
- unsigned char *dst2 = dst;
- unsigned char *src2 = src;
- for (unsigned int x = 0; x < m_imageWidth; x++, dst2 += 4, src2 += 3)
- {
- dst2[0] = src2[0];
- dst2[1] = src2[1];
- dst2[2] = src2[2];
- dst2[3] = 0xff;
- }
- src -= srcPitch;
- dst += dstPitch;
- }
-
- if(image.alpha)
+ if(pImage != NULL && pImage->LoadImageFromMemory(buffer, bufSize, width, height))
{
- dst = m_pixels + 3;
- src = image.alpha + (m_imageHeight - 1) * m_imageWidth;
-
- for (unsigned int y = 0; y < m_imageHeight; y++)
+ if (pImage->Width() > 0 && pImage->Height() > 0)
{
- unsigned char *dst2 = dst;
- unsigned char *src2 = src;
-
- for (unsigned int x = 0; x < m_imageWidth; x++, dst2+=4, src2++)
- *dst2 = *src2;
- src -= m_imageWidth;
- dst += dstPitch;
+ Allocate(pImage->Width(), pImage->Height(), XB_FMT_A8R8G8B8);
+ if (pImage->Decode(m_pixels, GetPitch(), XB_FMT_A8R8G8B8))
+ {
+ if (autoRotate && pImage->Orientation())
+ m_orientation = pImage->Orientation() - 1;
+ m_hasAlpha = pImage->hasAlpha();
+ m_originalWidth = pImage->originalWidth();
+ m_originalHeight = pImage->originalHeight();
+ ClampToEdge();
+ return true;
+ }
}
}
- ClampToEdge();
+ return false;
}
bool CBaseTexture::LoadFromMemory(unsigned int width, unsigned int height, unsigned int pitch, unsigned int format, bool hasAlpha, unsigned char* pixels)
View
4 xbmc/guilib/Texture.h
@@ -24,6 +24,7 @@
#include "gui3d.h"
#include "utils/StdString.h"
#include "XBTF.h"
+#include "guilib/imagefactory.h"
#pragma pack(1)
struct COLOR {unsigned char b,g,r,x;}; // Windows GDI expects 4bytes per color
@@ -32,7 +33,6 @@ struct COLOR {unsigned char b,g,r,x;}; // Windows GDI expects 4bytes per color
class CTexture;
class CGLTexture;
class CDXTexture;
-struct ImageInfo;
/*!
\ingroup textures
@@ -111,7 +111,7 @@ class CBaseTexture
bool LoadFromFileInMem(unsigned char* buffer, size_t size, const std::string& mimeType,
unsigned int maxWidth, unsigned int maxHeight);
bool LoadFromFileInternal(const CStdString& texturePath, unsigned int maxWidth, unsigned int maxHeight, bool autoRotate);
- void LoadFromImage(ImageInfo &image, bool autoRotate = false);
+ bool LoadIImage(IImage* pImage, unsigned char* buffer, unsigned int bufSize, unsigned int width, unsigned int height, bool autoRotate=false);
// helpers for computation of texture parameters for compressed textures
unsigned int GetPitch(unsigned int width) const;
unsigned int GetRows(unsigned int height) const;
View
131 xbmc/guilib/cximage.cpp
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2012 Team XBMC
+ * http://www.xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+#include "cximage.h"
+#include "utils/log.h"
+
+CXImage::CXImage(const std::string& strMimeType): m_strMimeType(strMimeType), m_thumbnailbuffer(NULL)
+{
+ m_hasAlpha = false;
+ memset(&m_image, 0, sizeof(m_image));
+ m_dll.Load();
+}
+
+CXImage::~CXImage()
+{
+ m_dll.FreeMemory(m_thumbnailbuffer);
+ m_dll.ReleaseImage(&m_image);
+ m_dll.Unload();
+}
+
+bool CXImage::LoadImageFromMemory(unsigned char* buffer, unsigned int bufSize, unsigned int width, unsigned int height)
+{
+ if (!m_dll.IsLoaded())
+ return false;
+
+ memset(&m_image, 0, sizeof(m_image));
+
+ std::string strExt = m_strMimeType;
+ int nPos = strExt.find('/');
+ if (nPos > -1)
+ strExt.erase(0, nPos + 1);
+
+ if(!m_dll.LoadImageFromMemory(buffer, bufSize, strExt.c_str(), width, height, &m_image))
+ {
+ CLog::Log(LOGERROR, "Texture manager unable to load image from memory");
+ return false;
+ }
+
+ m_hasAlpha = NULL != m_image.alpha;
+ m_width = m_image.width;
+ m_height = m_image.height;
+ m_orientation = m_image.exifInfo.Orientation;
+ m_originalWidth = m_image.originalwidth;
+ m_originalHeight = m_image.originalheight;
+ return true;
+}
+
+bool CXImage::Decode(const unsigned char *pixels, unsigned int pitch, unsigned int format)
+{
+ if (m_image.width == 0 || m_image.width == 0 || !m_dll.IsLoaded())
+ return false;
+
+ unsigned int dstPitch = pitch;
+ unsigned int srcPitch = ((m_image.width + 1)* 3 / 4) * 4; // bitmap row length is aligned to 4 bytes
+
+ unsigned char *dst = (unsigned char*)pixels;
+ unsigned char *src = m_image.texture + (m_height - 1) * srcPitch;
+
+ for (unsigned int y = 0; y < m_height; y++)
+ {
+ unsigned char *dst2 = dst;
+ unsigned char *src2 = src;
+ for (unsigned int x = 0; x < m_width; x++, dst2 += 4, src2 += 3)
+ {
+ dst2[0] = src2[0];
+ dst2[1] = src2[1];
+ dst2[2] = src2[2];
+ dst2[3] = 0xff;
+ }
+ src -= srcPitch;
+ dst += dstPitch;
+ }
+
+ if(m_image.alpha)
+ {
+ dst = (unsigned char*)pixels + 3;
+ src = m_image.alpha + (m_height - 1) * m_width;
+
+ for (unsigned int y = 0; y < m_height; y++)
+ {
+ unsigned char *dst2 = dst;
+ unsigned char *src2 = src;
+
+ for (unsigned int x = 0; x < m_width; x++, dst2+=4, src2++)
+ *dst2 = *src2;
+ src -= m_width;
+ dst += dstPitch;
+ }
+ }
+
+ m_dll.ReleaseImage(&m_image);
+ memset(&m_image, 0, sizeof(m_image));
+ return true;
+}
+
+bool CXImage::CreateThumbnailFromSurface(unsigned char* bufferin, unsigned int width, unsigned int height, unsigned int format, unsigned int pitch, const CStdString& destFile,
+ unsigned char* &bufferout, unsigned int &bufferoutSize)
+{
+ if (!bufferin || !m_dll.IsLoaded())
+ return false;
+
+ bool ret = m_dll.CreateThumbnailFromSurface2((BYTE *)bufferin, width, height, pitch, destFile.c_str(), m_thumbnailbuffer, bufferoutSize);
+ bufferout = m_thumbnailbuffer;
+ return ret;
+}
+
+void CXImage::ReleaseThumbnailBuffer()
+{
+ if (!m_dll.IsLoaded())
+ return;
+
+ m_dll.FreeMemory(m_thumbnailbuffer);
+ m_thumbnailbuffer = NULL;
+}
View
43 xbmc/guilib/cximage.h
@@ -0,0 +1,43 @@
+#pragma once
+/*
+ * Copyright (C) 2012 Team XBMC
+ * http://www.xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "iimage.h"
+#include "pictures/DllImageLib.h"
+
+class CXImage : public IImage
+{
+public:
+ CXImage(const std::string& strMimeType);
+ ~CXImage();
+
+ virtual bool LoadImageFromMemory(unsigned char* buffer, unsigned int bufSize, unsigned int width, unsigned int height);
+ virtual bool Decode(const unsigned char *pixels, unsigned int pitch, unsigned int format);
+ virtual bool CreateThumbnailFromSurface(unsigned char* bufferin, unsigned int width, unsigned int height, unsigned int format, unsigned int pitch, const CStdString& destFile,
+ unsigned char* &bufferout, unsigned int &bufferoutSize);
+ virtual void ReleaseThumbnailBuffer();
+
+private:
+ DllImageLib m_dll;
+ ImageInfo m_image;
+ std::string m_strMimeType;
+ BYTE* m_thumbnailbuffer;
+};
View
84 xbmc/guilib/iimage.h
@@ -0,0 +1,84 @@
+#pragma once
+/*
+* Copyright (C) 2012 Team XBMC
+* http://www.xbmc.org
+*
+* This Program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2, or (at your option)
+* any later version.
+*
+* This Program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with XBMC; see the file COPYING. If not, write to
+* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+* http://www.gnu.org/copyleft/gpl.html
+*
+*/
+#include "utils/StdString.h"
+
+class IImage
+{
+public:
+
+ IImage():m_width(0), m_height(0), m_originalWidth(0), m_originalHeight(0), m_orientation(0), m_hasAlpha(false) {};
+ virtual ~IImage() {};
+
+ /*!
+ \brief Load an image from memory with the format m_strMimeType to determine it's size and orientation
+ \param buffer The memory location where the image data can be found
+ \param bufSize The size of the buffer
+ \param width The ideal width of the texture
+ \param height The ideal height of the texture
+ \return true if the image could be loaded
+ */
+ virtual bool LoadImageFromMemory(unsigned char* buffer, unsigned int bufSize, unsigned int width, unsigned int height)=0;
+ /*!
+ \brief Decodes the previously loaded image data to the output buffer in 32 bit raw bits
+ \param pixels The output buffer
+ \param pitch The pitch of the output buffer
+ \param format The format of the output buffer (JpegIO only)
+ \return true if the image data could be decoded to the output buffer
+ */
+ virtual bool Decode(const unsigned char *pixels, unsigned int pitch, unsigned int format)=0;
+ /*!
+ \brief Encodes an thumbnail from raw bits of given memory location
+ \remarks Caller need to call ReleaseThumbnailBuffer() afterwards to free the output buffer
+ \param bufferin The memory location where the image data can be found
+ \param width The width of the thumbnail
+ \param height The height of the thumbnail
+ \param format The format of the input buffer (JpegIO only)
+ \param pitch The pitch of the input texture stored in bufferin
+ \param destFile The destination path of the thumbnail to determine the image format from the extension
+ \param bufferout The output buffer (will be allocated inside the method)
+ \param bufferoutSize The output buffer size
+ \return true if the thumbnail was successfully created
+ */
+ virtual bool CreateThumbnailFromSurface(unsigned char* bufferin, unsigned int width, unsigned int height, unsigned int format, unsigned int pitch, const CStdString& destFile,
+ unsigned char* &bufferout, unsigned int &bufferoutSize)=0;
+ /*!
+ \brief Frees the output buffer allocated by CreateThumbnailFromSurface
+ */
+ virtual void ReleaseThumbnailBuffer() {return;}
+
+ unsigned int Width() { return m_width; }
+ unsigned int Height() { return m_height; }
+ unsigned int originalWidth() { return m_originalWidth; }
+ unsigned int originalHeight() { return m_originalHeight; }
+ unsigned int Orientation() { return m_orientation; }
+ bool hasAlpha() { return m_hasAlpha; }
+
+protected:
+
+ unsigned int m_width;
+ unsigned int m_height;
+ unsigned int m_originalWidth; ///< original image width before scaling or cropping
+ unsigned int m_originalHeight; ///< original image height before scaling or cropping
+ unsigned int m_orientation;
+ bool m_hasAlpha;
+
+};
View
52 xbmc/guilib/imagefactory.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2012 Team XBMC
+ * http://www.xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "imagefactory.h"
+#include "guilib/JpegIO.h"
+#include "guilib/cximage.h"
+
+IImage* ImageFactory::CreateLoader(const std::string& strFileName)
+{
+ CURL url(strFileName);
+ return CreateLoader(url);
+}
+
+IImage* ImageFactory::CreateLoader(const CURL& url)
+{
+ return CreateLoaderFromMimeType("image/"+url.GetFileType());
+}
+
+IImage* ImageFactory::CreateLoaderFromMimeType(const std::string& strMimeType)
+{
+ if(strMimeType == "image/jpeg" || strMimeType == "image/tbn" || strMimeType == "image/jpg")
+ return new CJpegIO();
+ return new CXImage(strMimeType);
+}
+
+IImage* ImageFactory::CreateFallbackLoader(const std::string& strMimeType)
+{
+ return new CXImage(strMimeType);
+}
+
+IImage* ImageFactory::CreateFallbackLoader(const CURL& url)
+{
+ return new CXImage("image/"+url.GetFileType());
+}
View
37 xbmc/guilib/imagefactory.h
@@ -0,0 +1,37 @@
+#pragma once
+/*
+ * Copyright (C) 2012 Team XBMC
+ * http://www.xbmc.org
+ *
+ * This Program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XBMC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "iimage.h"
+#include "URL.h"
+
+class ImageFactory
+{
+public:
+ ImageFactory() {}
+ virtual ~ImageFactory() {}
+
+ static IImage* CreateLoader(const std::string& strFileName);
+ static IImage* CreateLoader(const CURL& url);
+ static IImage* CreateLoaderFromMimeType(const std::string& strMimeType);
+ static IImage* CreateFallbackLoader(const std::string& strMimeType);
+ static IImage* CreateFallbackLoader(const CURL& url);
+};
View
6 xbmc/pictures/DllImageLib.h
@@ -93,6 +93,8 @@ class DllImageLibInterface
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 CreateThumbnailFromSurface(BYTE *, unsigned int, unsigned int, unsigned int, const char *)=0;
+ virtual bool CreateThumbnailFromSurface2(BYTE *, unsigned int, unsigned int, unsigned int, const char *, BYTE * &, unsigned int&)=0;
+ virtual void FreeMemory(void*)=0;
};
class DllImageLib : public DllDynamic, DllImageLibInterface
@@ -102,10 +104,14 @@ class DllImageLib : public DllDynamic, DllImageLibInterface
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, CreateThumbnailFromSurface, (BYTE * p1, unsigned int p2, unsigned int p3, unsigned int p4, const char * p5))
+ DEFINE_METHOD7(bool, CreateThumbnailFromSurface2, (BYTE * p1, unsigned int p2, unsigned int p3, unsigned int p4, const char * p5, BYTE * &p6, unsigned int &p7))
+ DEFINE_METHOD1(void, FreeMemory, (void *p1))
BEGIN_METHOD_RESOLVE()
RESOLVE_METHOD(ReleaseImage)
RESOLVE_METHOD(LoadImage)
RESOLVE_METHOD(LoadImageFromMemory)
RESOLVE_METHOD(CreateThumbnailFromSurface)
+ RESOLVE_METHOD(CreateThumbnailFromSurface2)
+ RESOLVE_METHOD(FreeMemory)
END_METHOD_RESOLVE()
};
View
32 xbmc/pictures/Picture.cpp
@@ -28,12 +28,11 @@
#include "settings/GUISettings.h"
#include "FileItem.h"
#include "filesystem/File.h"
-#include "DllImageLib.h"
#include "utils/log.h"
#include "utils/URIUtils.h"
#include "DllSwScale.h"
-#include "guilib/JpegIO.h"
#include "guilib/Texture.h"
+#include "guilib/imagefactory.h"
#if defined(HAS_OMXPLAYER)
#include "cores/omxplayer/OMXImage.h"
#endif
@@ -54,13 +53,30 @@ bool CPicture::CreateThumbnailFromSurface(const unsigned char *buffer, int width
}
delete omxImage;
#endif
- CJpegIO jpegImage;
- if (jpegImage.CreateThumbnailFromSurface((BYTE *)buffer, width, height, XB_FMT_A8R8G8B8, stride, thumbFile.c_str()))
- return true;
}
- DllImageLib dll;
- if (!buffer || !dll.Load()) return false;
- return dll.CreateThumbnailFromSurface((BYTE *)buffer, width, height, stride, thumbFile.c_str());
+
+ unsigned char *thumb = NULL;
+ unsigned int thumbsize=0;
+ IImage* pImage = ImageFactory::CreateLoader(thumbFile);
+ if(pImage == NULL || !pImage->CreateThumbnailFromSurface((BYTE *)buffer, width, height, XB_FMT_A8R8G8B8, stride, thumbFile.c_str(), thumb, thumbsize))
+ {
+ CLog::Log(LOGERROR, "Failed to CreateThumbnailFromSurface for %s", thumbFile.c_str());
+ delete pImage;
+ return false;
+ }
+
+ XFILE::CFile file;
+ if (file.OpenForWrite(thumbFile, true))
+ {
+ file.Write(thumb, thumbsize);
+ file.Close();
+ pImage->ReleaseThumbnailBuffer();
+ delete pImage;
+ return true;
+ }
+ pImage->ReleaseThumbnailBuffer();
+ delete pImage;
+ return false;
}
CThumbnailWriter::CThumbnailWriter(unsigned char* buffer, int width, int height, int stride, const CStdString& thumbFile)
Please sign in to comment.
Something went wrong with that request. Please try again.