Skip to content
This repository
Browse code

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 January 01, 2013
12  XBMC-ATV2.xcodeproj/project.pbxproj
@@ -123,6 +123,8 @@
123 123
 		DF402A95164462FC001C56B8 /* swig.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F502C09C160F421600C96C76 /* swig.cpp */; };
124 124
 		DF402A96164462FC001C56B8 /* XBPython.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F502C09E160F421600C96C76 /* XBPython.cpp */; };
125 125
 		DF402A97164462FC001C56B8 /* XBPyThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F502C0A0160F421600C96C76 /* XBPyThread.cpp */; };
  126
+		DF404AA716B98E6300D8023E /* cximage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF404AA316B98E6300D8023E /* cximage.cpp */; };
  127
+		DF404AA816B98E6300D8023E /* imagefactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF404AA516B98E6300D8023E /* imagefactory.cpp */; };
126 128
 		DF4485351400651B0069344B /* PipesManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF4485321400651B0069344B /* PipesManager.cpp */; };
127 129
 		DF4485381400654A0069344B /* AirTunesServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF4485361400654A0069344B /* AirTunesServer.cpp */; };
128 130
 		DF527780151BAFD600B5B63B /* WebSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF527777151BAFD600B5B63B /* WebSocket.cpp */; };
@@ -1317,6 +1319,10 @@
1317 1319
 		DF33C2AC15509C5A0046CDCB /* ilog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ilog.h; sourceTree = "<group>"; };
1318 1320
 		DF34890713FD96390026A711 /* GUIAction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUIAction.cpp; sourceTree = "<group>"; };
1319 1321
 		DF34890813FD96390026A711 /* GUIAction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUIAction.h; sourceTree = "<group>"; };
  1322
+		DF404AA316B98E6300D8023E /* cximage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cximage.cpp; sourceTree = "<group>"; };
  1323
+		DF404AA416B98E6300D8023E /* cximage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cximage.h; sourceTree = "<group>"; };
  1324
+		DF404AA516B98E6300D8023E /* imagefactory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = imagefactory.cpp; sourceTree = "<group>"; };
  1325
+		DF404AA616B98E6300D8023E /* imagefactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imagefactory.h; sourceTree = "<group>"; };
1320 1326
 		DF4485321400651B0069344B /* PipesManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PipesManager.cpp; sourceTree = "<group>"; };
1321 1327
 		DF4485331400651B0069344B /* PipesManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PipesManager.h; sourceTree = "<group>"; };
1322 1328
 		DF4485361400654A0069344B /* AirTunesServer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AirTunesServer.cpp; sourceTree = "<group>"; };
@@ -5027,6 +5033,8 @@
5027 5033
 			children = (
5028 5034
 				F56C74FE131EC152000AD0F6 /* AnimatedGif.cpp */,
5029 5035
 				F56C74A0131EC152000AD0F6 /* AnimatedGif.h */,
  5036
+				DF404AA316B98E6300D8023E /* cximage.cpp */,
  5037
+				DF404AA416B98E6300D8023E /* cximage.h */,
5030 5038
 				F56C7500131EC152000AD0F6 /* D3DResource.cpp */,
5031 5039
 				F56C74A2131EC152000AD0F6 /* D3DResource.h */,
5032 5040
 				F56C7501131EC152000AD0F6 /* DDSImage.cpp */,
@@ -5171,6 +5179,8 @@
5171 5179
 				F56C7543131EC152000AD0F6 /* GUIWrappingListContainer.cpp */,
5172 5180
 				F56C74E9131EC152000AD0F6 /* GUIWrappingListContainer.h */,
5173 5181
 				F56C74EA131EC152000AD0F6 /* IAudioDeviceChangedCallback.h */,
  5182
+				DF404AA516B98E6300D8023E /* imagefactory.cpp */,
  5183
+				DF404AA616B98E6300D8023E /* imagefactory.h */,
5174 5184
 				F56C74EB131EC152000AD0F6 /* IMsgTargetCallback.h */,
5175 5185
 				F56C7544131EC152000AD0F6 /* IWindowManagerCallback.cpp */,
5176 5186
 				F56C74EC131EC152000AD0F6 /* IWindowManagerCallback.h */,
@@ -7659,6 +7669,8 @@
7659 7669
 				DFB02E0816629E1900F37752 /* PyContext.cpp in Sources */,
7660 7670
 				DF07255216873553008DCAAD /* karaokevideobackground.cpp in Sources */,
7661 7671
 				DF07255516873565008DCAAD /* FFmpegVideoDecoder.cpp in Sources */,
  7672
+				DF404AA716B98E6300D8023E /* cximage.cpp in Sources */,
  7673
+				DF404AA816B98E6300D8023E /* imagefactory.cpp in Sources */,
7662 7674
 				5500731516A75A2700097786 /* UPnPPlayer.cpp in Sources */,
7663 7675
 				DF64FE6C16C07B2C00D028FB /* GUIViewControl.cpp in Sources */,
7664 7676
 				DF64FE6D16C07B2C00D028FB /* GUIViewState.cpp in Sources */,
16  XBMC-IOS.xcodeproj/project.pbxproj
@@ -124,6 +124,8 @@
124 124
 		DF402A83164462C3001C56B8 /* swig.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F502C076160F417B00C96C76 /* swig.cpp */; };
125 125
 		DF402A84164462C3001C56B8 /* XBPython.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F502C078160F417B00C96C76 /* XBPython.cpp */; };
126 126
 		DF402A85164462C3001C56B8 /* XBPyThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F502C07A160F417B00C96C76 /* XBPyThread.cpp */; };
  127
+		DF404A9416B98E4A00D8023E /* cximage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF404A8F16B98E4A00D8023E /* cximage.cpp */; };
  128
+		DF404A9516B98E4A00D8023E /* imagefactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF404A9216B98E4A00D8023E /* imagefactory.cpp */; };
127 129
 		DF448572140065E10069344B /* PipesManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF44856F140065E10069344B /* PipesManager.cpp */; };
128 130
 		DF4485751400662D0069344B /* AirTunesServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF4485731400662D0069344B /* AirTunesServer.cpp */; };
129 131
 		DF527757151BAF8200B5B63B /* WebSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF52774E151BAF8200B5B63B /* WebSocket.cpp */; };
@@ -1322,6 +1324,11 @@
1322 1324
 		DF33C29215509BF50046CDCB /* ilog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ilog.h; sourceTree = "<group>"; };
1323 1325
 		DF3488F613FD961A0026A711 /* GUIAction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUIAction.cpp; sourceTree = "<group>"; };
1324 1326
 		DF3488F713FD961A0026A711 /* GUIAction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUIAction.h; sourceTree = "<group>"; };
  1327
+		DF404A8F16B98E4A00D8023E /* cximage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cximage.cpp; sourceTree = "<group>"; };
  1328
+		DF404A9016B98E4A00D8023E /* cximage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cximage.h; sourceTree = "<group>"; };
  1329
+		DF404A9116B98E4A00D8023E /* iimage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iimage.h; sourceTree = "<group>"; };
  1330
+		DF404A9216B98E4A00D8023E /* imagefactory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = imagefactory.cpp; sourceTree = "<group>"; };
  1331
+		DF404A9316B98E4A00D8023E /* imagefactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imagefactory.h; sourceTree = "<group>"; };
1325 1332
 		DF44856F140065E10069344B /* PipesManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PipesManager.cpp; sourceTree = "<group>"; };
1326 1333
 		DF448570140065E10069344B /* PipesManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PipesManager.h; sourceTree = "<group>"; };
1327 1334
 		DF4485731400662D0069344B /* AirTunesServer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AirTunesServer.cpp; sourceTree = "<group>"; };
@@ -5386,6 +5393,8 @@
5386 5393
 			children = (
5387 5394
 				F56C84E1131F42E9000AD0F6 /* AnimatedGif.cpp */,
