[Windows Mobile Software Development] Nixeus:
Hello my friend,

As you know, when you select a wallpaper for Sense, it compress it and resize it to JPEG in a file named HomeBackground.img.

If you open this HomeBackground.img in a imaging software like Gimp or Photoshop, you can see that the quality is good on your PC but not when you set it as walpapper.

So i think that manila recompress it on the fly before display it.

I have disassembled the Manila.exe and the dll with ida pro in order to find any compression function but....no found !

Second step, i have download the manila kitchen and decompilled all the manila files. With a multi text file searcher, i have searched the occurence "HomeBackground.img" and i have founbd this file :

090a4ee8_manila

Here is the code of the file decompilled

-- Decompiled using luadec 3.2.2beta -- Fri Jun 10 23:16:41 2011
-- File name: 090a4ee8_manila

require("asyncimageloader")
require("shell_svc")
CachedImagePath = "\\Windows\\HomeBackground.img"

InterpolateOpacity = function(l_1_0, l_1_1)
l_1_1.Opacity:Interpolate(l_1_0, 20, 0, Interpolate_EaseOutQuad)
end

BackgroundWidth = 480
BackgroundHeight = 696
if _application.Store:GetStringValue(Lifetime_Permanent, "DevResolution") == "HVGA" then
BackgroundWidth = 320
BackgroundHeight = 410
end
LoadDefaultBackground = function()
trace("LoadDefaultBackground()")
InterpolateOpacity(0, HomeBackground)
if HomeTitleBar ~= nil then
HomeTitleBar.Opacity.value = 0
_application.Navigation.TabTrayOpacity = 100
end
end

BackgroundImageLoaded = function(l_3_0, l_3_1)
trace("BackgroundImageLoaded")
if l_3_0 then
if l_3_1 == 1 then
HomeBackground.TextureCoords.width = l_3_0.TextureCoords.width
HomeBackground.TextureCoords.height = l_3_0.TextureCoords.height
local l_3_2 = l_3_0.TextureCoords.width * l_3_0.Image.Width
local l_3_3 = l_3_0.TextureCoords.height * l_3_0.Image.Height
_StoreImageWidth = l_3_2
_StoreImageHeight = l_3_3
local l_3_4 = l_3_2 / BackgroundWidth
local l_3_5 = l_3_3 / BackgroundHeight
if l_3_4 < l_3_5 then
HomeBackground.Size.height = l_3_3 / l_3_2 * BackgroundWidth
HomeBackground.Size.width = BackgroundWidth
else
HomeBackground.Size.width = l_3_2 / l_3_3 * BackgroundHeight
HomeBackground.Size.height = BackgroundHeight
end
HomeBackground.Position.x = (BackgroundWidth - HomeBackground.Size.width) / 2
HomeBackground.Position.y = -(BackgroundHeight - HomeBackground.Size.height) / 2
HomeBackground:SetTexture(l_3_0.Image)
InterpolateOpacity(100, HomeBackground)
if HomeTitleBar ~= nil then
local l_3_6 = _application.Store:GetIntValue(Lifetime_Application, "ShowCacheHomePage")
if l_3_6 == 1 then
HomeTitleBar.Opacity.value = 60
_application.Navigation.TabTrayOpacity = 60
end
end
else
LoadDefaultBackground()
end
collectgarbage("collect")
BackgroundAsyncImageLoader = nil
elseif _StoreImageWidth and _StoreImageHeight then
local l_3_7 = _StoreImageWidth / BackgroundWidth
local l_3_8 = _StoreImageHeight / BackgroundHeight
if l_3_7 < l_3_8 then
HomeBackground.Size.height = _StoreImageHeight / _StoreImageWidth * BackgroundWidth
HomeBackground.Size.width = BackgroundWidth
else
HomeBackground.Size.width = _StoreImageWidth / _StoreImageHeight * BackgroundHeight
HomeBackground.Size.height = BackgroundHeight
end
HomeBackground.Position.x = (BackgroundWidth - HomeBackground.Size.width) / 2
HomeBackground.Position.y = -(BackgroundHeight - HomeBackground.Size.height) / 2
end
_application.Store:SetIntValue(Lifetime_Application, "Home.BackgroundMaskFadeOut", 0)
if HomeBackgroundMask.Opacity.value ~= 0 then
HomeBackgroundMask.Opacity:Interpolate(0, 20, 0, Interpolate_Linear)
end
end