5388 5395
 				F56C8483131F42E9000AD0F6 /* AnimatedGif.h */,
  5396
+				DF404A8F16B98E4A00D8023E /* cximage.cpp */,
  5397
+				DF404A9016B98E4A00D8023E /* cximage.h */,
5389 5398
 				F56C84E3131F42E9000AD0F6 /* D3DResource.cpp */,
5390 5399
 				F56C8485131F42E9000AD0F6 /* D3DResource.h */,
5391 5400
 				F56C84E4131F42E9000AD0F6 /* DDSImage.cpp */,
@@ -5452,9 +5461,9 @@
5452 5461
 				F56C84A4131F42E9000AD0F6 /* GUIIncludes.h */,
5453 5462
 				F56C84FF131F42E9000AD0F6 /* GUIInfoTypes.cpp */,
5454 5463
 				F56C84A5131F42E9000AD0F6 /* GUIInfoTypes.h */,
  5464
+				DF02A831153373EC0084754E /* GUIKeyboard.h */,
5455 5465
 				DF830C9C15BB215500602BE6 /* GUIKeyboardFactory.cpp */,
5456 5466
 				DF830C9D15BB215500602BE6 /* GUIKeyboardFactory.h */,
5457  
-				DF02A831153373EC0084754E /* GUIKeyboard.h */,
5458 5467
 				F56C8500131F42E9000AD0F6 /* GUILabel.cpp */,
5459 5468
 				F56C84A6131F42E9000AD0F6 /* GUILabel.h */,
5460 5469
 				F56C8501131F42E9000AD0F6 /* GUILabelControl.cpp */,
@@ -5530,6 +5539,9 @@
5530 5539
 				F56C8526131F42E9000AD0F6 /* GUIWrappingListContainer.cpp */,
5531 5540
 				F56C84CC131F42E9000AD0F6 /* GUIWrappingListContainer.h */,
5532 5541
 				F56C84CD131F42E9000AD0F6 /* IAudioDeviceChangedCallback.h */,
  5542
+				DF404A9116B98E4A00D8023E /* iimage.h */,
  5543
+				DF404A9216B98E4A00D8023E /* imagefactory.cpp */,
  5544
+				DF404A9316B98E4A00D8023E /* imagefactory.h */,
5533 5545
 				F56C84CE131F42E9000AD0F6 /* IMsgTargetCallback.h */,
5534 5546
 				F56C8527131F42E9000AD0F6 /* IWindowManagerCallback.cpp */,
5535 5547
 				F56C84CF131F42E9000AD0F6 /* IWindowManagerCallback.h */,
@@ -7688,6 +7700,8 @@
7688 7700
 				DFB02DFB16629DF200F37752 /* PyContext.cpp in Sources */,
7689 7701
 				DF07254116873517008DCAAD /* karaokevideobackground.cpp in Sources */,
7690 7702
 				DF0725441687352C008DCAAD /* FFmpegVideoDecoder.cpp in Sources */,
  7703
+				DF404A9416B98E4A00D8023E /* cximage.cpp in Sources */,
  7704
+				DF404A9516B98E4A00D8023E /* imagefactory.cpp in Sources */,
7691 7705
 				5500730E16A759D800097786 /* UPnPPlayer.cpp in Sources */,
7692 7706
 				DF64FE5616C07AF700D028FB /* GUIViewControl.cpp in Sources */,
7693 7707
 				DF64FE5716C07AF700D028FB /* GUIViewState.cpp in Sources */,
14  XBMC.xcodeproj/project.pbxproj
@@ -397,6 +397,8 @@
397 397
 		DF402A65164461B9001C56B8 /* swig.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F502BFF0160F36AD00C96C76 /* swig.cpp */; };
398 398
 		DF402A66164461B9001C56B8 /* XBPython.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F502BFE6160F34FE00C96C76 /* XBPython.cpp */; };
399 399
 		DF402A67164461B9001C56B8 /* XBPyThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F502BFE8160F34FE00C96C76 /* XBPyThread.cpp */; };
  400
+		DF404A3916B9896C00D8023E /* cximage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF404A3416B9896C00D8023E /* cximage.cpp */; };
  401
+		DF404A3A16B9896C00D8023E /* imagefactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF404A3716B9896C00D8023E /* imagefactory.cpp */; };
400 402
 		DF448457140048A60069344B /* AirTunesServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF448455140048A60069344B /* AirTunesServer.cpp */; };
401 403
 		DF44845E140048C80069344B /* PipesManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF44845B140048C80069344B /* PipesManager.cpp */; };
402 404
 		DF5276E1151BAEDA00B5B63B /* Base64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DF52769A151BAEDA00B5B63B /* Base64.cpp */; };
@@ -1915,6 +1917,11 @@
1915 1917
 		DF34892913FD9C780026A711 /* AirPlayServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AirPlayServer.h; sourceTree = "<group>"; };
1916 1918
 		DF34897A13FDAA270026A711 /* HttpParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HttpParser.h; sourceTree = "<group>"; };
1917 1919
 		DF34898113FDAAF60026A711 /* HttpParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HttpParser.cpp; sourceTree = "<group>"; };
  1920
+		DF404A3416B9896C00D8023E /* cximage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cximage.cpp; sourceTree = "<group>"; };
  1921
+		DF404A3516B9896C00D8023E /* cximage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cximage.h; sourceTree = "<group>"; };
  1922
+		DF404A3616B9896C00D8023E /* iimage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iimage.h; sourceTree = "<group>"; };
  1923
+		DF404A3716B9896C00D8023E /* imagefactory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = imagefactory.cpp; sourceTree = "<group>"; };
  1924
+		DF404A3816B9896C00D8023E /* imagefactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imagefactory.h; sourceTree = "<group>"; };
1918 1925
 		DF448455140048A60069344B /* AirTunesServer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AirTunesServer.cpp; sourceTree = "<group>"; };
1919 1926
 		DF448456140048A60069344B /* AirTunesServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AirTunesServer.h; sourceTree = "<group>"; };
1920 1927
 		DF44845B140048C80069344B /* PipesManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PipesManager.cpp; sourceTree = "<group>"; };
@@ -3418,6 +3425,8 @@
3418 3425
 			children = (
3419 3426
 				18B7C7541294222E009E7A26 /* AnimatedGif.cpp */,
3420 3427
 				18B7C6F61294222D009E7A26 /* AnimatedGif.h */,
  3428
+				DF404A3416B9896C00D8023E /* cximage.cpp */,
  3429
+				DF404A3516B9896C00D8023E /* cximage.h */,
3421 3430
 				18B7C7561294222E009E7A26 /* D3DResource.cpp */,
3422 3431
 				18B7C6F81294222D009E7A26 /* D3DResource.h */,
3423 3432
 				18B7C7571294222E009E7A26 /* DDSImage.cpp */,
@@ -3562,6 +3571,9 @@
3562 3571
 				18B7C7991294222E009E7A26 /* GUIWrappingListContainer.cpp */,
3563 3572
 				18B7C73F1294222D009E7A26 /* GUIWrappingListContainer.h */,
3564 3573
 				18B7C7401294222D009E7A26 /* IAudioDeviceChangedCallback.h */,
  3574
+				DF404A3616B9896C00D8023E /* iimage.h */,
  3575
+				DF404A3716B9896C00D8023E /* imagefactory.cpp */,
  3576
+				DF404A3816B9896C00D8023E /* imagefactory.h */,
3565 3577
 				18B7C7411294222D009E7A26 /* IMsgTargetCallback.h */,
3566 3578
 				18B7C79A1294222E009E7A26 /* IWindowManagerCallback.cpp */,
3567 3579
 				18B7C7421294222D009E7A26 /* IWindowManagerCallback.h */,
@@ -7720,6 +7732,8 @@
7720 7732
 				DF64FE3D16C07AAA00D028FB /* GUIViewControl.cpp in Sources */,
7721 7733
 				DF64FE3E16C07AAA00D028FB /* GUIViewState.cpp in Sources */,
7722 7734
 				DF64FE4016C07AAA00D028FB /* ViewDatabase.cpp in Sources */,
  7735
+				DF404A3916B9896C00D8023E /* cximage.cpp in Sources */,
  7736
+				DF404A3A16B9896C00D8023E /* imagefactory.cpp in Sources */,
7723 7737
 			);
7724 7738
 			runOnlyForDeploymentPostprocessing = 0;
7725 7739
 		};
55  lib/cximage-6.0/CxImage/DllInterface.cpp
@@ -330,6 +330,61 @@ extern "C"
330 330
     }
331 331
     return true;
332 332
   };
  333
+
  334
+  __declspec(dllexport) bool CreateThumbnailFromSurface2(BYTE * bufferin, unsigned int width, unsigned int height, unsigned int stride, const char *thumb, 
  335
+                                                         BYTE * &bufferout, unsigned int &bufferoutSize)
  336
+  {
  337
+    if (!bufferin) return false;
  338
+    // creates an image, and copies the surface data into it.
  339
+    CxImage image(width, height, 24, CXIMAGE_FORMAT_PNG);
  340
+    if (!image.IsValid()) return false;
  341
+    image.AlphaCreate();
  342
+    if (!image.AlphaIsValid()) return false;
  343
+    bool fullyTransparent(true);
  344
+    bool fullyOpaque(true);
  345
+    for (unsigned int y = 0; y < height; y++)
  346
+    {
  347
+      BYTE *ptr = bufferin + (y * stride);
  348
+      for (unsigned int x = 0; x < width; x++)
  349
+      {
  350
+        BYTE b = *ptr++;
  351
+        BYTE g = *ptr++;
  352
+        BYTE r = *ptr++;
  353
+        BYTE a = *ptr++;  // alpha
  354
+        if (a)
  355
+          fullyTransparent = false;
  356
+        if (a != 0xff)
  357
+          fullyOpaque = false;
  358
+        image.SetPixelColor(x, height - 1 - y, RGB(r, g, b));
  359
+        image.AlphaSet(x, height - 1 - y, a);
  360
+      }
  361
+    }
  362
+    if (fullyTransparent || fullyOpaque)
  363
+      image.AlphaDelete();
  364
+    image.SetJpegQuality(90);
  365
+
  366
+    DWORD type;
  367
+    if (image.AlphaIsValid() || GetImageType(thumb) == CXIMAGE_FORMAT_PNG)
  368
+      type = CXIMAGE_FORMAT_PNG;
  369
+    else
  370
+      type = CXIMAGE_FORMAT_JPG;
  371
+
  372
+    long buffout=0;
  373
+
  374
+    if (!image.Encode(bufferout, buffout, type))
  375
+    {
  376
+      printf("PICTURE::CreateThumbnailFromSurface: Unable to save thumb to %s", thumb);
  377
+      return false;
  378
+    }
  379
+    bufferoutSize = buffout;
  380
+    return true;
  381
+  };
  382
+
  383
+  __declspec(dllexport) void	FreeMemory(void* memblock)
  384
+  {
  385
+    if (memblock)
  386
+		  free(memblock);
  387
+  };
333 388
 }
334 389
 
335 390
 #endif
5  project/VS2010Express/XBMC.vcxproj
@@ -583,6 +583,7 @@
583 583
     <ClCompile Include="..\..\xbmc\GUIInfoManager.cpp" />
584 584
     <ClCompile Include="..\..\xbmc\GUILargeTextureManager.cpp" />
585 585
     <ClCompile Include="..\..\xbmc\guilib\AnimatedGif.cpp" />
  586
+    <ClCompile Include="..\..\xbmc\guilib\cximage.cpp" />
586 587
     <ClCompile Include="..\..\xbmc\guilib\D3DResource.cpp" />
587 588
     <ClCompile Include="..\..\xbmc\guilib\DDSImage.cpp" />
588 589
     <ClCompile Include="..\..\xbmc\guilib\DirectXGraphics.cpp" />
@@ -668,6 +669,7 @@
668 669
     <ClCompile Include="..\..\xbmc\guilib\GUIWindow.cpp" />
669 670
     <ClCompile Include="..\..\xbmc\guilib\GUIWindowManager.cpp" />
670 671
     <ClCompile Include="..\..\xbmc\guilib\GUIWrappingListContainer.cpp" />
  672
+    <ClCompile Include="..\..\xbmc\guilib\imagefactory.cpp" />
671 673
     <ClCompile Include="..\..\xbmc\guilib\IWindowManagerCallback.cpp" />
672 674
     <ClCompile Include="..\..\xbmc\guilib\JpegIO.cpp" />
673 675
     <ClCompile Include="..\..\xbmc\guilib\Key.cpp" />
@@ -1035,8 +1037,11 @@
1035 1037
     <ClInclude Include="..\..\xbmc\filesystem\VideoDatabaseDirectory\DirectoryNodeTags.h" />
1036 1038
     <ClInclude Include="..\..\xbmc\filesystem\windows\WINFileSMB.h" />
1037 1039
     <ClInclude Include="..\..\xbmc\filesystem\windows\WINSMBDirectory.h" />
  1040
+    <ClInclude Include="..\..\xbmc\guilib\cximage.h" />
1038 1041
     <ClInclude Include="..\..\xbmc\guilib\GUIKeyboard.h" />
1039 1042
     <ClInclude Include="..\..\xbmc\guilib\GUIKeyboardFactory.h" />
  1043
+    <ClInclude Include="..\..\xbmc\guilib\iimage.h" />
  1044
+    <ClInclude Include="..\..\xbmc\guilib\imagefactory.h" />
1040 1045
     <ClInclude Include="..\..\xbmc\input\windows\WINJoystick.h" />
1041 1046
     <ClInclude Include="..\..\xbmc\interfaces\json-rpc\PVROperations.h" />
1042 1047
     <ClInclude Include="..\..\xbmc\interfaces\legacy\Addon.h" />
18  project/VS2010Express/XBMC.vcxproj.filters
@@ -2969,6 +2969,12 @@
2969 2969
     <ClCompile Include="..\..\xbmc\view\ViewDatabase.cpp">
2970 2970
       <Filter>view</Filter>
2971 2971
     </ClCompile>
  2972
+    <ClCompile Include="..\..\xbmc\guilib\imagefactory.cpp">
  2973
+      <Filter>guilib</Filter>
  2974
+    </ClCompile>
  2975
+    <ClCompile Include="..\..\xbmc\guilib\cximage.cpp">
  2976
+      <Filter>guilib</Filter>
  2977
+    </ClCompile>
2972 2978
   </ItemGroup>
2973 2979
   <ItemGroup>
2974 2980
     <ClInclude Include="..\..\xbmc\win32\pch.h">
@@ -5781,6 +5787,16 @@
5781 5787
     <ClInclude Include="..\..\xbmc\interfaces\python\PyContext.h">
5782 5788
       <Filter>interfaces\python</Filter>
5783 5789
     </ClInclude>
  5790
+
  5791
+    <ClInclude Include="..\..\xbmc\guilib\iimage.h">
  5792
+      <Filter>guilib</Filter>
  5793
+    </ClInclude>
  5794
+    <ClInclude Include="..\..\xbmc\guilib\imagefactory.h">
  5795
+      <Filter>guilib</Filter>
  5796
+    </ClInclude>
  5797
+    <ClInclude Include="..\..\xbmc\guilib\cximage.h">
  5798