BeginLoadBackgroundImage = function(l_4_0)
trace("BeginLoadBackgroundImage")
if Shell_HaveDRMRightsToFile(machineStatus.HomeBackgroundPath.Value, false) then
BackgroundAsyncImageLoader = AsyncImageLoader()
BackgroundAsyncImageLoader.Priority = TaskPriority_Normal
BackgroundAsyncImageLoader.OnComplete:connect(BackgroundImageLoaded)
BackgroundAsyncImageLoader:BeginLoadFile(l_4_0, false, true)
else
machineStatus.HomeBackgroundPath.Value = ""
machineStatus.CachedBackgroundPath.Value = ""
LoadDefaultBackground()
end
end

BackgroundImageResized = function(l_5_0, l_5_1)
trace("BackgroundImageResized")
trace("[homebackground] : HomePath = " .. tostring(machineStatus.HomeBackgroundPath.Value))
trace("[homebackground] : CachedPath = " .. tostring(machineStatus.CachedBackgroundPath.Value))
if l_5_1 == 1 and machineStatus.HomeBackgroundPath.Value ~= "" then
machineStatus.CachedBackgroundPath.Value = machineStatus.HomeBackgroundPath.Value
BeginLoadBackgroundImage(CachedImagePath)
else
trace("result = 0")
LoadDefaultBackground()
BackgroundAsyncImageLoader = nil
end
AnimationDelayHandler()
trace("BackgroundImageResized end")
trace("[homebackground] : HomePath = " .. tostring(machineStatus.HomeBackgroundPath.Value))
trace("[homebackground] : CachedPath = " .. tostring(machineStatus.CachedBackgroundPath.Value))
collectgarbage("collect")
end

machineStatus_OnCustomBackgroundUpdate = function()
trace("machineStatus_OnCustomBackgroundUpdate")
if _config_os == "windowsmobile" then
local l_6_0 = machineStatus.HomeBackgroundPath.Value
local l_6_1 = machineStatus.CachedBackgroundPath.Value
trace("[homebackground] : HomePath = " .. tostring(l_6_0))
trace("[homebackground] : CachedPath = " .. tostring(l_6_1))
if l_6_0 ~= l_6_1 then
if BackgroundAsyncImageFactoryLoader ~= nil and BackgroundAsyncImageFactoryLoader:IsRunning() then
BackgroundAsyncImageFactoryLoader.OnComplete:disconnect(BackgroundImageResized)
BackgroundAsyncImageFactoryLoader:Cancel()
BackgroundAsyncImageFactoryLoader = nil
collectgarbage("collect")
end
if BackgroundAsyncImageLoader ~= nil and BackgroundAsyncImageLoader:IsRunning() then
BackgroundAsyncImageLoader:Cancel()
BackgroundAsyncImageLoader = nil
collectgarbage("collect")
end
if l_6_0 == "" then
machineStatus.CachedBackgroundPath.Value = machineStatus.HomeBackgroundPath.Value
LoadDefaultBackground()
else
BackgroundAsyncImageFactoryLoader = AsyncImageFactoryLoader()
BackgroundAsyncImageFactoryLoader.Priority = TaskPriority_BelowNormal
BackgroundAsyncImageFactoryLoader.Quality = 100
BackgroundAsyncImageFactoryLoader.OnComplete:connect(BackgroundImageResized)
BackgroundAsyncImageFactoryLoader:ResizeImage(machineStatus.HomeBackgroundPath.Value, CachedImagePath, EncoderType_JPEG, 512, 512, true, false)
end
elseif l_6_1 ~= "" then
if BackgroundAsyncImageFactoryLoader ~= nil and BackgroundAsyncImageFactoryLoader:IsRunning() then
BackgroundAsyncImageFactoryLoader.OnComplete:disconnect(BackgroundImageResized)
BackgroundAsyncImageFactoryLoader:Cancel()
BackgroundAsyncImageFactoryLoader = nil
bRefreshBackground = true
collectgarbage("collect")
end
if BackgroundAsyncImageLoader ~= nil and BackgroundAsyncImageLoader:IsRunning() then
BackgroundAsyncImageLoader:Cancel()
BackgroundAsyncImageLoader = nil
bRefreshBackground = true
collectgarbage("collect")
end
if bRefreshBackground then
trace("[homebackground] : Change wallpaper too quickly and home and cache registry are the same, but loader is running, so load home background again.")
machineStatus.CachedBackgroundPath.Value = ""
machineStatus_OnCustomBackgroundUpdate()
else
BeginLoadBackgroundImage(CachedImagePath)
end
else
LoadDefaultBackground()
end
else
LoadDefaultBackground()
end
end