+      <Filter>guilib</Filter>
  5799
+    </ClInclude>
5784 5800
     <ClInclude Include="..\..\xbmc\music\karaoke\karaokevideobackground.h">
5785 5801
       <Filter>music\karaoke</Filter>
5786 5802
     </ClInclude>
@@ -5830,4 +5846,4 @@
5830 5846
       <Filter>interfaces\swig</Filter>
5831 5847
     </None>
5832 5848
   </ItemGroup>
5833  
-</Project>
  5849
+</Project>
115  xbmc/guilib/JpegIO.cpp
@@ -237,6 +237,7 @@ CJpegIO::CJpegIO()
237 237
   m_inputBuff = NULL;
238 238
   m_texturePath = "";
239 239
   memset(&m_cinfo, 0, sizeof(m_cinfo));
  240
+  m_thumbnailbuffer = NULL;
240 241
 }
241 242
 
242 243
 CJpegIO::~CJpegIO()
@@ -248,6 +249,7 @@ void CJpegIO::Close()
248 249
 {
249 250
   free(m_inputBuff);
250 251
   m_inputBuffSize = 0;
  252
+  ReleaseThumbnailBuffer();
251 253
 }
252 254
 
253 255
 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
724 726
 
725 727
   return orientation;//done
726 728
 }
  729
+
  730
+bool CJpegIO::LoadImageFromMemory(unsigned char* buffer, unsigned int bufSize, unsigned int width, unsigned int height)
  731
+{
  732
+  return Read(buffer, bufSize, width, height);
  733
+}
  734
+
  735
+bool CJpegIO::CreateThumbnailFromSurface(unsigned char* bufferin, unsigned int width, unsigned int height, unsigned int format, unsigned int pitch, const CStdString& destFile, 
  736
+                                         unsigned char* &bufferout, unsigned int &bufferoutSize)
  737
+{
  738
+  //Encode raw data from buffer, save to destbuffer
  739
+  struct jpeg_compress_struct cinfo;
  740
+  struct my_error_mgr jerr;
  741
+  JSAMPROW row_pointer[1];
  742
+  long unsigned int outBufSize = width * height;
  743
+  unsigned char* src = bufferin;
  744
+  unsigned char* rgbbuf, *src2, *dst2;
  745
+
  746
+  if(bufferin == NULL)
  747
+  {
  748
+    CLog::Log(LOGERROR, "JpegIO::CreateThumbnailFromSurface no buffer");
  749
+    return false;
  750
+  }
  751
+
  752
+  m_thumbnailbuffer = (unsigned char*) malloc(outBufSize); //Initial buffer. Grows as-needed.
  753
+  if (m_thumbnailbuffer == NULL)
  754
+  {
  755
+    CLog::Log(LOGERROR, "JpegIO::CreateThumbnailFromSurface error allocating memory for image buffer");
  756
+    return false;
  757
+  }
  758
+
  759
+  if(format == XB_FMT_RGB8)
  760
+  {
  761
+    rgbbuf = bufferin;
  762
+  }
  763
+  else if(format == XB_FMT_A8R8G8B8)
  764
+  {
  765
+    // create a copy for bgra -> rgb.
  766
+    rgbbuf = new unsigned char [(width * height * 3)];
  767
+    unsigned char* dst = rgbbuf;
  768
+    for (unsigned int y = 0; y < height; y++)
  769
+    {
  770
+      dst2 = dst;
  771
+      src2 = src;
  772
+      for (unsigned int x = 0; x < width; x++, src2 += 4)
  773
+      {
  774
+        *dst2++ = src2[2];
  775
+        *dst2++ = src2[1];
  776
+        *dst2++ = src2[0];
  777
+      }
  778
+      dst += width * 3;
  779
+      src += pitch;
  780
+    }
  781
+  }
  782
+  else
  783
+  {
  784
+    CLog::Log(LOGWARNING, "JpegIO::CreateThumbnailFromSurface Unsupported format");
  785
+    free(m_thumbnailbuffer);
  786
+    return false;
  787
+  }
  788
+
  789
+  cinfo.err = jpeg_std_error(&jerr.pub);
  790
+  jerr.pub.error_exit = jpeg_error_exit;
  791
+  jpeg_create_compress(&cinfo);
  792
+
  793
+  if (setjmp(jerr.setjmp_buffer))
  794
+  {
  795
+    jpeg_destroy_compress(&cinfo);
  796
+    free(m_thumbnailbuffer);
  797
+    if(format != XB_FMT_RGB8)
  798
+      delete [] rgbbuf;
  799
+    return false;
  800
+  }
  801
+  else
  802
+  {
  803
+#if JPEG_LIB_VERSION < 80
  804
+    x_jpeg_mem_dest(&cinfo, &m_thumbnailbuffer, &outBufSize);
  805
+#else
  806
+    jpeg_mem_dest(&cinfo, &m_thumbnailbuffer, &outBufSize);
  807
+#endif
  808
+    cinfo.image_width = width;
  809
+    cinfo.image_height = height;
  810
+    cinfo.input_components = 3;
  811
+    cinfo.in_color_space = JCS_RGB;
  812
+    jpeg_set_defaults(&cinfo);
  813
+    jpeg_set_quality(&cinfo, 90, TRUE);
  814
+    jpeg_start_compress(&cinfo, TRUE);
  815
+
  816
+    while (cinfo.next_scanline < cinfo.image_height)
  817
+    {
  818
+      row_pointer[0] = &rgbbuf[cinfo.next_scanline * width * 3];
  819
+      jpeg_write_scanlines(&cinfo, row_pointer, 1);
  820
+    }
  821
+
  822
+    jpeg_finish_compress(&cinfo);
  823
+    jpeg_destroy_compress(&cinfo);
  824
+  }
  825
+  if(format != XB_FMT_RGB8)
  826
+    delete [] rgbbuf;
  827
+
  828
+  bufferout = m_thumbnailbuffer;
  829
+  bufferoutSize = outBufSize;
  830
+
  831
+  return true;
  832
+}
  833
+
  834
+void CJpegIO::ReleaseThumbnailBuffer()
  835
+{
  836
+  if(m_thumbnailbuffer != NULL)
  837
+  {
  838
+    free(m_thumbnailbuffer);
  839
+    m_thumbnailbuffer = NULL;
  840
+  }
  841
+}
19  xbmc/guilib/JpegIO.h
@@ -28,8 +28,9 @@
28 28
 
29 29
 #include <jpeglib.h>
30 30
 #include "utils/StdString.h"
  31
+#include "iimage.h"
31 32
 
32  
-class CJpegIO
  33
+class CJpegIO : public IImage
33 34
 {
34 35
 
35 36
 public:
@@ -37,15 +38,16 @@ class CJpegIO
37 38
   ~CJpegIO();
38 39
   bool           Open(const CStdString& m_texturePath,  unsigned int minx=0, unsigned int miny=0, bool read=true);
39 40
   bool           Read(unsigned char* buffer, unsigned int bufSize, unsigned int minx, unsigned int miny);
40  
-  bool           Decode(const unsigned char *pixels, unsigned int pitch, unsigned int format);
41 41
   bool           CreateThumbnail(const CStdString& sourceFile, const CStdString& destFile, int minx, int miny, bool rotateExif);
42 42
   bool           CreateThumbnailFromMemory(unsigned char* buffer, unsigned int bufSize, const CStdString& destFile, unsigned int minx, unsigned int miny);
43 43
   bool           CreateThumbnailFromSurface(unsigned char* buffer, unsigned int width, unsigned int height, unsigned int format, unsigned int pitch, const CStdString& destFile);
44 44
   void           Close();
45  
-
46  
-  unsigned int   Width()       { return m_width; }
47  
-  unsigned int   Height()      { return m_height; }
48  
-  unsigned int   Orientation() { return m_orientation; }
  45
+  // methods for the imagefactory
  46
+  virtual bool   Decode(const unsigned char *pixels, unsigned int pitch, unsigned int format);
  47
+  virtual bool   LoadImageFromMemory(unsigned char* buffer, unsigned int bufSize, unsigned int width, unsigned int height);
  48
+  virtual bool   CreateThumbnailFromSurface(unsigned char* bufferin, unsigned int width, unsigned int height, unsigned int format, unsigned int pitch, const CStdString& destFile, 
  49
+                                            unsigned char* &bufferout, unsigned int &bufferoutSize);
  50
+  virtual void   ReleaseThumbnailBuffer();
49 51
 
50 52
 protected:
51 53
   static  void   jpeg_error_exit(j_common_ptr cinfo);
@@ -56,10 +58,7 @@ class CJpegIO
56 58
   unsigned int   m_inputBuffSize;
57 59
   struct         jpeg_decompress_struct m_cinfo;
58 60
   CStdString     m_texturePath;
59  
-
60  
-  unsigned int   m_width;
61  
-  unsigned int   m_height;
62  
-  unsigned int   m_orientation;
  61
+  unsigned char* m_thumbnailbuffer;
63 62
 };
64 63
 
65 64
 #endif
2  xbmc/guilib/Makefile.in
@@ -3,6 +3,7 @@ SRCS += DDSImage.cpp
3 3
 SRCS += DirectXGraphics.cpp
4 4
 SRCS += DirtyRegionSolvers.cpp
5 5
 SRCS += DirtyRegionTracker.cpp
  6
+SRCS += cximage.cpp
6 7
 SRCS += FrameBufferObject.cpp
7 8
 SRCS += GraphicContext.cpp
8 9
 SRCS += GUIAction.cpp
@@ -61,6 +62,7 @@ SRCS += GUIVisualisationControl.cpp
61 62
 SRCS += GUIWindow.cpp
62 63
 SRCS += GUIWindowManager.cpp
63 64
 SRCS += GUIWrappingListContainer.cpp
  65
+SRCS += imagefactory.cpp
64 66
 SRCS += IWindowManagerCallback.cpp
65 67
 SRCS += JpegIO.cpp
66 68
 SRCS += Key.cpp
209  xbmc/guilib/Texture.cpp
@@ -22,10 +22,9 @@
22 22
 #include "windowing/WindowingFactory.h"
23 23
 #include "utils/log.h"
24 24
 #include "utils/URIUtils.h"
25  
-#include "pictures/DllImageLib.h"
26 25
 #include "DDSImage.h"
27 26
 #include "filesystem/SpecialProtocol.h"
28  
-#include "JpegIO.h"
  27
+#include "filesystem/File.h"
29 28
 #if defined(TARGET_DARWIN_IOS)
30 29
 #include <ImageIO/ImageIO.h>
31 30
 #include "filesystem/File.h"
@@ -293,48 +292,87 @@ bool CBaseTexture::LoadFromFileInternal(const CStdString& texturePath, unsigned
293 292
     return false;
294 293
   }
295 294
 
296  
-  //ImageLib is sooo sloow for jpegs. Try our own decoder first. If it fails, fall back to ImageLib.
297  
-  CStdString Ext = URIUtils::GetExtension(texturePath);
298  
-  Ext.ToLower(); // Ignore case of the extension
299  
-  if (Ext.Equals(".jpg") || Ext.Equals(".jpeg") || Ext.Equals(".tbn"))
  295
+  unsigned int width = maxWidth ? std::min(maxWidth, g_Windowing.GetMaxTextureSize()) : g_Windowing.GetMaxTextureSize();
  296
+  unsigned int height = maxHeight ? std::min(maxHeight, g_Windowing.GetMaxTextureSize()) : g_Windowing.GetMaxTextureSize();
  297
+
  298
+  // Read image into memory to use our vfs
  299
+  unsigned char *inputBuff = NULL;
  300
+  unsigned int inputBuffSize = 0;
  301
+
  302
+  XFILE::CFile file;
  303
+  if (file.Open(texturePath.c_str(), READ_TRUNCATED))
300 304
   {
301  
-    CJpegIO jpegfile;
302  
-    if (jpegfile.Open(texturePath, maxWidth, maxHeight))
  305
+    /*
  306
+     GetLength() will typically return values that fall into three cases:
  307
+       1. The real filesize. This is the typical case.
  308
+       2. Zero. This is the case for some http:// streams for example.
  309
+       3. Some value smaller than the real filesize. This is the case for an expanding file.
  310
+
  311
+     In order to handle all three cases, we read the file in chunks, relying on Read()
  312
+     returning 0 at EOF.  To minimize (re)allocation of the buffer, the chunksize in
  313
+     cases 1 and 3 is set to one byte larger** than the value returned by GetLength().
  314
+     The chunksize in case 2 is set to the larger of 64k and GetChunkSize().
  315
+
  316
+     We fill the buffer entirely before reallocation.  Thus, reallocation never occurs in case 1
  317
+     as the buffer is larger than the file, so we hit EOF before we hit the end of buffer.
  318
+
  319
+     To minimize reallocation, we double the chunksize each time up to a maxchunksize of 2MB.
  320
+     */
  321
+    unsigned int filesize = (unsigned int)file.GetLength();
  322
+    unsigned int chunksize = filesize ? (filesize + 1) : std::max(65536U, (unsigned int)file.GetChunkSize());
  323
+    unsigned int maxchunksize = 2048*1024U; /* max 2MB chunksize */
  324
+    unsigned char *tempinputBuff = NULL;
  325
+
  326
+    unsigned int total_read = 0, free_space = 0;
  327
+    while (true)
303 328
     {
304  
-      if (jpegfile.Width() > 0 && jpegfile.Height() > 0)
305  
-      {
306  
-        Allocate(jpegfile.Width(), jpegfile.Height(), XB_FMT_A8R8G8B8);
307  
-        if (jpegfile.Decode(m_pixels, GetPitch(), XB_FMT_A8R8G8B8))
  329
+      if (!free_space)
  330
+      { // (re)alloc
  331
+        inputBuffSize += chunksize;
  332
+        tempinputBuff = (unsigned char *)realloc(inputBuff, inputBuffSize);
  333
+        if (!tempinputBuff)
308 334
         {
309  
-          if (autoRotate && jpegfile.Orientation())
310  
-            m_orientation = jpegfile.Orientation() - 1;
311  
-          m_hasAlpha=false;
312  
-          ClampToEdge();
313  
-          return true;
  335
+          CLog::Log(LOGERROR, "%s unable to allocate buffer of size %u", __FUNCTION__, inputBuffSize);
  336
+          free(inputBuff);
  337
+          file.Close();
  338
+          return false;
314 339
         }
  340
+        inputBuff = tempinputBuff;
  341
+        free_space = chunksize;
  342
+        chunksize = std::min(chunksize*2, maxchunksize);
315 343
       }
  344
+      unsigned int read = file.Read(inputBuff + total_read, free_space);
  345
+      free_space -= read;
  346
+      total_read += read;
  347
+      if (!read)
  348
+        break;
316 349
     }
317  
-    CLog::Log(LOGDEBUG, "%s - Load of %s failed. Falling back to ImageLib", __FUNCTION__, texturePath.c_str());
318  
-  }
  350
+    inputBuffSize = total_read;
  351
+    file.Close();
319 352
 
320  
-  DllImageLib dll;
321  
-  if (!dll.Load())
  353
+    if (inputBuffSize == 0)
  354
+      return false;
  355
+  }
  356
+  else
322 357
     return false;
323 358
 