AnimationDelayHandler = function()
local l_7_0 = _application.Store:GetIntValue(Lifetime_Permanent, "Home.WallpaperMode")
local l_7_1 = _application.Store:GetIntValue(Lifetime_Application, "DelayAnimationEffect")
if l_7_0 == 1 and l_7_1 == 1 then
if _AnimationWallpaper then
_AnimationWallpaper:Show()
end
_application.Store:SetIntValue(Lifetime_Application, "DelayAnimationEffect", 0)
end
end

if _application.Store:GetStringValue(Lifetime_Permanent, "EnableLandscape") == "true" then
require("RotationTemplate")
homebackground_ScreenRotation = class(RotationTemplate)
homebackground_ScreenRotation.__init = function(l_8_0)
RotationTemplate.__init(l_8_0)
trace("+++++++[homebackground] : __init")
end

homebackground_ScreenRotation.OnScreenRotation = function(l_9_0)
trace("+++++++[homebackground] : OnScreenRotation")
if _application.Orientation == ScreenOrientation_Portrait then
BackgroundWidth = 480
BackgroundHeight = 696
elseif _application.Orientation == ScreenOrientation_Landscape then
BackgroundWidth = 805
BackgroundHeight = 376
end
BackgroundImageLoaded(nil, nil)
end

end
if _config_os == "windowsmobile" then
if _application.Store:GetStringValue(Lifetime_Permanent, "EnableLandscape") == "true" then
_homebackground_ScreenRotation = homebackground_ScreenRotation()
end
machineStatus.HomeBackgroundPath.OnValueChanged:connect(machineStatus_OnCustomBackgroundUpdate)
machineStatus_OnCustomBackgroundUpdate()
end

At the line 141 tou can see this :

BackgroundAsyncImageFactoryLoader:ResizeImage(machineStatus.HomeBackgroundPath.Value, CachedImagePath, EncoderType_JPEG, [B]512[/B], [B]512[/B], true, false)

* If you delete this line, the wallpaper don't display !

* The 512,512 are the width and height values, so i think it's better to replace them by 480 , 696 ( the real width and height)--> Warning, you need to use a walpapper with a heigh and width of 480x696 :)

With this, the image will be

better

.

BUT it's not finish !

When you modify this file and recompile it, you can see thaht you walpapper is not cropped but, the quality is always not good.

Look at this :

And with a zoom :

--> So you can see that there is even a compression thaht destruct the quality, but where is it ?

I would like to find a way of bypassing a function of recompression but i don't found it. I would like to investigate on this project with some people, so if anyone have some informations about this, it will be very great !

So, you can contact me on this thread or by PM !

If you want to help me, it's very simple :

1) Download the manila kitchen here : http://xdaforums.com/showthread.php?t=528548

2) Copy all your *manila* files on the "source" folder.

3) Read the .doc or the .pdf document that explain how decompile this file ( it's very very easy)

4) Investigate about improving walpapper quality :)

I know that the truth is near, but i need some help !

Thanks a lot for all people that could help me to create this hack.

Best regards,

Nixeus