324  
-  ImageInfo image;
325  
-  memset(&image, 0, sizeof(image));
326  
-
327  
-  unsigned int width = maxWidth ? std::min(maxWidth, g_Windowing.GetMaxTextureSize()) : g_Windowing.GetMaxTextureSize();
328  
-  unsigned int height = maxHeight ? std::min(maxHeight, g_Windowing.GetMaxTextureSize()) : g_Windowing.GetMaxTextureSize();
329  
-
330  
-  if(!dll.LoadImage(texturePath.c_str(), width, height, &image))
  359
+  CURL url(texturePath);
  360
+  IImage* pImage = ImageFactory::CreateLoader(url);
  361
+  if(!LoadIImage(pImage, inputBuff, inputBuffSize, width, height, autoRotate))
331 362
   {
332  
-    CLog::Log(LOGERROR, "Texture manager unable to load file: %s", texturePath.c_str());
333  
-    return false;
  363
+    delete pImage;
  364
+    pImage = NULL;
  365
+    pImage = ImageFactory::CreateFallbackLoader(texturePath);
  366
+    if(!LoadIImage(pImage, inputBuff, inputBuffSize, width, height))
  367
+    {
  368
+      CLog::Log(LOGDEBUG, "%s - Load of %s failed.", __FUNCTION__, texturePath.c_str());
  369
+      delete pImage;
  370
+      free(inputBuff);
  371
+      return false;
  372
+    }
334 373
   }
335  
-
336  
-  LoadFromImage(image, autoRotate);
337  
-  dll.ReleaseImage(&image);
  374
+  delete pImage;
  375
+  free(inputBuff);
338 376
 
339 377
   return true;
340 378
 }
@@ -344,98 +382,45 @@ bool CBaseTexture::LoadFromFileInMem(unsigned char* buffer, size_t size, const s
344 382
   if (!buffer || !size)
345 383
     return false;
346 384
 
347  
-  //ImageLib is sooo sloow for jpegs. Try our own decoder first. If it fails, fall back to ImageLib.
348  
-  if (mimeType == "image/jpeg")
349  
-  {
350  
-    CJpegIO jpegfile;
351  
-    if (jpegfile.Read(buffer, size, maxWidth, maxHeight))
352  
-    {
353  
-      if (jpegfile.Width() > 0 && jpegfile.Height() > 0)
354  
-      {
355  
-        Allocate(jpegfile.Width(), jpegfile.Height(), XB_FMT_A8R8G8B8);
356  
-        if (jpegfile.Decode(m_pixels, GetPitch(), XB_FMT_A8R8G8B8))
357  
-        {
358  
-          m_hasAlpha=false;
359  
-          ClampToEdge();
360  
-          return true;
361  
-        }
362  
-      }
363  
-    }
364  
-  }
365  
-  DllImageLib dll;
366  
-  if (!dll.Load())
367  
-    return false;
368  
-
369  
-  ImageInfo image;
370  
-  memset(&image, 0, sizeof(image));
371  
-
372 385
   unsigned int width = maxWidth ? std::min(maxWidth, g_Windowing.GetMaxTextureSize()) : g_Windowing.GetMaxTextureSize();
373 386
   unsigned int height = maxHeight ? std::min(maxHeight, g_Windowing.GetMaxTextureSize()) : g_Windowing.GetMaxTextureSize();
374 387
 
375  
-  CStdString ext = mimeType;
376  
-  int nPos = ext.Find('/');
377  
-  if (nPos > -1)
378  
-    ext.Delete(0, nPos + 1);
379  
-
380  
-  if(!dll.LoadImageFromMemory(buffer, size, ext.c_str(), width, height, &image))
  388
+  IImage* pImage = ImageFactory::CreateLoaderFromMimeType(mimeType);
  389
+  if(!LoadIImage(pImage, buffer, size, width, height))
381 390
   {
382  
-    CLog::Log(LOGERROR, "Texture manager unable to load image from memory");
383  
-    return false;
  391
+    delete pImage;
  392
+    pImage = NULL;
  393
+    pImage = ImageFactory::CreateFallbackLoader(mimeType);
  394
+    if(!LoadIImage(pImage, buffer, size, width, height))
  395
+    {
  396
+      delete pImage;
  397
+      return false;
  398
+    }
384 399
   }
385  
-  LoadFromImage(image);
386  
-  dll.ReleaseImage(&image);
387  
-
  400
+  delete pImage;
388 401
   return true;
389 402
 }
390 403
 
391  
-void CBaseTexture::LoadFromImage(ImageInfo &image, bool autoRotate)
  404
+bool CBaseTexture::LoadIImage(IImage *pImage, unsigned char* buffer, unsigned int bufSize, unsigned int width, unsigned int height, bool autoRotate)
392 405
 {
393  
-  m_hasAlpha = NULL != image.alpha;
394  
-
395  
-  Allocate(image.width, image.height, XB_FMT_A8R8G8B8);
396  
-  if (autoRotate && image.exifInfo.Orientation)
397  
-    m_orientation = image.exifInfo.Orientation - 1;
398  
-  m_originalWidth = image.originalwidth;
399  
-  m_originalHeight = image.originalheight;
400  
-
401  
-  unsigned int dstPitch = GetPitch();
402  
-  unsigned int srcPitch = ((image.width + 1)* 3 / 4) * 4; // bitmap row length is aligned to 4 bytes
403  
-
404  
-  unsigned char *dst = m_pixels;
405  
-  unsigned char *src = image.texture + (m_imageHeight - 1) * srcPitch;
406  
-
407  
-  for (unsigned int y = 0; y < m_imageHeight; y++)
408  
-  {
409  
-    unsigned char *dst2 = dst;
410  
-    unsigned char *src2 = src;
411  
-    for (unsigned int x = 0; x < m_imageWidth; x++, dst2 += 4, src2 += 3)
412  
-    {
413  
-      dst2[0] = src2[0];
414  
-      dst2[1] = src2[1];
415  
-      dst2[2] = src2[2];
416  
-      dst2[3] = 0xff;
417  
-    }
418  
-    src -= srcPitch;
419  
-    dst += dstPitch;
420  
-  }
421  
-
422  
-  if(image.alpha)
  406
+  if(pImage != NULL && pImage->LoadImageFromMemory(buffer, bufSize, width, height))
423 407
   {
424  
-    dst = m_pixels + 3;
425  
-    src = image.alpha + (m_imageHeight - 1) * m_imageWidth;
426  
-
427  
-    for (unsigned int y = 0; y < m_imageHeight; y++)
  408
+    if (pImage->Width() > 0 && pImage->Height() > 0)
428 409
     {
429  
-      unsigned char *dst2 = dst;
430  
-      unsigned char *src2 = src;
431  
-
432  
-      for (unsigned int x = 0; x < m_imageWidth; x++,  dst2+=4, src2++)
433  
-        *dst2 = *src2;
434  
-      src -= m_imageWidth;
435  
-      dst += dstPitch;
  410
+      Allocate(pImage->Width(), pImage->Height(), XB_FMT_A8R8G8B8);
  411
+      if (pImage->Decode(m_pixels, GetPitch(), XB_FMT_A8R8G8B8))
  412
+      {
  413
+        if (autoRotate && pImage->Orientation())
  414
+          m_orientation = pImage->Orientation() - 1;
  415
+        m_hasAlpha = pImage->hasAlpha();
  416
+        m_originalWidth = pImage->originalWidth();
  417
+        m_originalHeight = pImage->originalHeight();
  418
+        ClampToEdge();
  419
+        return true;
  420
+      }
436 421
     }
437 422
   }
438  
-  ClampToEdge();
  423
+  return false;
439 424
 }
440 425
 
441 426
 bool CBaseTexture::LoadFromMemory(unsigned int width, unsigned int height, unsigned int pitch, unsigned int format, bool hasAlpha, unsigned char* pixels)
4  xbmc/guilib/Texture.h
@@ -24,6 +24,7 @@
24 24
 #include "gui3d.h"
25 25
 #include "utils/StdString.h"
26 26
 #include "XBTF.h"
  27
+#include "guilib/imagefactory.h"
27 28
 
28 29
 #pragma pack(1)
29 30
 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
32 33
 class CTexture;
33 34
 class CGLTexture;
34 35
 class CDXTexture;
35  
-struct ImageInfo;
36 36
 
37 37
 /*!
38 38
 \ingroup textures
@@ -111,7 +111,7 @@ class CBaseTexture
111 111
   bool LoadFromFileInMem(unsigned char* buffer, size_t size, const std::string& mimeType,
112 112
                          unsigned int maxWidth, unsigned int maxHeight);
113 113
   bool LoadFromFileInternal(const CStdString& texturePath, unsigned int maxWidth, unsigned int maxHeight, bool autoRotate);
114  
-  void LoadFromImage(ImageInfo &image, bool autoRotate = false);
  114
+  bool LoadIImage(IImage* pImage, unsigned char* buffer, unsigned int bufSize, unsigned int width, unsigned int height, bool autoRotate=false);
115 115
   // helpers for computation of texture parameters for compressed textures
116 116
   unsigned int GetPitch(unsigned int width) const;
117 117
   unsigned int GetRows(unsigned int height) const;
131  xbmc/guilib/cximage.cpp
... ...
@@ -0,0 +1,131 @@
  1
+/*
  2
+ *      Copyright (C) 2012 Team XBMC
  3
+ *      http://www.xbmc.org
  4
+ *
  5
+ *  This Program is free software; you can redistribute it and/or modify
  6
+ *  it under the terms of the GNU General Public License as published by
  7
+ *  the Free Software Foundation; either version 2, or (at your option)
  8
+ *  any later version.
  9
+ *
  10
+ *  This Program is distributed in the hope that it will be useful,
  11
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13
+ *  GNU General Public License for more details.
  14
+ *
  15
+ *  You should have received a copy of the GNU General Public License
  16
+ *  along with XBMC; see the file COPYING.  If not, write to
  17
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  18
+ *  http://www.gnu.org/copyleft/gpl.html
  19
+ *
  20
+ */
  21
+#include "cximage.h"
  22
+#include "utils/log.h"
  23
+
  24
+CXImage::CXImage(const std::string& strMimeType): m_strMimeType(strMimeType), m_thumbnailbuffer(NULL)
  25
+{
  26
+  m_hasAlpha = false;
  27
+  memset(&m_image, 0, sizeof(m_image));
  28
+  m_dll.Load();
  29
+}
  30
+
  31
+CXImage::~CXImage()
  32
+{
  33
+  m_dll.FreeMemory(m_thumbnailbuffer);
  34
+  m_dll.ReleaseImage(&m_image);
  35
+  m_dll.Unload();
  36
+}
  37
+
  38
+bool CXImage::LoadImageFromMemory(unsigned char* buffer, unsigned int bufSize, unsigned int width, unsigned int height)
  39
+{
  40
+  if (!m_dll.IsLoaded())
  41
+    return false;
  42
+
  43
+  memset(&m_image, 0, sizeof(m_image));
  44
+
  45
+  std::string strExt = m_strMimeType;
  46
+  int nPos = strExt.find('/');
  47
+  if (nPos > -1)
  48
+    strExt.erase(0, nPos + 1);
  49
+
  50
+  if(!m_dll.LoadImageFromMemory(buffer, bufSize, strExt.c_str(), width, height, &m_image))
  51
+  {
  52
+    CLog::Log(LOGERROR, "Texture manager unable to load image from memory");
  53
+    return false;
  54
+  }
  55
+
  56
+  m_hasAlpha = NULL != m_image.alpha;
  57
+  m_width = m_image.width;
  58
+  m_height = m_image.height;
  59
+  m_orientation = m_image.exifInfo.Orientation;
  60
+  m_originalWidth = m_image.originalwidth;
  61
+  m_originalHeight = m_image.originalheight;
  62
+  return true;
  63
+}
  64
+
  65
+bool CXImage::Decode(const unsigned char *pixels, unsigned int pitch, unsigned int format)
  66
+{
  67
+  if (m_image.width == 0 || m_image.width == 0 || !m_dll.IsLoaded())
  68
+    return false;
  69
+
  70
+  unsigned int dstPitch = pitch;
  71
+  unsigned int srcPitch = ((m_image.width + 1)* 3 / 4) * 4; // bitmap row length is aligned to 4 bytes
  72
+
  73
+  unsigned char *dst = (unsigned char*)pixels;
  74
+  unsigned char *src = m_image.texture + (m_height - 1) * srcPitch;
  75
+
  76
+  for (unsigned int y = 0; y < m_height; y++)
  77
+  {
  78
+    unsigned char *dst2 = dst;
  79
+    unsigned char *src2 = src;
  80
+    for (unsigned int x = 0; x < m_width; x++, dst2 += 4, src2 += 3)
  81
+    {
  82
+      dst2[0] = src2[0];
  83
+      dst2[1] = src2[1];
  84
+      dst2[2] = src2[2];
  85
+      dst2[3] = 0xff;
  86
+    }
  87
+    src -= srcPitch;
  88
+    dst += dstPitch;
  89
+  }
  90
+
  91
+  if(m_image.alpha)
  92
+  {
  93
+    dst = (unsigned char*)pixels + 3;
  94
+    src = m_image.alpha + (m_height - 1) * m_width;
  95
+
  96
+    for (unsigned int y = 0; y < m_height; y++)
  97
+    {
  98
+      unsigned char *dst2 = dst;
  99
+      unsigned char *src2 = src;
  100
+
  101
+      for (unsigned int x = 0; x < m_width; x++,  dst2+=4, src2++)
  102
+        *dst2 = *src2;
  103
+      src -= m_width;
  104
+      dst += dstPitch;
  105
+    }
  106
+  }
  107
+
  108
+  m_dll.ReleaseImage(&m_image);
  109
+  memset(&m_image, 0, sizeof(m_image));
  110
+  return true;
  111
+}
  112
+
  113
+bool CXImage::CreateThumbnailFromSurface(unsigned char* bufferin, unsigned int width, unsigned int height, unsigned int format, unsigned int pitch, const CStdString& destFile, 
  114
+                                         unsigned char* &bufferout, unsigned int &bufferoutSize)
  115
+{
  116
+  if (!bufferin || !m_dll.IsLoaded()) 
  117
+    return false;
  118
+
  119
+  bool ret = m_dll.CreateThumbnailFromSurface2((BYTE *)bufferin, width, height, pitch, destFile.c_str(), m_thumbnailbuffer, bufferoutSize);
  120
+  bufferout = m_thumbnailbuffer;
  121
+  return ret;
  122
+}
  123
+
  124
+void CXImage::ReleaseThumbnailBuffer()
  125
+{
  126
+  if (!m_dll.IsLoaded())
  127
+    return;
  128
+
  129
+  m_dll.FreeMemory(m_thumbnailbuffer);
  130
+  m_thumbnailbuffer = NULL;
  131
+}
43  xbmc/guilib/cximage.h
... ...
@@ -0,0 +1,43 @@
  1
+#pragma once
  2
+/*
  3
+ *      Copyright (C) 2012 Team XBMC
  4
+ *      http://www.xbmc.org
  5
+ *
  6
+ *  This Program is free software; you can redistribute it and/or modify
  7
+ *  it under the terms of the GNU General Public License as published by
  8
+ *  the Free Software Foundation; either version 2, or (at your option)
  9
+ *  any later version.
  10
+ *
  11
+ *  This Program is distributed in the hope that it will be useful,
  12
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14
+ *  GNU General Public License for more details.
  15
+ *
  16
+ *  You should have received a copy of the GNU General Public License
  17
+ *  along with XBMC; see the file COPYING.  If not, write to
  18
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  19
+ *  http://www.gnu.org/copyleft/gpl.html
  20
+ *
  21
+ */
  22
+
  23
+#include "iimage.h"
  24
+#include "pictures/DllImageLib.h"
  25
+
  26
+class CXImage : public IImage
  27
+{
  28
+public:
  29
+  CXImage(const std::string& strMimeType);
  30
+  ~CXImage();
  31
+
  32
+  virtual bool LoadImageFromMemory(unsigned char* buffer, unsigned int bufSize, unsigned int width, unsigned int height);
  33
+  virtual bool Decode(const unsigned char *pixels, unsigned int pitch, unsigned int format);
  34
+  virtual bool CreateThumbnailFromSurface(unsigned char* bufferin, unsigned int width, unsigned int height, unsigned int format, unsigned int pitch, const CStdString& destFile, 
  35
+                                          unsigned char* &bufferout, unsigned int &bufferoutSize);
  36
+  virtual void ReleaseThumbnailBuffer();
  37
+
  38
+private:
  39
+  DllImageLib m_dll;
  40
+  ImageInfo m_image;
  41
+  std::string m_strMimeType;
  42
+  BYTE* m_thumbnailbuffer;
  43
+};
84  xbmc/guilib/iimage.h
... ...
@@ -0,0 +1,84 @@
  1
+#pragma once
  2
+/*
  3
+*      Copyright (C) 2012 Team XBMC
  4
+*      http://www.xbmc.org
  5
+*
  6
+*  This Program is free software; you can redistribute it and/or modify
  7
+*  it under the terms of the GNU General Public License as published by
  8
+*  the Free Software Foundation; either version 2, or (at your option)
  9
+*  any later version.
  10
+*
  11
+*  This Program is distributed in the hope that it will be useful,
  12
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14
+*  GNU General Public License for more details.
  15
+*
  16
+*  You should have received a copy of the GNU General Public License
  17
+*  along with XBMC; see the file COPYING.  If not, write to
  18
+*  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  19
+*  http://www.gnu.org/copyleft/gpl.html
  20
+*
  21
+*/
  22
+#include "utils/StdString.h"
  23
+
  24
+class IImage
  25
+{
  26
+public:
  27
+
  28
+  IImage():m_width(0), m_height(0), m_originalWidth(0), m_originalHeight(0), m_orientation(0), m_hasAlpha(false) {};
  29
+  virtual ~IImage() {};
  30
+
  31
+  /*!
  32
+   \brief Load an image from memory with the format m_strMimeType to determine it's size and orientation
  33
+   \param buffer The memory location where the image data can be found
  34
+   \param bufSize The size of the buffer
  35
+   \param width The ideal width of the texture
  36
+   \param height The ideal height of the texture
  37
+   \return true if the image could be loaded
  38
+   */
  39
+  virtual bool LoadImageFromMemory(unsigned char* buffer, unsigned int bufSize, unsigned int width, unsigned int height)=0;
  40
+  /*!
  41
+   \brief Decodes the previously loaded image data to the output buffer in 32 bit raw bits
  42
+   \param pixels The output buffer
  43
+   \param pitch The pitch of the output buffer
  44
+   \param format The format of the output buffer (JpegIO only)
  45
+   \return true if the image data could be decoded to the output buffer
  46
+   */
  47
+  virtual bool Decode(const unsigned char *pixels, unsigned int pitch, unsigned int format)=0;
  48
+  /*!
  49
+   \brief Encodes an thumbnail from raw bits of given memory location
  50
+   \remarks Caller need to call ReleaseThumbnailBuffer() afterwards to free the output buffer
  51
+   \param bufferin The memory location where the image data can be found
  52
+   \param width The width of the thumbnail
  53
+   \param height The height of the thumbnail
  54
+   \param format The format of the input buffer (JpegIO only)
  55
+   \param pitch The pitch of the input texture stored in bufferin
  56
+   \param destFile The destination path of the thumbnail to determine the image format from the extension
  57
+   \param bufferout The output buffer (will be allocated inside the method)
  58
+   \param bufferoutSize The output buffer size
  59
+   \return true if the thumbnail was successfully created
  60
+   */
  61
+  virtual bool CreateThumbnailFromSurface(unsigned char* bufferin, unsigned int width, unsigned int height, unsigned int format, unsigned int pitch, const CStdString& destFile, 
  62
+                                          unsigned char* &bufferout, unsigned int &bufferoutSize)=0;
  63
+  /*!
  64
+   \brief Frees the output buffer allocated by CreateThumbnailFromSurface
  65
+   */
  66
+  virtual void ReleaseThumbnailBuffer() {return;}
  67
+
  68
+  unsigned int Width()              { return m_width; }
  69
+  unsigned int Height()             { return m_height; }
  70
+  unsigned int originalWidth()      { return m_originalWidth; }
  71
+  unsigned int originalHeight()     { return m_originalHeight; }
  72
+  unsigned int Orientation()        { return m_orientation; }
  73
+  bool hasAlpha()                   { return m_hasAlpha; }
  74
+
  75
+protected:
  76
+
  77
+  unsigned int m_width;
  78
+  unsigned int m_height;
  79
+  unsigned int m_originalWidth;   ///< original image width before scaling or cropping
  80
+  unsigned int m_originalHeight;  ///< original image height before scaling or cropping
  81
+  unsigned int m_orientation;
  82
+  bool m_hasAlpha;
  83
+ 
  84
+};
52  xbmc/guilib/imagefactory.cpp
... ...
@@ -0,0 +1,52 @@
  1
+/*
  2
+ *      Copyright (C) 2012 Team XBMC
  3
+ *      http://www.xbmc.org
  4
+ *
  5
+ *  This Program is free software; you can redistribute it and/or modify
  6
+ *  it under the terms of the GNU General Public License as published by
  7
+ *  the Free Software Foundation; either version 2, or (at your option)
  8
+ *  any later version.
  9
+ *
  10
+ *  This Program is distributed in the hope that it will be useful,
  11
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13
+ *  GNU General Public License for more details.
  14
+ *
  15
+ *  You should have received a copy of the GNU General Public License
  16
+ *  along with XBMC; see the file COPYING.  If not, write to
  17
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  18
+ *  http://www.gnu.org/copyleft/gpl.html
  19
+ *
  20
+ */
  21
+
  22
+#include "imagefactory.h"
  23
+#include "guilib/JpegIO.h"
  24
+#include "guilib/cximage.h"
  25
+
  26
+IImage* ImageFactory::CreateLoader(const std::string& strFileName)
  27
+{
  28
+  CURL url(strFileName);
  29
+  return CreateLoader(url);
  30
+}
  31
+
  32
+IImage* ImageFactory::CreateLoader(const CURL& url)
  33
+{
  34
+  return CreateLoaderFromMimeType("image/"+url.GetFileType());
  35
+}
  36
+
  37
+IImage* ImageFactory::CreateLoaderFromMimeType(const std::string& strMimeType)
  38
+{
  39
+  if(strMimeType == "image/jpeg" || strMimeType == "image/tbn" || strMimeType == "image/jpg")
  40
+    return new CJpegIO();
  41
+  return new CXImage(strMimeType);
  42
+}
  43
+
  44
+IImage* ImageFactory::CreateFallbackLoader(const std::string& strMimeType)
  45
+{
  46
+  return new CXImage(strMimeType);
  47
+}
  48
+
  49
+IImage* ImageFactory::CreateFallbackLoader(const CURL& url)
  50
+{
  51
+  return new CXImage("image/"+url.GetFileType());
  52
+}
37  xbmc/guilib/imagefactory.h
... ...
@@ -0,0 +1,37 @@
  1
+#pragma once
  2
+/*
  3
+ *      Copyright (C) 2012 Team XBMC