This is a hybrid batch and C program that I wrote to decode and encode the MotoLogo image container. I originally wrote it for the Nexus 6, but it works on your device too. It will allow you to edit or replace any of the images in your logo partition. This will also work with any Motorola device utilizing this current format.
The logo partition has nothing to do with your boot animation. Your boot animation actually comes right after the static image that is one of the several images you can change with this tool. Your boot animation follows after this screen goes away, your boot animation is typically animated or dynamic. The static screen is known as your splash screen to some, or boot screen to others. This tool allows you to change the static image (splash screen) and not your boot animation!Thanks to GrayBoltWolf for making this video!!
This video was made using a Nexus 6, but the encoding of the logo.bin is identical. When I made this program, I made it with the mindset of being able to use it to edit ANY MotoLogo image container, even if it's an electronic billboard. I did not include the Nexus 6 bootlader in this version for obvious reasons. But you will just drag and drop your logo.bin from your phone, or if you have an unzipped bootloader (like I provided for the Nexus 6), you can just drag that. The program will find the MotoLogo container in it and cut it out.
Download the "MotoLogo Injector v.1.1" zip file at the bottom of this post.
Extract the zip file to a new folder.
To use just drag any file (your "logo.bin") that you think might have a MotoLogo container in it onto the batch file "MotoLogo_Injectorv1.1.bat"
The program will then find the Container in the file, extract it and validate every byte in it, and output it in the "Projects" folder.
A newly created folder will pop up that contains the raw image files, PNG image files, some identification files, and your extracted "logo.bin"
There will also be two new batch files in the folder that will make it easy to close the program, edit the images, then just click one of the batch files to get back into the program to re-encode the images. The difference in the two batch files is that one of them will re-encode the logo bin in a "Strict" way, and the other way is "Non-Strict"
Strict goes in the exact same order that the images were encoded in the first place.
Strict will fail if there are any more or any less images.
Strict will fail if any of the image names are changed.
Strict will check the resolution.
Strict will not let you have a Jpg, Bmp, ....any other format mixed in with the Pngs. (If you prefer to work with another image format, you can change that in the settings but you still can't mix them up inside of the "Images" folder; they should all be of the same type.
If an images resolution doesn't match the original images, it will warn you and give you options to resize or disregard the size difference.
Non-Strict simply goes through every file in the "Images" folder in alphanumerical order and makes it a raw file, encodes it, and puts the MotoLogo container together.
Non-Strict will take all kinds of differently formatted images.
The only reason I can see someone wanting to use Non-Strict is to delete images from a MotoLogo container.
In your "Images" folder is where you either edit or replace the PNG images. You can make them bigger, but I don't know what implications this may have as I do not have a device to test on. You must keep the names the exact same as the images, it is okay to change the image or even replace it (that's the whole point) but you have to keep the names the same for Strict mode, which I encourage you to use.
When you are finished editing your images:
You can open up the Original batch program if you haven't used it anymore (it remembers the last file loaded that had a successful validated container in it, so you don't have to drag and drop everytime). And then hit 1 "Rebuild Images Directory (Strict-In Order_Resolution Checks)"
Or you can click on the "Make MotoLogo Bin From Images Folder.bat" to go directly there.
After the program has rebuilt it, it will re validate the container, and then reconvert the container into view-able Pngs again. A new folder will automatically open. This contains your modified container called "build.bin". You can flash it from there.
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
v.97b Initial Release
v.1.0
Fixed error with Moto X Style bg encoded image size being evenly divisible by 512
Made logging to the screen default so you can tell it's working and not hung up
Changed default image extension from "Png" to "png"
v.1.1
Fixed Settings Bug
I am not responsible for any damage done to your device!! Source is in Posts 2 & 3!
SOURCE:
SOURCE:
MotoLogo_Injectorv1.1.bat
Code:
@echo off&setlocal enabledelayedexpansion
MODE CON:COLS=78 LINES=1024&set "vers=1.1"
color 0b
title Motorola Image Injector v%vers%
cd /d "%~dp0"
set "file=%~1"
set /a "aspectMultiplier=100000"
set "useDefaultViewer="
set "syslog=>>"%~dp0sys\log.txt""
set "ffmpeglog="
set "validlog="
set "codeclog="
set "rawBGRDir=Raw_BGR_Files"
set "imagesDir=Images"
set "mrDir=Raw_MR_Files"
set "workHere=Projects"
set "IDfile=MoID.ID"
set "buildFile=build.ID"
set "dontShowInfo=0"
set "autoOpenFolders=1"
set "prevailExt=png"
if not exist "%~dp0sys\" mkdir "%~dp0sys"
if exist "%~dp0sys\settings.cfg" (call :LoadSetFile)
if "%dontShowInfo%"=="1" set "validlog=>>"%~dp0sys\validation_log.txt" 2>&1" &set "codeclog=>>"%~dp0sys\codec_log.txt" 2>&1" &set "ffmpeglog=>>"%~dp0sys\ffmpeg_log.txt" 2>&1"
if exist "%~dp0sys\last_file" if "[%file%]"=="[]" call :Existing
if /i "[%file%]" equ "[$$$convert$$$]" set "file=%~2" &set "home=%~3" &call :SaveSettings &goto :ConvertFolder
if /i "[%file%]" equ "[$$notstrict$$]" set "file=%~2" &set "home=%~3" &call :SaveSettings &goto :NotStrictConvert
if "[%file%]" neq "[]" if exist "%file%" call :New &goto :Menu
call :help
:Settings
call :DrawHead
echo( ____________________________________________________________________________
echo(
if %dontShowInfo%==1 (
echo( 1 - Show Info On The Screen ^(currently data is logged^)) else (echo( 1 - Log Info To A Text File ^(currently data is shown on screen^))
)
echo(
if %autoOpenFolders%==1 (
echo( 2 - Auto Open Folders After A New File Is Created ^(currently is On^)) else (echo( 2 - Auto Open Folders After A New File Is Created ^(currently is Off^))
echo(
echo( 3 - Change Which Image Format To Use ^(currently it is %prevailExt%^)
echo(
echo( 4 - Clear Logs In Sys Folder
echo(
echo( 5 - Exit
echo(
choice /n /m " Please Select A Menu Number:" /c:12345
if errorlevel 1 set k=1
if errorlevel 2 set k=2
if errorlevel 3 set k=3
if errorlevel 4 set k=4
if errorlevel 5 set k=5
if %k%==1 if %dontShowInfo%==1 (set "dontShowInfo=0") else (set "dontShowInfo=1")
if %k%==2 if %autoOpenFolders%==1 (set "autoOpenFolders=0") else (set "autoOpenFolders=1")
if %k%==3 call :ImageFormat
if %k%==4 2>nul del /q "%~dp0sys\*log*.txt
if %k%==5 goto :Menu
call :SaveSetFile
goto :Settings
:ImageFormat
call :DrawHead
echo(&echo( If you change the extension used in the program, you will no longer
echo( be able to edit older project folders that used the current image extension.
echo( You would have to switch back to what ever image format was used if you wanted
echo( to open an older project. Unless you rebuild a folder in Non Strict, which
echo( would allow you to use all different image types.
echo(&echo( Enter The Extension ^(without the "."^) That You Want To Use.
echo( Currently it is %prevailExt%
set /p prevailExt=: || set "prevailExt=png"
call :SaveSetFile
goto :eof
:LoadSetFile
<"%~dp0sys\settings.cfg" (
set /p dontShowInfo=
set /p autoOpenFolders=
set /p prevailExt=
)
goto :eof
:SaveSetFile
>"%~dp0sys\settings.cfg" (
echo(%dontShowInfo%
echo(%autoOpenFolders%
echo(%prevailExt%
)
goto :eof
:Existing
call :LoadSettings
call :SaveSettings
if not exist "%file%" call :NotThere
if not exist "%home%\%IDfile%" call :NotThere
if not exist "%home%\%buildFile%" call :NotThere
call :LoadDetails "%home%\%IDfile%"
goto :menu
pause
:New
call :DrawHead
call :LoadNewFile
%codeclog% "%~dp0bin\MotoLogoCodec.exe" -i "%file%" -o "%name%" -p "%home%" || (if defined "%home%" if exist "%home%\" rd /q "%home%" &call :NoLogo)
echo(&echo( MotoLogo container found, validating data...
%validlog% "%~dp0bin\MotoLogoValidator.exe" -i "%file%" || (
if exist "%home%\logo.bin" (
set "file=%home%\Logo.bin"
%validlog% "%~dp0bin\MotoLogoValidator.exe" -i "!file!" || (if defined home if exist "%home%\" del /q "%home%\*.bin" &rd /q "%home%" &call :ValidFail)
) else (if defined home if exist "%home%\" del /q "%home%\*.bin" &rd /q "%home%" &call :ValidFail)
)
set "file=%home%\logo.bin"
call :SaveSettings
echo(&echo( VALIDATION SUCCESSFUL&echo(
%syslog% move "%~dp0%IDfile%" "%home%\"
call :LoadDetails "%home%\%IDfile%"
call :MakeFolders
echo(&echo( Extracting images....Please wait...&echo(
"%~dp0bin\MotoLogoCodec.exe" -z -c -d -i "%file%" -o "%name%" -p "%home%\%mrDir%"
%syslog% move "%~dp0%buildFile%" "%home%\"
%syslog% move "%home%\%mrDir%\*.bgr24" "%home%\%rawBGRDir%\"
call :ffmpegit "%home%\%rawBGRDir%" "%home%\%imagesDir%"
goto :eof
:ValidFail
echo(&echo(&echo( Container Failed Validataion..
echo( Press any key to exit.
pause>nul
exit
goto :eof
:MakeFolders
2>nul mkdir "%home%\%rawBGRDir%"
2>nul mkdir "%home%\%mrDir%"
2>nul mkdir "%home%\%imagesDir%"
goto :eof
:Menu
call :DrawHead
call :DrawDetails
echo( ____________________________________________________________________________
echo(
echo( 1 - Rebuild %imagesDir% Directory ^(Strict-In Order-Resolution Checks^)
echo(
echo( 2 - Rebuild %imagesDir% Directory ^(Not Strict^)
echo(
echo( 3 - Open Current Project Folder
echo(
echo( 4 - Settings
echo(
echo( 5 - Fastboot Flash Current File
echo(
echo( 6 - Exit
echo(
choice /n /m " Please Select A Menu Number:" /c:123456
if errorlevel 1 set k=1
if errorlevel 2 set k=2
if errorlevel 3 set k=3
if errorlevel 4 set k=4
if errorlevel 5 set k=5
if errorlevel 6 set k=6
if %k%==1 call :ConvertFolder
if %k%==2 call :NotStrictConvert
if %k%==3 start "" "%home%"
if %k%==4 call :Settings
if %k%==5 call :Fla****
if %k%==6 goto :finish
goto :Menu
:Fla****
call :DrawHead
call :DrawDetails
echo(&echo( Your logo is ready to be flashed.&echo(
echo(&echo( Make sure that your device is connected and in Bootloader Mode.
echo(&echo( The following command will be issued:
echo( fastboot flash logo "%file%"
echo(&echo( Press 1 to flash the logo partition, or 2 to go back.&echo(
echo(&echo( 1 - Flash
echo(&echo( 2 - Go Back
echo(
choice /n /m " Please select a menu number:" /c:12
if errorlevel 1 set k=1
if errorlevel 2 set k=2
if !k!==1 (call )
if !k!==2 goto :Menu
"%~dp0bin\fastboot.exe" flash logo "%file%" &&echo. Finished..Press any key to Reboot your device.&&pause>nul&&"%~dp0bin\fastboot.exe" reboot
goto :eof
:NotStrictConvert
call :DrawHead
echo(&echo( This will rebuild all images in the %imageDir% folder.
echo( It will rebuild in alphabetical order while disregarding
echo( original width, height, position in bin file. You can pretty
echo( much put any image format in here and get an encoded bin file.
echo( Press 1 to Continue or 2 to Go Back
echo(&echo( 1 - Continue
echo(&echo( 2 - Go Back
echo(
choice /n /m "please select a menu number:" /c:12
if errorlevel 1 set k=1
if errorlevel 2 set k=2
if !k!==1 (call )
if !k!==2 goto :Menu
if exist "%home%\errors.txt" del /q "%home%\errors.txt"
if not exist "%home%\%IDfile%" call :NotThere
if not exist "%home%\%buildFile%" call :NotThere
call :LoadDetails "%home%\%IDfile%"
if defined home if exist "%home%\" rd /s /q "%home%\Not_Strict_Modified\" 2>nul
2>nul md "%home%\Not_Strict_Modified"
2>nul md "%home%\Not_Strict_Modified\%rawBGRDir%"
2>nul md "%home%\Not_Strict_Modified\%mrDir%"
set /a imageCount=0
2>nul del /q "%home%\%imagesDir%\Thumbs.db"
for /f %%a in ('dir /b /a-d-h "%home%\%imagesDir%\*.*"') do (
set /a imageCount=!imageCount!+1
echo( Converting: %%a
set "name=%%~na"
set name=!name:~0,24!
for /f "tokens=1-8* delims=," %%A in ('bin\ffmpeg -hide_banner -i "%home%\%imagesDir%\%%a" -f rawvideo -vcodec rawvideo -pix_fmt bgr24 -y "%home%\Not_Strict_Modified\%rawBGRDir%\!name!.bgr24" 2^>^&1^|findstr /rxic:".*stream #0:0.*[0-9]x[0-9].*"') do (
echo(%%A >"%home%\imageres"
echo(%%B >>"%home%\imageres"
echo(%%C >>"%home%\imageres"
echo(%%D >>"%home%\imageres"
echo(%%E >>"%home%\imageres"
echo(%%F >>"%home%\imageres"
echo(%%G >>"%home%\imageres"
echo(%%H >>"%home%\imageres"
)
for /f "tokens=1-3 delims=x " %%I in ('type "%home%\imageres"^|findstr /rxic:".*[0-9]x[0-9].*"') do set /a width=%%I &set /a height=%%J
if not defined width echo( Error: "Width undefined in %%a">>"%home%\errors.txt"
if not defined height echo( Error: "Height undefined in %%a">>"%home%\errors.txt"
if not exist "%home%\Not_Strict_Modified\%rawBGRDir%\!name!.bgr24" echo( Error: "%home%\Not_Strict_Modified\%rawBGRDir%\!name!.bgr24" Was not created.>>"%home%\errors.txt"
echo( Encoding: !name!.bgr24
%codeclog% "%~dp0bin\MotoLogoCodec.exe" -e -i "%home%\Not_Strict_Modified\%rawBGRDir%\!name!.bgr24" -o "%home%\Not_Strict_Modified\%mrDir%\!name!.mr" -w !width! -h !height!
if not exist "%home%\Not_Strict_Modified\%mrDir%\!name!.mr" echo( Error: "%home%\Not_Strict_Modified\%mrDir%\!name!.mr" Was not sucessfully encoded.>>"%home%\errors.txt"
echo(!name!?%home%\Not_Strict_Modified\%mrDir%\!name!.mr>>"%home%\Not_Strict_Modified\%buildFile%"
set check=
)
del /q "%home%\imageres"
if exist "%home%\errors.txt" call :Error
echo( Rebuilding Encoded Files...
"%~dp0bin\BuildMotoLogo.exe" <"%home%\Not_Strict_Modified\%buildFile%" -o "%home%\Not_Strict_Modified\build.bin" -n %imageCount%
%validlog% "%~dp0bin\MotoLogoValidator.exe" -i "%home%\Not_Strict_Modified\build.bin" || goto :RebuildError
set "file=%home%\Not_Strict_Modified\build.bin"
set "home=%home%\Not_Strict_Modified"
call :SaveSettings
%syslog% move "%~dp0%IDfile%" "%home%\"
call :LoadDetails "%home%\%IDfile%"
echo( Validation succesful
2>nul md "%home%\%imagesDir%"
call :ffmpegit
goto :Menu
:ConvertFolder
call :DrawHead
if exist "%home%\errors.txt" del /q "%home%\errors.txt"
if not exist "%home%\%IDfile%" call :NotThere
if not exist "%home%\%buildFile%" call :NotThere
call :LoadDetails "%home%\%IDfile%"
echo(&echo( Checking Resolutions..
if defined home if exist "%home%\" rd /s /q "%home%\Modified\" 2>nul
2>nul md "%home%\Modified"
2>nul md "%home%\Modified\%rawBGRDir%"
2>nul md "%home%\Modified\%mrDir%"
for /l %%a in (1,1,%images%) do (
echo( Converting: !logoName[%%a]!
if not exist "%home%\%imagesDir%\!logoName[%%a]!.%prevailExt%" (
call :DrawHead
echo(&echo( An image for !logoName[%%a]! is missing in the %imagesDir% folder.
echo(&echo( If you are trying to remove an image from you bin file, you need
echo( to rebuild the %imagesDir% folder in Non Strict Mode.
echo(&echo( Press any key to return to the menu.
pause>nul
goto :Menu
)
for /f "tokens=1-8* delims=," %%A in ('bin\ffmpeg -hide_banner -i "%home%\%imagesDir%\!logoName[%%a]!.%prevailExt%" -f rawvideo -vcodec rawvideo -pix_fmt bgr24 -y "%home%\Modified\%rawBGRDir%\!logoName[%%a]!.bgr24" 2^>^&1^|findstr /rxic:".*stream #0:0.*[0-9]x[0-9].*"') do (
echo(%%A >"%home%\imageres"
echo(%%B >>"%home%\imageres"
echo(%%C >>"%home%\imageres"
echo(%%D >>"%home%\imageres"
echo(%%E >>"%home%\imageres"
echo(%%F >>"%home%\imageres"
echo(%%G >>"%home%\imageres"
echo(%%H >>"%home%\imageres"
)
for /f "tokens=1-3 delims=x " %%I in ('type "%home%\imageres"^|findstr /rxic:".*[0-9]x[0-9].*"') do set /a width=%%I &set /a height=%%J
if not defined width echo( Error: "Width undefined in !logoName[%%a]!.%prevailExt%">>"%home%\errors.txt"
if not defined height echo( Error: "Height undefined in !logoName[%%a]!.%prevailExt%">>"%home%\errors.txt"
if !width! neq !logoWidth[%%a]! set check=1
if !height! neq !logoHeight[%%a]! set check=1
if defined check call :Aspect !width! !height! !logoWidth[%%a]! !logoHeight[%%a]! "%home%\%imagesDir%\!logoName[%%a]!.%prevailExt%" "%home%\Modified\%rawBGRDir%\!logoName[%%a]!.bgr24" "!logoName[%%a]!"
if not exist "%home%\Modified\%rawBGRDir%\!logoName[%%a]!.bgr24" echo( Error: "%home%\Modified\%rawBGRDir%\!logoName[%%a]!.bgr24" Was not created.>>"%home%\errors.txt"
echo( Encoding: !logoName[%%a]!
%codeclog% "%~dp0bin\MotoLogoCodec.exe" -e -i "%home%\Modified\%rawBGRDir%\!logoName[%%a]!.bgr24" -o "%home%\Modified\%mrDir%\!logoName[%%a]!.mr" -w !width! -h !height!
if not exist "%home%\Modified\%mrDir%\!logoName[%%a]!.mr" echo( Error: "%home%\Modified\%mrDir%\!logoName[%%a]!.mr" Was not sucessfully encoded.>>"%home%\errors.txt"
echo(!logoName[%%a]!?%home%\Modified\%mrDir%\!logoName[%%a]!.mr>>"%home%\Modified\%buildFile%"
set check=
set width=
set height=
)
del /q "%home%\imageres"
if exist "%home%\errors.txt" call :Error
echo( Rebuilding Encoded Files...
"%~dp0bin\BuildMotoLogo.exe" <"%home%\Modified\%buildFile%" -o "%home%\Modified\build.bin" -n %images%
%validlog% "%~dp0bin\MotoLogoValidator.exe" -i "%home%\Modified\build.bin" || goto :RebuildError
set "file=%home%\Modified\build.bin"
set "home=%home%\Modified"
call :SaveSettings
%syslog% move "%~dp0%IDfile%" "%home%\"
call :LoadDetails "%home%\%IDfile%"
echo( Validation succesful
2>nul md "%home%\%imagesDir%"
call :ffmpegit
goto :Menu
:Aspect
set check=
set /a border=5
set /a border2=2*%border%
echo(&echo( Image: %~7
set /a newAspect=%aspectMultiplier%*%1/%2
set /a originalAspect=%aspectMultiplier%*%3/%4
echo(
echo( The resolution for %7 is different from the original image.
echo( New : %1x%2
echo( Original: %3x%4
echo(
echo( ____________________________________________________________________________
if "%originalAspect%"=="%newAspect%" (
echo(
echo( 1 - Stretch Or Shrink The Image To Fit The Original Size
echo(
echo( 2 - Do Nothing And Continue
echo(
choice /n /m "please select a menu number:" /c:12
if errorlevel 1 set k=1
if errorlevel 2 set k=2
if !k!==1 set "videoFilters=-vf "scale=%3:%4""
if !k!==2 goto :eof
) else (
echo(
if %3 gtr %4 (echo( 1 - Resize And Crop While Keeping The Original Aspect And Size ^(Upper Image^)) else (echo( 1 - Resize And Crop While Keeping The Original Aspect And Size ^(Left Image^))
echo(
if %3 gtr %4 (echo( 2 - Stretch Or Shrink The Image To Fit The Original Size ^(Lower Image^)) else (echo( 2 - Stretch Or Shrink The Image To Fit The Original Size ^(Right Image^))
echo(
echo( 3 - Do Nothing And Continue With %1x%2 Image
echo(
if %4 lss %3 (set /a ffw=%3+2*%border%&set /a ffh=%4*2+3*%border%&set "overlay=overlay=%border%:h+%border2%") else (set /a ffw=%3*2+3*%border%&set /a ffh=%4+2*%border%&set "overlay=overlay=w+%border2%:%border%")
if %originalAspect% lss %newAspect% (set "scale=scale=-1:%4") else (set "scale=scale=%3:-1")
"%~dp0bin\ffmpeg.exe" -loglevel fatal -i "%~5" -i "%~5" -filter_complex "color=red:!ffw!x!ffh!:1[bg];[0]!scale!, crop=%3:%4[sc0];[1]scale=%3:%4[sc1];[bg][sc0]overlay=%border%:%border%[x];[x][sc1]!overlay!" -y "%home%\test.png"%ffmpeglog%
if exist "%home%\test.png" if defined useDefaultViewer (start "" "%home%\test.png") else (rundll32 "%ProgramFiles%\Windows Photo Viewer\PhotoViewer.dll", ImageView_Fullscreen %home%\test.png)
choice /n /m "please select a menu number:" /c:123
if errorlevel 1 set k=1
if errorlevel 2 set k=2
if errorlevel 3 set k=3
if !k!==1 (
if %originalAspect% gtr %newAspect% set "videoFilters=-vf "scale=%3:-1, crop=%3:%4""
if %originalAspect% lss %newAspect% set "videoFilters=-vf "scale=-1:%4, crop=%3:%4""
)
if !k!==2 set "videoFilters=-vf "scale=%3:%4""
if !k!==3 goto :eof
2>nul del /q "%home%\test.png"
)
set /a width=%3
set /a height=%4
%ffmpeglog% "%~dp0bin\ffmpeg.exe" %ffdebug% %ffshowb% -i "%~5" !videoFilters! -f rawvideo -vcodec rawvideo -pix_fmt bgr24 -y "%~6"
goto :eof
:RebuildError
echo( There was a problem rebuilding the images..
echo( Press any key to exit.
pause>nul
goto :Finish
:Error
call :DrawHead
echo(&type "%home%\errors.txt"
echo(&echo( Press any key to exit..
pause >nul
goto :Finish
:DrawHead
cls echo( _________________________________________________________________________-_-
echo( Motorola Image Injector v%vers%
echo(
echo( written by Makers_Mark
echo( ____________________________________________________________________________
goto :eof
:DrawFileInfo
echo( File: %file% &echo( Size: %fileSize% Bytes ^(%megaSize%.%megaDeci% MB^)&echo( ____________________________________________________________________________
goto :eof
:DrawDetails
call :DrawFileInfo
"%~dp0bin\DrawDetails.exe" <"%home%\%IDfile%"
goto :eof
:NoLogo
call :DrawHead
echo(&echo( No Motorola Logo Images were found in the file.
echo( Press any key to exit....
pause>nul
exit
:LoadDetails
set /a images=0
for /f "tokens=1-7 delims=," %%t in ('type "%~1"') do (
set /a images+=1
set "logoName[!images!]=%%t" &set /a logoOffset[!images!]=%%y &set /a logoSize[!images!]=%%z &set /a logoSizeTotal[!images!]=%%w
set /a logoBlocks[!images!]=%%x &set /a logoWidth[!images!]=%%u &set /a logoHeight[!images!]=%%v
)
goto :eof
:dupename
if not exist "%~dp0%workhere%\!%~1!\" (goto :eof)
set /a unique=1
:dupe
if not exist "%~dp0%workhere%\!%~1!.%unique%\" (
set "%~1=!%~1!.%unique%"
goto :eof
) else (
set /a unique+=1
goto :dupe
)
goto :eof
:LoadNewFile
for %%? in ("%file%") do set /a "size=%%~z?" &set "filename=%%~nx?" &set "ext=%%~x?" &set "name=%%~n?"
set "newDir=%name%"
call :dupename "newDir"
set "home=%~dp0%workHere%\%newDir%"
2>nul mkdir "%home%"
goto :eof
:LoadSettings
<"%~dp0sys\last_file" (
set /p file=
set /p home=
set /p fileSize=
)
call :StripQuotes %file% %home%
goto :eof
:StripQuotes
set "file=%~1"
set "home=%~2"
goto :eof
:SaveSettings
for %%? in ("%file%") do set fileSize=%%~z?
set /a fileSize
set /a megaSize=%fileSize%/(1024*1024)
set /a remain=%fileSize% %% (1024*1024)
set /a megaDeci=(%remain%*1000)/(1024*1024)
>"%~dp0sys\last_file" (
echo("%file%"
echo("%home%"
echo(%fileSize%
)
goto :eof
:ffmpegit
echo( Converting Images Into %prevailExt% Images...
(for /f %%a in ('dir /b/a-d "%home%\%rawBGRDir%\*.bgr24"') do (
for /l %%? in (1, 1, %images%) do (
if "%%~na"=="!logoName[%%?]!" (
call set /a width=!logoWidth[%%?]!"
call set /a height=!logoHeight[%%?]!
)
)
"%~dp0bin\ffmpeg.exe" %ffdebug% %ffshowb% -loglevel fatal -f rawvideo -vcodec rawvideo -s !width!x!height! -pix_fmt bgr24 -i "%home%\%rawBGRDir%\%%~nxa" -y "%home%\%imagesDir%\%%~na.%prevailExt%"
))%ffmpeglog%
>"%home%\Make MotoLogo Bin From %imagesDir% Folder.bat" (
echo(@echo off
echo(cmd ^/c ^""%~dpnx0" $$$convert$$$ "%file%" "%home%"^"
echo(
)
>"%home%\Make MotoLogo Bin (Not Strict) From %imagesDir% Folder.bat" (
echo(@echo off
echo(cmd ^/c ^""%~dpnx0" $$notstrict$$ "%file%" "%home%"^"
echo(
)
if %autoOpenFolders%==1 start "" "%home%\"
goto :eof
:help
call :DrawHead
echo(&echo(
echo( You have to drag a file onto this batch file,
echo( in order to load a file into it.
echo( Press a key to close this window and exit.
pause >nul
goto :finish
:NotThere
call :Drawhead
echo(&echo(
echo( File^(s^) are missing. Reload File by dragging and dropping onto
echo( this batch file again.
echo( Press a key to close this window and exit.
pause>nul
goto :finish
:Finish
cls&exit
goto :eof
DrawDetails.c
Code:
#include <string.h>
#include <stdio.h>
#include <windows.h>
int main()
{
char *s = "," ;
char *token ;
int i , j = 1 , k , color ;
char line[80];
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
WORD originalColor;
GetConsoleScreenBufferInfo(hConsole, &consoleInfo);
originalColor = consoleInfo.wAttributes;
printf(" ____________________________________________________________________________\n");
printf(" Image Name WxH Size+ Blocks Offset Raw Size \n");
printf(" _________________________________________________________________________-_-\n");
while(fgets(line, sizeof line, stdin) != NULL){
if (( j % 2 ) == 0) {
color = 0x0B;
} else {
color = 0xB0;
}
SetConsoleTextAttribute(hConsole, color);
token = strtok(line, s);
for ( i = 0; i < 7; i++){
if (i==0){
printf(" %2d.%-24s", j,token);
token = strtok(NULL,s);
} else if ( i == 1 ){
printf("%dx", atoi(token));
token = strtok(NULL,s);
} else if ( i == 2 ){
printf("%d\t", atoi(token));
token = strtok(NULL,s);
} else if (( i > 2) && ( i < 6 )){
printf("%d\t", atoi(token));
token = strtok(NULL,s);
} else {
printf("%-13d\r\n", atoi(token));
token = strtok(NULL,s);
}
}
j++;
}
SetConsoleTextAttribute(hConsole, originalColor);
}
SOURCE:
MotoLogoCodec.c
Code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#define OUT_FILE "logo.bin"
#define MOTOLOGO_BARE_HEADER 13
#define MOTOLOGO_IMG_BLK_SIZE 32
#define BIT_SET 0x8000
#define IS_BIT_SET(x) (x & BIT_SET)
#define COLORS 3
#define SWAP(x) (((x & 0xFF00) >> 8) | ((x & 0x00FF) << 8))
typedef struct {
unsigned short count;
unsigned char color[COLORS];
} motoSet;
typedef struct {
char header[8];
unsigned short width;
unsigned short height;
} motoHead;
typedef struct {
char name[24];
unsigned long offset;
unsigned long size;
unsigned short totalBlocks;
unsigned long totalSize;
motoHead imageHead;
} imageHead;
typedef struct {
unsigned char r;
unsigned char g;
unsigned char b;
} pixel;
void MotoRunEncode(void);
int FindMotoLogo(void);
int ParseHeader(unsigned long, int);
void CutMRImageOut(int, char*, unsigned long);
unsigned long int BlockIt(unsigned long int);
void MotoDecode(int, char*, unsigned short, unsigned short, unsigned long, int);
unsigned short pad = 1;
unsigned short addDetails = 0;
unsigned short cutMR = 0;
unsigned short decode = 0, encode = 0;
unsigned short blockSize = 512;
unsigned short pos = 0;
unsigned short filesFound = 0;
unsigned short logoOutput = 1;
unsigned short width = 0, height = 0;
char *inputFile, *base, *path;
char *motoLogoHeader;
unsigned long start, end;
FILE *inStream;
FILE *outStream;
char command[512];
char padByte = 0xff;
void MotoRunEncode(void)
{
unsigned int i,ind, m;
pixel line[width];
unsigned short count;
motoHead motoRunHeader;
if ((inStream = fopen(inputFile, "rb")) == NULL){
fclose(inStream);
fprintf(stderr, "\n%s\nCould not be opened.", inputFile);
return;
}
if ((outStream = fopen(base, "wb")) == NULL){
fclose(inStream);
fclose(outStream);
fprintf(stderr, "\n%s\nCould not be opened.", base);
return;
}
motoRunHeader.header[0] = 0x4D;
motoRunHeader.header[1] = 0x6F;
motoRunHeader.header[2] = 0x74;
motoRunHeader.header[3] = 0x6F;
motoRunHeader.header[4] = 0x52;
motoRunHeader.header[5] = 0x75;
motoRunHeader.header[6] = 0x6E;
motoRunHeader.header[7] = 0x00;
motoRunHeader.width = SWAP(width);
motoRunHeader.height = SWAP(height);
fwrite(&motoRunHeader, 1, sizeof(motoRunHeader), outStream);
for (i = 1; i <= height; i++){
fread(line, COLORS, width, inStream);
for (ind = 0, count = 0 ; ind <= width - 1; ){
if ((memcmp(&line[ind], &line[ind+1], 3) == 0)){
ind++;
count = 1;
while((ind <= width - 2) && ((memcmp(&line[ind], &line[ind+1], 3))== 0)){
count++;
ind++;
}
if (count == 1){
count++;
ind++;
goto LOOP;
} else {
count++;
count |= BIT_SET;
count = SWAP(count);
fwrite(&count, 1, 2, outStream);
fwrite(&line[ind], 1, 3, outStream);
}
ind++;
} else {
count = 1;
ind++;
LOOP:
while (((ind >= width -2)&&(ind <= width -1)) || ((ind <= width - 2) && (memcmp(&line[ind], &line[ind+1], 3) != 0)) || ((ind <= width - 3) && (memcmp(&line[ind+1], &line[ind+2], 3) != 0))){
count++;
ind++;
}
count = SWAP(count);
fwrite(&count, 1, 2, outStream);
fwrite(&line[ind - SWAP(count)], SWAP(count), COLORS, outStream);
continue;
}
}
}
return;
}
int FindMotoLogo(void)
{
char header[] = {0x4D,0x6F,0x74,0x6F,0x4C,0x6F,0x67,0x6F,0x00};
unsigned long int firstOffset;
int readByte;
char string[9];
if ((inStream = fopen(inputFile, "rb")) == NULL){
fclose(inStream);
fprintf(stderr, "\n%s\nCould not be opened.", inputFile);
return;
}
int inNumber = fileno(inStream);
while ((readByte = fgetc(inStream)) != EOF){
if (readByte == header[pos]){
if (pos == 8){
start = (ftell(inStream) - 9);
fseek(inStream, start + 9, SEEK_SET);
read(inNumber, &end, 4);
fseek(inStream, start + 9 + 4 + 24, SEEK_SET );
read(inNumber, &firstOffset, 4);
fseek(inStream, start + firstOffset, SEEK_SET );
read(inNumber, &string, 9);
if (strcmp(string, "MotoRun") == 0){
fseek(inStream, start + 13, SEEK_SET );
return (ParseHeader(end, inNumber));
} else {
pos = 0;
fseek(inStream, start + 9, SEEK_SET );
continue;
}
} else {
pos++;
continue;
}
}
pos = 0;
}
close(inNumber);
fprintf(stderr,"\n%d MotoLogo (logo.bin) files found.", filesFound);
return;
}
int ParseHeader(unsigned long end, int inNumber)
{
unsigned int imageCounter = (end - MOTOLOGO_BARE_HEADER) / MOTOLOGO_IMG_BLK_SIZE;
imageHead motomoto[imageCounter];
int i;
unsigned long logoSize, pos;
for(i=0; i < imageCounter; i++){
read(inNumber, &motomoto[i], 32);
motomoto[i].totalSize = BlockIt(motomoto[i].size);
motomoto[i].totalBlocks = (motomoto[i].totalSize /blockSize);
fprintf(stdout,"\nName: %s\nOffset in Logo.bin: %ld\nImage Data Size: %ld",motomoto[i].name, motomoto[i].offset, motomoto[i].size);
fprintf(stdout,"\nTotal Size: %ld",motomoto[i].totalSize);
fprintf(stdout,"\nTotal Blocks: %d",motomoto[i].totalBlocks);
pos = ftell(inStream);
fseek(inStream, start + motomoto[i].offset, SEEK_SET);
if (cutMR){
CutMRImageOut(inNumber, motomoto[i].name, motomoto[i].size);
fseek(inStream, start + motomoto[i].offset, SEEK_SET); //moved this line inside the parentheses
}
read(inNumber, &motomoto[i].imageHead, 12);
motomoto[i].imageHead.width = SWAP(motomoto[i].imageHead.width);
motomoto[i].imageHead.height = SWAP(motomoto[i].imageHead.height);
fprintf(stdout,"\nWidth x Height: %dx%d",motomoto[i].imageHead.width,motomoto[i].imageHead.height);
fprintf(stdout,"\nHeader: %s\n\n",motomoto[i].imageHead.header);
if (decode){
MotoDecode(inNumber, motomoto[i].name, motomoto[i].imageHead.width, motomoto[i].imageHead.height, motomoto[i].size , i+1);
}
fseek(inStream, pos, SEEK_SET);
}
logoSize = motomoto[imageCounter-1].offset + motomoto[imageCounter-1].totalSize;
fprintf(stdout,"\nLogo.bin contains %ld image files and is %ld bytes in size", i, logoSize);
if (!(logoOutput)){
return 0;
}
sprintf(command,"%s\\%s", path , OUT_FILE );
if ((outStream = fopen(command, "wb")) == NULL){
fclose(outStream);
fprintf(stderr, "\n%s\\%s could not be opened.", path, OUT_FILE);
return 1;
}
int outNumber = fileno(outStream);
fseek(inStream, start, SEEK_SET );
char* logobin = malloc(logoSize);
read(inNumber, logobin, logoSize);
write(outNumber, logobin, logoSize);
close(outNumber);
free(logobin);
return 0;
}
void CutMRImageOut(int inNumber, char* name, unsigned long size){
char newName[26];
FILE *txt;
sprintf(command,"%s\\%s.mr", path , name );
if ((txt = fopen("build.ID", "a")) == NULL){
fclose(txt);
fprintf(stderr, "\nBuild.ID could not be opened.\n");
return;
}
if ((outStream = fopen(command, "wb")) == NULL){
fclose(outStream);
fclose(txt);
fprintf(stderr, "\n%s\\%s.mr could not be opened", path, name);
return;
}
sprintf(command,"%s\n", command );
sprintf(newName, "%s?", name);
fwrite(newName, strlen(newName), 1, txt);
fwrite(command, strlen(command), 1, txt);
fclose(txt);
int outNumber = fileno(outStream);
char *dataStream = malloc(size);
read(inNumber, dataStream, size);
write(outNumber, dataStream, size);
if (pad){
if ((size % blockSize) != 0){
unsigned int max = blockSize - (size % blockSize ), i;
for (i = 0; i < max; i++){
write(outNumber, &padByte , 1);
}
fprintf(stdout,"\n%d bytes padded to %s", max, name);
}
}
close(outNumber);
free(dataStream);
return;
}
unsigned long int BlockIt(unsigned long int isize){
if ((isize % blockSize) == 0){
return isize;
}else{
return isize + (blockSize - (isize %blockSize));
}
}
void MotoDecode(int inNumber, char* name, unsigned short width, unsigned short height, unsigned long size, int index)
{
unsigned short repeats, count;
unsigned char color[3];
unsigned long counter = 0;
motoSet data;
if (addDetails){
sprintf(command, "%s\\%03d_%dx%d_%s.bgr24", path , index, width, height, name);
} else {
sprintf(command, "%s\\%s.bgr24", path, name);
}
if ((outStream = fopen(command, "wb")) == NULL){
fclose(outStream);
fprintf(stderr, "\n%s\nCould not be opened.", command);
return;
}
int outNumber = fileno(outStream);
while((read(inNumber, &data, 5) != EOF) && (counter < size)){
counter += 5;
if ((counter >= size ) || (data.count == 0xffff)){
close(outNumber);
return;
}
data.count = SWAP(data.count);
if (IS_BIT_SET(data.count)){
data.count &= ~BIT_SET;
for (repeats = 0;repeats < data.count; repeats++){
write(outNumber, &data.color, COLORS);
}
} else {
write(outNumber, &data.color, COLORS);
for (repeats = 0; repeats < data.count -1; repeats++){
counter += COLORS;
if ((read(inNumber, color, COLORS) == EOF) || counter >= size){
write(outNumber, &color, COLORS);
close(outNumber);
return;
}
write(outNumber, &color, COLORS);
}
}
}
close(outNumber);
return;
}
int main(int argc, char **argv)
{
int c;
while ((c = getopt (argc, argv, "i:o:p:b:w:h:cdezna")) != -1){
switch(c)
{
case 'a':
addDetails = 1;
break; //add index number and resolution to decoded filenames
case 'i':
inputFile = optarg;
break;
case 'o':
base = optarg;
break;
case 'p':
path = optarg;
break;
case 'b':
blockSize = atoi(optarg);
break;
case 'c':
cutMR = 1;
break;
case 'd':
decode = 1;
break;
case 'e':
encode = 1;
break;
case 'z':
pad = 0;
break;
case 'n':
logoOutput = 0;
break;
case 'w':
width = atoi(optarg);
break;
case 'h':
height = atoi(optarg);
break;
}
}
if (encode == 1){
MotoRunEncode();
return;
}
return(FindMotoLogo());
}
MotoLogoValidator.c
Code:
/*
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#define MOTOLOGO_BARE_HEADER 13
#define MOTOLOGO_IMG_BLK_SIZE 32
#define BIT_SET 0x8000
#define IS_BIT_SET(x) (x & BIT_SET)
#define COLORS 3
#define SWAP(x) (((x & 0xFF00) >> 8) | ((x & 0x00FF) << 8))
typedef struct {
unsigned short count;
unsigned char color[COLORS];
} motoSet;
typedef struct {
char header[8];
unsigned short width;
unsigned short height;
} motoHead;
typedef struct {
char name[24];
unsigned long offset;
unsigned long size;
unsigned short totalBlocks;
unsigned long totalSize;
motoHead imageHead;
} imageHead;
typedef struct {
unsigned char r;
unsigned char g;
unsigned char b;
} pixel;
int FindMotoLogo();
int ValidateMotoLogoHeader();
unsigned long int BlockIt(unsigned long int);
int VerifyImages(char*, unsigned short, unsigned short, unsigned long);
unsigned short pos, inNumber, blockSize = 512;
char *inputFile;
unsigned long start, end;
FILE *inStream;
FILE *txt;
char command[512];
char padByte = 0xff;
int FindMotoLogo()
{
char header[] = {0x4D,0x6F,0x74,0x6F,0x4C,0x6F,0x67,0x6F,0x00};
unsigned long int firstOffset;
int readByte;
char string[9];
for (pos = 0 ; pos <= 8 ; pos++ ){
if ((readByte = fgetc(inStream)) == header[pos]){
fprintf(stdout,"\nHeader:\n%d %02x",pos, header[pos]);
if (pos == 8){
fprintf(stdout, "\nHeader Match");
start = 0;
fseek(inStream, start + 9, SEEK_SET);
read(inNumber, &end, 4);
fseek(inStream, start + 9 + 4 + 24, SEEK_SET );
read(inNumber, &firstOffset, 4);
fseek(inStream, start + firstOffset, SEEK_SET );
read(inNumber, &string, 9);
if (strcmp(string, "MotoRun") == 0){
fseek(inStream, start + 13, SEEK_SET );
fprintf(stdout,"\nEnd of MotoLogo Header is byte %d.\n", end);
return 0;
} else {
fprintf(stderr,"\nFirst offset in MotoLogo header doesn't point to an image header.");
return 1;
}
} else {
continue;
}
} else {
fprintf(stderr,"\nFile: %s\ndoes not start with a valid MotoLogo header.", inputFile);
return 1;
}
}
return 1;
}
int ValidateMotoLogoHeader()
{
unsigned int imageCounter = (end - MOTOLOGO_BARE_HEADER) / (MOTOLOGO_IMG_BLK_SIZE);
fprintf(stdout,"\n%d images referenced in header.\nChecking Images.\n", imageCounter);
imageHead motomoto[imageCounter];
int i;
char motoRunHeader[] = "MotoRun\0";
fseek(inStream, 13, SEEK_SET);
for(i=0; i < imageCounter; i++){
read(inNumber, &motomoto[i], 32); //add an if parameter switch for the last element not to include the padding
motomoto[i].totalSize = BlockIt(motomoto[i].size);
motomoto[i].totalBlocks = (motomoto[i].totalSize /blockSize);
fprintf(stdout,"\nName: \"%s\"\nOffset In File: %ld\nImage Data Size: %ld",motomoto[i].name, motomoto[i].offset, motomoto[i].size);
fprintf(stdout,"\nTotal Size With Padding: %ld",motomoto[i].totalSize);
fprintf(stdout,"\nTotal Blocks: %d",motomoto[i].totalBlocks);
if (i != 0){
if ((motomoto[i-1].offset + motomoto[i-1].totalSize) == (motomoto[i].offset)){
fprintf(stdout, "\nOffsets match!");
} else {
fprintf(stderr, "\nOffsets do not match between %s and %s.\nVALIDATION FAILURE!\n", motomoto[i-1].name, motomoto[i].name);
return 1;
}
} else {
if (motomoto[i].offset == BlockIt(end)){
fprintf(stdout, "\nOffsets Match!");
} else {
fprintf(stderr, "\n%d is offset and %d is the end of the MotoLogo Header\nVALIDATION FAILURE!\n", motomoto[i].offset, BlockIt(end));
return 1;
}
}
pos = ftell(inStream);
fseek(inStream, motomoto[i].offset, SEEK_SET);
read(inNumber, &motomoto[i].imageHead, 12);
motomoto[i].imageHead.width = SWAP(motomoto[i].imageHead.width);
motomoto[i].imageHead.height = SWAP(motomoto[i].imageHead.height);
fprintf(stdout,"\nWidth x Height: %dx%d",motomoto[i].imageHead.width,motomoto[i].imageHead.height);
fprintf(stdout,"\nExpected Pixels: %d", (motomoto[i].imageHead.width * motomoto[i].imageHead.height));
if(strcmp(motoRunHeader, motomoto[i].imageHead.header) != 0){
fprintf(stderr, "\nHeader Should be \"%s\", not \"%s\"\nVALIDATION FAILED!\n", motoRunHeader, motomoto[i].imageHead.header);
return 1;
}
fprintf(stdout,"\nHeader: \"%s\"",motomoto[i].imageHead.header);
if (!VerifyImages(motomoto[i].name, motomoto[i].imageHead.width, motomoto[i].imageHead.height, motomoto[i].size - 12)){
fseek(inStream, pos, SEEK_SET);
continue;
} else {
return 1;
}
}
if ((txt = fopen("MoID.ID", "w")) == NULL){
fclose(txt);
fprintf(stderr, "\nMoID.ID could not be opened.\n");
return 1;
}
for(i=0; i < imageCounter; i++){
fprintf(txt, "%s,%d,%d,%d,%d,", motomoto[i].name, motomoto[i].imageHead.width, motomoto[i].imageHead.height, motomoto[i].totalSize, motomoto[i].totalBlocks);
fprintf(txt, "%d,%d\n", motomoto[i].offset, motomoto[i].size);
}
fclose(txt);
return 0;
}
unsigned long int BlockIt(unsigned long int isize){
if ((isize % blockSize) == 0){
return isize;
}else{
return isize + (blockSize - (isize %blockSize));
}
}
int VerifyImages(char* name, unsigned short width, unsigned short height, unsigned long size)
{
unsigned short line = 0, pixelsonline = 0;
unsigned long pixelsDecoded = 0, totalPixels = 0, bytesRead = 0;
motoSet data;
unsigned long posi;
while(bytesRead < size){
if ((bytesRead += read(inNumber, &data, 5)) == EOF){
return 0;
}
data.count = SWAP(data.count);
if (IS_BIT_SET(data.count)){
data.count &= ~BIT_SET;
pixelsonline += data.count;
} else {
posi = ftell(inStream);
fseek(inStream, (posi + (COLORS * (data.count - 1))), SEEK_SET);
pixelsonline += data.count;
bytesRead = bytesRead + (COLORS * (data.count - 1));
}
if (pixelsonline == width){
line++;
pixelsDecoded += pixelsonline;
pixelsonline = 0;
}
if ((pixelsonline == width) && ((pixelsDecoded / line) == pixelsonline)){
line++;
pixelsonline = 0;
}
}
fprintf(stdout,"\nPixels Decoded: %d\nBytes Read: %d\nSize Minus Header: %d\nLines Properly Terminated: %d", pixelsDecoded, bytesRead, size , line);
if ((pixelsDecoded == width * height) && (bytesRead == size) && (height == line )){
fprintf(stdout,"\n\"%s\" Is Encoded Correctly\n", name);
return 0;
}
if (pixelsDecoded != (width * height)){
fprintf(stderr, "\nThe total pixels decoded, %d, doesn't equal the resolution: %dx%d=%d",pixelsDecoded, width, height, (width * height));
}
if (bytesRead != size){
fprintf(stderr, "\nThe total bytes read, %d, is not equal to the encoded size, %d.", bytesRead, size);
}
if (height != line ){
fprintf(stderr, "\nAt least one run in the encoding runs past the edge of the screen.\nThis will not work.");
}
fprintf(stderr, "\n%s is not encoded correctly\nVALIDATION FAILURE!\n", name);
return 1;
}
int main(int argc, char **argv)
{
int c;
while ((c = getopt (argc, argv, "i:b:")) != -1){
switch(c)
{
case 'i':
inputFile = optarg;
break;
case 'b':
blockSize = atoi(optarg);
break;
}
}
if ((inStream = fopen(inputFile, "rb")) == NULL){
fclose(inStream);
fprintf(stderr, "\n%s\nCould not be opened.\n", inputFile);
return 1;
}
inNumber = fileno(inStream);
if (!FindMotoLogo()){
if (!ValidateMotoLogoHeader()){
fclose(inStream);
return 0;
}
}
fclose(inStream);
return 1;
}
BuildMotoLogo.c v1.1
Code:
/* Version 1.1
Fixed error with encoded files that have a file size that is
evenly divisible by 512
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
typedef struct {
char name[24];
unsigned long offset;
unsigned long size;
unsigned long sizeWithPadding;
} imageHead;
unsigned long int ReadList(void);
unsigned int GetHeaderSize(void);
unsigned long int BlockIt(unsigned long int);
char *txtFileName;
FILE *inFile;
FILE *outFile;
char *outputFileName;
unsigned short images = 0;
unsigned short blockSize = 512;
unsigned long int ReadList(void){
char header[] = {0x4D,0x6F,0x74,0x6F,0x4C,0x6F,0x67,0x6F,0x00};
char line[512];
int readByte;
imageHead Item[images];
unsigned long int totalDataSize = 0;
int i = 0 , k = 0 , l = 0;
unsigned char padByte = 255;
unsigned long sizes[images];
char *s = "?";
char *tok;
unsigned long int hs;
if ((outFile = fopen (outputFileName, "wb")) == NULL){
perror("\nError opening output file:");
fclose(outFile);
}
hs = GetHeaderSize();
for ( i = 0 ; i < hs ; i++){
fputc(padByte, outFile);
}
i = 0;
hs = (images * 32) + 13;
while(fgets(line, sizeof line , stdin) != NULL){
tok = strtok(line, s);
sprintf(Item[i].name, "%s",tok);
tok = strtok(NULL, s);
for ( l = 24 ; l - strlen(Item[i].name) > 0 ; l-- ){
Item[i].name[l] = '\0';
}
for (k = 0; k < strlen(tok); k++){
if (( tok[k] == '\n') || (tok[k] == '\r' )){
tok[k] = '\0';
}
}
if ((inFile = fopen( tok , "rb")) == NULL){
perror("\nError opening mr file:");
fclose(inFile);
return 0;
}
while( ( readByte = fgetc(inFile) ) != EOF ){
fputc(readByte, outFile);
}
Item[i].size = ftell(inFile);
fprintf(stdout, "\n%d" , Item[i].size);
if ((Item[i].size % 512) != 0){
for ( k = 0 ; k < (blockSize - (Item[i].size % blockSize)) ; k++){
fputc(padByte, outFile);
}
}
Item[i].sizeWithPadding = BlockIt(Item[i].size);
totalDataSize += Item[i].sizeWithPadding;
if (i == 0){
Item[i].offset = BlockIt(hs);
} else {
Item[i].offset = ((Item[ i - 1 ].sizeWithPadding) + (Item[ i - 1 ].offset));
}
fprintf(stdout, "\n%ld", Item[i].offset);
i++;
fclose(inFile);
}
fseek(outFile, 0 , SEEK_SET);
fwrite(&header, sizeof header, 1 , outFile);
fwrite(&hs, 4, 1 ,outFile);
fprintf(stdout, "\n Size of Header is %d.", hs);
for (i = 0 ; i < images ; i++ ){
fwrite(&Item[i].name, 1 , 24 , outFile);
fwrite(&Item[i].offset, 4, 1 , outFile);
fwrite(&Item[i].size, 4, 1, outFile);
}
fclose(outFile);
fclose(inFile);
return totalDataSize;
}
unsigned int GetHeaderSize(void){
unsigned int ret = BlockIt(13 + ( 32 * images));
return ret;
}
unsigned long int BlockIt(unsigned long int isize){
if ((isize % blockSize) == 0){
return isize;
}else{
return isize + (blockSize - (isize %blockSize));
}
}
int main(int argc, char **argv){
int c;
while ((c = getopt (argc, argv, "o:n:")) != -1){
switch(c)
{
case 'o':
outputFileName = optarg;
break;
case 'n':
images = atoi(optarg);
break;
}
}
ReadList();
return;
}
nice it's very important
Does this really work for Moto G 2015? i dont wanna break my phone
how does the bootlogo look
and can you post a pic
@makers_mark Would it be possible to get this as a bash script to run on Ubuntu?
Excellent, works beautifully.
dustin_b said:
@makers_mark Would it be possible to get this as a bash script to run on Ubuntu?
Click to expand...
Click to collapse
Yeah, it's possible, but what I think you're asking is if I can do it, and I'm not proficient enough to write a bash script to do everything my batch script does. You're probably better off running a Windows vm, or if you know what you want to replace with what, send me the images and I'll do it for you.
makers_mark said:
Yeah, it's possible, but what I think you're asking is if I can do it, and I'm not proficient enough to write a batch script to do everything my that batch script does. You're probably better off running a Windows vm, or if you know what you want to replace with what, send me the images and I'll do it for you.
Click to expand...
Click to collapse
Yeah, that's what I was getting at. I know nothing about it or I would do it so I just thought I would ask. I have a Windows laptop( a cheap one though that is slow), and I'm able to use your script on it. It works great by the way! But I prefer my Ubuntu laptop and try not to use the other if possible. I will just use it on Windows or check out the VM like you suggested. Thanks for replying though and for the script!
Sent from my XT1575 using Tapatalk
edit moto x pure .bin
I cannot get v1.1 to validate my logo.bin file and open it to edit. Im pretty sure it is valid because I flashed it and am currently using it. phone is a moto x pure. any tips?
etmidust said:
I cannot get v1.1 to validate my logo.bin file and open it to edit. Im pretty sure it is valid because I flashed it and am currently using it. phone is a moto x pure. any tips?
Click to expand...
Click to collapse
You probably downloaded a logo.bin that was altered. The popular thing to do is simply use a hex editor and edit the offset of the logo unlocked image so that it points to the logo boot image. These will fall validation with my program because I check that the offset of an image meets exactly at the tail end of the previous image. It may work on your phone, but it's a safety I put there to check mainly the modified logo that is produced. I may change that though for the initial validation.
makers_mark said:
You probably downloaded a logo.bin that was altered. The popular thing to do is simply use a hex editor and edit the offset of the logo unlocked image so that it points to the logo boot image. These will fall validation with my program because I check that the offset of an image meets exactly at the tail end of the previous image. It may work on your phone, but it's a safety I put there to check mainly the modified logo that is produced. I may change that though for the initial validation.
Click to expand...
Click to collapse
Thanks, ill keep looking for one I can actually edit then.
etmidust said:
Thanks, ill keep looking for one I can actually edit then.
Click to expand...
Click to collapse
You have one on your phone ☺ I don't have a device, so I don't know the exact location of your logo partition. But follow this guide and you can grab yours off of your phone.
EDIT :
Unless the one there is the already modified one. In that case, try dragging your whole downloaded system image (from Motorola) onto the program. If it is unzipped, the program will find it and cut it out.
etmidust said:
Thanks, ill keep looking for one I can actually .edit then.
Click to expand...
Click to collapse
in the Moto X pure forums, development thread there is a return to stock tool that contains an unmodified boot logo.
NEVERMIND I'm stupid, it's in the development section for the Moto X threads.
Could anybody upload the stock logo.bin? I already have an altered one so I can't rip mine from my phone and my internet (yes, at home) has a data cap so I can't really download the stock image and extract the logo.bin from there. Thanks.
bigfunkychiken said:
NEVERMIND I'm stupid, it's in the development section for the Moto X threads.
Could anybody upload the stock logo.bin? I already have an altered one so I can't rip mine from my phone and my internet (yes, at home) has a data cap so I can't really download the stock image and extract the logo.bin from there. Thanks.
Click to expand...
Click to collapse
Sure, but what is your device model? XT1540?
Thank you for this. It works perfect for my Droid Turbo and is VERY user friendly!
very good. It was very useful.
Can you also add a stock boot image that we can use as a template? All others are from the same modified source that fail validation.
Related
This is a hybrid batch and C program that I wrote to decode and encode the MotoLogo image container. It will allow you to edit or replace any of the 23 images in your logo partition. Click here to see all of the images. This will also work with any Motorola device utilizing this current format.
The logo partition has nothing to do with your boot animation. Your boot animation actually comes right after the static image, that in this case says "Google" in catull font; and if you have an unlocked bootloader, additionally there will be a little lock that appears to be open (aka "dummy locked") in the bottom center of the screen. Your boot animation follows after this screen goes away, your boot animation is typically animated or dynamic. The static screen with "Google" is known as your splash screen to some, or boot screen to others. This tool allows you to change the static image (splash screen) and not your boot animation.Thanks to GrayBoltWolf for making this video!!
Download the "MotoLogo Injector v.97b" zip file at the bottom of this post.
Extract the zip file to a new folder.
To use just drag any file that you think might have a MotoLogo container in it onto the batch file "MotoLogo_Injectorv97b.bat" (I have included your Nexus 6 71.05 bootloader image in the zip, so just drag it onto the batch script)
The program will then find the Container in the file, extract it and validate every byte in it, and output it in the "Projects" folder.
A newly created folder will pop up that contains the raw image files, PNG image files, some identification files, and your extracted "logo.bin"
There will also be two new batch files in the folder that will make it easy to close the program, edit the images, then just click one of the batch files to get back into the program to re-encode the images. The difference in the two batch files is that one of them will re-encode the logo bin in a "Strict" way, and the other way is "Non-Strict"
Strict goes in the exact same order that the images were encoded in the first place.
Strict will fail if there are any more or any less images.
Strict will fail if any of the image names are changed.
Strict will check the resolution.
Strict will not let you have a Jpg, Bmp, ....any other format mixed in with the Pngs. (If you prefer to work with another image format, you can change that in the settings but you still can't mix them up inside of the "Images" folder; they should all be of the same type.
If an images resolution doesn't match the original images, it will warn you and give you options to resize or disregard the size difference.
Non-Strict simply goes through every file in the "Images" folder in alphanumerical order and makes it a raw file, encodes it, and puts the MotoLogo container together.
Non-Strict will take all kinds of differently formatted images.
The only reason I can see someone wanting to use Non-Strict is to delete images from a MotoLogo container.
In your "Images" folder is where you either edit or replace the PNG images. You can make them bigger, but I don't know what implications this may have as I do not have a Nexus 6. You must keep the names the exact same as the images, it is okay to change the image or even replace it (that's the whole point) but you have to keep the names the same for Strict mode, which I encourage you to use.
When you are finished editing your images:
You can open up the Original batch program if you haven't used it anymore (it remembers the last file loaded that had a successful validated container in it, so you don't have to drag and drop everytime). And then hit 1 "Rebuild Images Directory (Strict-In Order_Resolution Checks)"
Or you can click on the "Make MotoLogo Bin From Images Folder.bat" to go directly there.
After the program has rebuilt it, it will re validate the container, and then reconvert the container into view-able Pngs again. A new folder will automatically open. This contains your modified container called "build.bin". You can flash it from there.
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
This is a beta version, because I do not have a device to test on. So, the things I would normally know, i don't know. For instance:
I don't know if you can change all 23 images in the Nexus 6 bootloader, I assume you can, as they are all stored in the Logo partition. If you can, you can theme your bootloader
I also don't know if you can make certain graphics bigger that may overlap another, like the "Start" button interfering with the "arrows" for the rocker buttons.
You need to stay under the size of your "Logo" partition, I'm pretty sure fastboot just errors out if you try to write more data than a partition can hold. But I would like to know how big the partition mmcblk0p30 is. You could find out by executing the following, and posting the size of the C:\LogoPartition.raw file
Code:
adb shell
su
dd if=/dev/block/mmcblk0p30 of=/mnt/sdcard/LogoPartition.raw
exit
exit
adb pull /sdcard/LogoPartition.raw "C:\LogoPartition.raw"
adb kill-server
You may not need the 'mnt' before the "/sdcard/LogoPartition.raw" in the DD command. Please do not try this if you are not familiar with the command, because you could mess some stuff up if you accidentally reverse the "if" and "of"
Thanks to @grim489 for testing changing the logo_boot "Google" image!
I am not responsible for any damage done to your device!! Source is in Posts 2 & 3!
SOURCE:
MotoLogoCodec.c
Code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#define OUT_FILE "logo.bin"
#define MOTOLOGO_BARE_HEADER 13
#define MOTOLOGO_IMG_BLK_SIZE 32
#define BIT_SET 0x8000
#define IS_BIT_SET(x) (x & BIT_SET)
#define COLORS 3
#define SWAP(x) (((x & 0xFF00) >> 8) | ((x & 0x00FF) << 8))
typedef struct {
unsigned short count;
unsigned char color[COLORS];
} motoSet;
typedef struct {
char header[8];
unsigned short width;
unsigned short height;
} motoHead;
typedef struct {
char name[24];
unsigned long offset;
unsigned long size;
unsigned short totalBlocks;
unsigned long totalSize;
motoHead imageHead;
} imageHead;
typedef struct {
unsigned char r;
unsigned char g;
unsigned char b;
} pixel;
void MotoRunEncode(void);
int FindMotoLogo(void);
int ParseHeader(unsigned long, int);
void CutMRImageOut(int, char*, unsigned long);
unsigned long int BlockIt(unsigned long int);
void MotoDecode(int, char*, unsigned short, unsigned short, unsigned long, int);
unsigned short pad = 1;
unsigned short addDetails = 0;
unsigned short cutMR = 0;
unsigned short decode = 0, encode = 0;
unsigned short blockSize = 512;
unsigned short pos = 0;
unsigned short filesFound = 0;
unsigned short logoOutput = 1;
unsigned short width = 0, height = 0;
char *inputFile, *base, *path;
char *motoLogoHeader;
unsigned long start, end;
FILE *inStream;
FILE *outStream;
char command[512];
char padByte = 0xff;
void MotoRunEncode(void)
{
unsigned int i,ind, m;
pixel line[width];
unsigned short count;
motoHead motoRunHeader;
if ((inStream = fopen(inputFile, "rb")) == NULL){
fclose(inStream);
fprintf(stderr, "\n%s\nCould not be opened.", inputFile);
return;
}
if ((outStream = fopen(base, "wb")) == NULL){
fclose(inStream);
fclose(outStream);
fprintf(stderr, "\n%s\nCould not be opened.", base);
return;
}
motoRunHeader.header[0] = 0x4D;
motoRunHeader.header[1] = 0x6F;
motoRunHeader.header[2] = 0x74;
motoRunHeader.header[3] = 0x6F;
motoRunHeader.header[4] = 0x52;
motoRunHeader.header[5] = 0x75;
motoRunHeader.header[6] = 0x6E;
motoRunHeader.header[7] = 0x00;
motoRunHeader.width = SWAP(width);
motoRunHeader.height = SWAP(height);
fwrite(&motoRunHeader, 1, sizeof(motoRunHeader), outStream);
for (i = 1; i <= height; i++){
fread(line, COLORS, width, inStream);
for (ind = 0, count = 0 ; ind <= width - 1; ){
if ((memcmp(&line[ind], &line[ind+1], 3) == 0)){
ind++;
count = 1;
while((ind <= width - 2) && ((memcmp(&line[ind], &line[ind+1], 3))== 0)){
count++;
ind++;
}
if (count == 1){
count++;
ind++;
goto LOOP;
} else {
count++;
count |= BIT_SET;
count = SWAP(count);
fwrite(&count, 1, 2, outStream);
fwrite(&line[ind], 1, 3, outStream);
}
ind++;
} else {
count = 1;
ind++;
LOOP:
while (((ind >= width -2)&&(ind <= width -1)) || ((ind <= width - 2) && (memcmp(&line[ind], &line[ind+1], 3) != 0)) || ((ind <= width - 3) && (memcmp(&line[ind+1], &line[ind+2], 3) != 0))){
count++;
ind++;
}
count = SWAP(count);
fwrite(&count, 1, 2, outStream);
fwrite(&line[ind - SWAP(count)], SWAP(count), COLORS, outStream);
continue;
}
}
}
return;
}
int FindMotoLogo(void)
{
char header[] = {0x4D,0x6F,0x74,0x6F,0x4C,0x6F,0x67,0x6F,0x00};
unsigned long int firstOffset;
int readByte;
char string[9];
if ((inStream = fopen(inputFile, "rb")) == NULL){
fclose(inStream);
fprintf(stderr, "\n%s\nCould not be opened.", inputFile);
return;
}
int inNumber = fileno(inStream);
while ((readByte = fgetc(inStream)) != EOF){
if (readByte == header[pos]){
if (pos == 8){
start = (ftell(inStream) - 9);
fseek(inStream, start + 9, SEEK_SET);
read(inNumber, &end, 4);
fseek(inStream, start + 9 + 4 + 24, SEEK_SET );
read(inNumber, &firstOffset, 4);
fseek(inStream, start + firstOffset, SEEK_SET );
read(inNumber, &string, 9);
if (strcmp(string, "MotoRun") == 0){
fseek(inStream, start + 13, SEEK_SET );
return (ParseHeader(end, inNumber));
} else {
pos = 0;
fseek(inStream, start + 9, SEEK_SET );
continue;
}
} else {
pos++;
continue;
}
}
pos = 0;
}
close(inNumber);
fprintf(stderr,"\n%d MotoLogo (logo.bin) files found.", filesFound);
return;
}
int ParseHeader(unsigned long end, int inNumber)
{
unsigned int imageCounter = (end - MOTOLOGO_BARE_HEADER) / MOTOLOGO_IMG_BLK_SIZE;
imageHead motomoto[imageCounter];
int i;
unsigned long logoSize, pos;
for(i=0; i < imageCounter; i++){
read(inNumber, &motomoto[i], 32);
motomoto[i].totalSize = BlockIt(motomoto[i].size);
motomoto[i].totalBlocks = (motomoto[i].totalSize /blockSize);
fprintf(stdout,"\nName: %s\nOffset in Logo.bin: %ld\nImage Data Size: %ld",motomoto[i].name, motomoto[i].offset, motomoto[i].size);
fprintf(stdout,"\nTotal Size: %ld",motomoto[i].totalSize);
fprintf(stdout,"\nTotal Blocks: %d",motomoto[i].totalBlocks);
pos = ftell(inStream);
fseek(inStream, start + motomoto[i].offset, SEEK_SET);
if (cutMR){
CutMRImageOut(inNumber, motomoto[i].name, motomoto[i].size);
fseek(inStream, start + motomoto[i].offset, SEEK_SET); //moved this line inside the parentheses
}
read(inNumber, &motomoto[i].imageHead, 12);
motomoto[i].imageHead.width = SWAP(motomoto[i].imageHead.width);
motomoto[i].imageHead.height = SWAP(motomoto[i].imageHead.height);
fprintf(stdout,"\nWidth x Height: %dx%d",motomoto[i].imageHead.width,motomoto[i].imageHead.height);
fprintf(stdout,"\nHeader: %s\n\n",motomoto[i].imageHead.header);
if (decode){
MotoDecode(inNumber, motomoto[i].name, motomoto[i].imageHead.width, motomoto[i].imageHead.height, motomoto[i].size , i+1);
}
fseek(inStream, pos, SEEK_SET);
}
logoSize = motomoto[imageCounter-1].offset + motomoto[imageCounter-1].totalSize;
fprintf(stdout,"\nLogo.bin contains %ld image files and is %ld bytes in size", i, logoSize);
if (!(logoOutput)){
return 0;
}
sprintf(command,"%s\\%s", path , OUT_FILE );
if ((outStream = fopen(command, "wb")) == NULL){
fclose(outStream);
fprintf(stderr, "\n%s\\%s could not be opened.", path, OUT_FILE);
return 1;
}
int outNumber = fileno(outStream);
fseek(inStream, start, SEEK_SET );
char* logobin = malloc(logoSize);
read(inNumber, logobin, logoSize);
write(outNumber, logobin, logoSize);
close(outNumber);
free(logobin);
return 0;
}
void CutMRImageOut(int inNumber, char* name, unsigned long size){
char newName[26];
FILE *txt;
sprintf(command,"%s\\%s.mr", path , name );
if ((txt = fopen("build.ID", "a")) == NULL){
fclose(txt);
fprintf(stderr, "\nBuild.ID could not be opened.\n");
return;
}
if ((outStream = fopen(command, "wb")) == NULL){
fclose(outStream);
fclose(txt);
fprintf(stderr, "\n%s\\%s.mr could not be opened", path, name);
return;
}
sprintf(command,"%s\n", command );
sprintf(newName, "%s?", name);
fwrite(newName, strlen(newName), 1, txt);
fwrite(command, strlen(command), 1, txt);
fclose(txt);
int outNumber = fileno(outStream);
char *dataStream = malloc(size);
read(inNumber, dataStream, size);
write(outNumber, dataStream, size);
if (pad){
if ((size % blockSize) != 0){
unsigned int max = blockSize - (size % blockSize ), i;
for (i = 0; i < max; i++){
write(outNumber, &padByte , 1);
}
fprintf(stdout,"\n%d bytes padded to %s", max, name);
}
}
close(outNumber);
free(dataStream);
return;
}
unsigned long int BlockIt(unsigned long int isize){
if ((isize % blockSize) == 0){
return isize;
}else{
return isize + (blockSize - (isize %blockSize));
}
}
void MotoDecode(int inNumber, char* name, unsigned short width, unsigned short height, unsigned long size, int index)
{
unsigned short repeats, count;
unsigned char color[3];
unsigned long counter = 0;
motoSet data;
if (addDetails){
sprintf(command, "%s\\%03d_%dx%d_%s.bgr24", path , index, width, height, name);
} else {
sprintf(command, "%s\\%s.bgr24", path, name);
}
if ((outStream = fopen(command, "wb")) == NULL){
fclose(outStream);
fprintf(stderr, "\n%s\nCould not be opened.", command);
return;
}
int outNumber = fileno(outStream);
while((read(inNumber, &data, 5) != EOF) && (counter < size)){
counter += 5;
if ((counter >= size ) || (data.count == 0xffff)){
close(outNumber);
return;
}
data.count = SWAP(data.count);
if (IS_BIT_SET(data.count)){
data.count &= ~BIT_SET;
for (repeats = 0;repeats < data.count; repeats++){
write(outNumber, &data.color, COLORS);
}
} else {
write(outNumber, &data.color, COLORS);
for (repeats = 0; repeats < data.count -1; repeats++){
counter += COLORS;
if ((read(inNumber, color, COLORS) == EOF) || counter >= size){
write(outNumber, &color, COLORS);
close(outNumber);
return;
}
write(outNumber, &color, COLORS);
}
}
}
close(outNumber);
return;
}
int main(int argc, char **argv)
{
int c;
while ((c = getopt (argc, argv, "i:o:p:b:w:h:cdezna")) != -1){
switch(c)
{
case 'a':
addDetails = 1;
break; //add index number and resolution to decoded filenames
case 'i':
inputFile = optarg;
break;
case 'o':
base = optarg;
break;
case 'p':
path = optarg;
break;
case 'b':
blockSize = atoi(optarg);
break;
case 'c':
cutMR = 1;
break;
case 'd':
decode = 1;
break;
case 'e':
encode = 1;
break;
case 'z':
pad = 0;
break;
case 'n':
logoOutput = 0;
break;
case 'w':
width = atoi(optarg);
break;
case 'h':
height = atoi(optarg);
break;
}
}
if (encode == 1){
MotoRunEncode();
return;
}
return(FindMotoLogo());
}
MotoLogoValidator.c
Code:
/*
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#define MOTOLOGO_BARE_HEADER 13
#define MOTOLOGO_IMG_BLK_SIZE 32
#define BIT_SET 0x8000
#define IS_BIT_SET(x) (x & BIT_SET)
#define COLORS 3
#define SWAP(x) (((x & 0xFF00) >> 8) | ((x & 0x00FF) << 8))
typedef struct {
unsigned short count;
unsigned char color[COLORS];
} motoSet;
typedef struct {
char header[8];
unsigned short width;
unsigned short height;
} motoHead;
typedef struct {
char name[24];
unsigned long offset;
unsigned long size;
unsigned short totalBlocks;
unsigned long totalSize;
motoHead imageHead;
} imageHead;
typedef struct {
unsigned char r;
unsigned char g;
unsigned char b;
} pixel;
int FindMotoLogo();
int ValidateMotoLogoHeader();
unsigned long int BlockIt(unsigned long int);
int VerifyImages(char*, unsigned short, unsigned short, unsigned long);
unsigned short pos, inNumber, blockSize = 512;
char *inputFile;
unsigned long start, end;
FILE *inStream;
FILE *txt;
char command[512];
char padByte = 0xff;
int FindMotoLogo()
{
char header[] = {0x4D,0x6F,0x74,0x6F,0x4C,0x6F,0x67,0x6F,0x00};
unsigned long int firstOffset;
int readByte;
char string[9];
for (pos = 0 ; pos <= 8 ; pos++ ){
if ((readByte = fgetc(inStream)) == header[pos]){
fprintf(stdout,"\nHeader:\n%d %02x",pos, header[pos]);
if (pos == 8){
fprintf(stdout, "\nHeader Match");
start = 0;
fseek(inStream, start + 9, SEEK_SET);
read(inNumber, &end, 4);
fseek(inStream, start + 9 + 4 + 24, SEEK_SET );
read(inNumber, &firstOffset, 4);
fseek(inStream, start + firstOffset, SEEK_SET );
read(inNumber, &string, 9);
if (strcmp(string, "MotoRun") == 0){
fseek(inStream, start + 13, SEEK_SET );
fprintf(stdout,"\nEnd of MotoLogo Header is byte %d.\n", end);
return 0;
} else {
fprintf(stderr,"\nFirst offset in MotoLogo header doesn't point to an image header.");
return 1;
}
} else {
continue;
}
} else {
fprintf(stderr,"\nFile: %s\ndoes not start with a valid MotoLogo header.", inputFile);
return 1;
}
}
return 1;
}
int ValidateMotoLogoHeader()
{
unsigned int imageCounter = (end - MOTOLOGO_BARE_HEADER) / (MOTOLOGO_IMG_BLK_SIZE);
fprintf(stdout,"\n%d images referenced in header.\nChecking Images.\n", imageCounter);
imageHead motomoto[imageCounter];
int i;
char motoRunHeader[] = "MotoRun\0";
fseek(inStream, 13, SEEK_SET);
for(i=0; i < imageCounter; i++){
read(inNumber, &motomoto[i], 32); //add an if parameter switch for the last element not to include the padding
motomoto[i].totalSize = BlockIt(motomoto[i].size);
motomoto[i].totalBlocks = (motomoto[i].totalSize /blockSize);
fprintf(stdout,"\nName: \"%s\"\nOffset In File: %ld\nImage Data Size: %ld",motomoto[i].name, motomoto[i].offset, motomoto[i].size);
fprintf(stdout,"\nTotal Size With Padding: %ld",motomoto[i].totalSize);
fprintf(stdout,"\nTotal Blocks: %d",motomoto[i].totalBlocks);
if (i != 0){
if ((motomoto[i-1].offset + motomoto[i-1].totalSize) == (motomoto[i].offset)){
fprintf(stdout, "\nOffsets match!");
} else {
fprintf(stderr, "\nOffsets do not match between %s and %s.\nVALIDATION FAILURE!\n", motomoto[i-1].name, motomoto[i].name);
return 1;
}
} else {
if (motomoto[i].offset == BlockIt(end)){
fprintf(stdout, "\nOffsets Match!");
} else {
fprintf(stderr, "\n%d is offset and %d is the end of the MotoLogo Header\nVALIDATION FAILURE!\n", motomoto[i].offset, BlockIt(end));
return 1;
}
}
pos = ftell(inStream);
fseek(inStream, motomoto[i].offset, SEEK_SET);
read(inNumber, &motomoto[i].imageHead, 12);
motomoto[i].imageHead.width = SWAP(motomoto[i].imageHead.width);
motomoto[i].imageHead.height = SWAP(motomoto[i].imageHead.height);
fprintf(stdout,"\nWidth x Height: %dx%d",motomoto[i].imageHead.width,motomoto[i].imageHead.height);
fprintf(stdout,"\nExpected Pixels: %d", (motomoto[i].imageHead.width * motomoto[i].imageHead.height));
if(strcmp(motoRunHeader, motomoto[i].imageHead.header) != 0){
fprintf(stderr, "\nHeader Should be \"%s\", not \"%s\"\nVALIDATION FAILED!\n", motoRunHeader, motomoto[i].imageHead.header);
return 1;
}
fprintf(stdout,"\nHeader: \"%s\"",motomoto[i].imageHead.header);
if (!VerifyImages(motomoto[i].name, motomoto[i].imageHead.width, motomoto[i].imageHead.height, motomoto[i].size - 12)){
fseek(inStream, pos, SEEK_SET);
continue;
} else {
return 1;
}
}
if ((txt = fopen("MoID.ID", "w")) == NULL){
fclose(txt);
fprintf(stderr, "\nMoID.ID could not be opened.\n");
return 1;
}
for(i=0; i < imageCounter; i++){
fprintf(txt, "%s,%d,%d,%d,%d,", motomoto[i].name, motomoto[i].imageHead.width, motomoto[i].imageHead.height, motomoto[i].totalSize, motomoto[i].totalBlocks);
fprintf(txt, "%d,%d\n", motomoto[i].offset, motomoto[i].size);
}
fclose(txt);
return 0;
}
unsigned long int BlockIt(unsigned long int isize){
if ((isize % blockSize) == 0){
return isize;
}else{
return isize + (blockSize - (isize %blockSize));
}
}
int VerifyImages(char* name, unsigned short width, unsigned short height, unsigned long size)
{
unsigned short line = 0, pixelsonline = 0;
unsigned long pixelsDecoded = 0, totalPixels = 0, bytesRead = 0;
motoSet data;
unsigned long posi;
while(bytesRead < size){
if ((bytesRead += read(inNumber, &data, 5)) == EOF){
return 0;
}
data.count = SWAP(data.count);
if (IS_BIT_SET(data.count)){
data.count &= ~BIT_SET;
pixelsonline += data.count;
} else {
posi = ftell(inStream);
fseek(inStream, (posi + (COLORS * (data.count - 1))), SEEK_SET);
pixelsonline += data.count;
bytesRead = bytesRead + (COLORS * (data.count - 1));
}
if (pixelsonline == width){
line++;
pixelsDecoded += pixelsonline;
pixelsonline = 0;
}
if ((pixelsonline == width) && ((pixelsDecoded / line) == pixelsonline)){
line++;
pixelsonline = 0;
}
}
fprintf(stdout,"\nPixels Decoded: %d\nBytes Read: %d\nSize Minus Header: %d\nLines Properly Terminated: %d", pixelsDecoded, bytesRead, size , line);
if ((pixelsDecoded == width * height) && (bytesRead == size) && (height == line )){
fprintf(stdout,"\n\"%s\" Is Encoded Correctly\n", name);
return 0;
}
if (pixelsDecoded != (width * height)){
fprintf(stderr, "\nThe total pixels decoded, %d, doesn't equal the resolution: %dx%d=%d",pixelsDecoded, width, height, (width * height));
}
if (bytesRead != size){
fprintf(stderr, "\nThe total bytes read, %d, is not equal to the encoded size, %d.", bytesRead, size);
}
if (height != line ){
fprintf(stderr, "\nAt least one run in the encoding runs past the edge of the screen.\nThis will not work.");
}
fprintf(stderr, "\n%s is not encoded correctly\nVALIDATION FAILURE!\n", name);
return 1;
}
int main(int argc, char **argv)
{
int c;
while ((c = getopt (argc, argv, "i:b:")) != -1){
switch(c)
{
case 'i':
inputFile = optarg;
break;
case 'b':
blockSize = atoi(optarg);
break;
}
}
if ((inStream = fopen(inputFile, "rb")) == NULL){
fclose(inStream);
fprintf(stderr, "\n%s\nCould not be opened.\n", inputFile);
return 1;
}
inNumber = fileno(inStream);
if (!FindMotoLogo()){
if (!ValidateMotoLogoHeader()){
fclose(inStream);
return 0;
}
}
fclose(inStream);
return 1;
}
BuildMotoLogo.c
[code[#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
typedef struct {
char name[24];
unsigned long offset;
unsigned long size;
unsigned long sizeWithPadding;
} imageHead;
unsigned long int ReadList(void);
unsigned int GetHeaderSize(void);
unsigned long int BlockIt(unsigned long int);
char *txtFileName;
FILE *inFile;
FILE *outFile;
char *outputFileName;
unsigned short images = 0;
unsigned short blockSize = 512;
unsigned long int ReadList(void){
char header[] = {0x4D,0x6F,0x74,0x6F,0x4C,0x6F,0x67,0x6F,0x00};
char line[512];
int readByte;
imageHead Item[images];
unsigned long int totalDataSize = 0;
int i = 0 , k = 0 , l = 0;
unsigned char padByte = 255;
unsigned long sizes[images];
char *s = "?";
char *tok;
unsigned long int hs;
if ((outFile = fopen (outputFileName, "wb")) == NULL){
perror("\nError opening output file:");
fclose(outFile);
}
hs = GetHeaderSize();
for ( i = 0 ; i < hs ; i++){
fputc(padByte, outFile);
}
i = 0;
hs = (images * 32) + 13;
while(fgets(line, sizeof line , stdin) != NULL){
tok = strtok(line, s);
sprintf(Item.name, "%s",tok);
tok = strtok(NULL, s);
for ( l = 24 ; l - strlen(Item.name) > 0 ; l-- ){
Item.name[l] = '\0';
}
for (k = 0; k < strlen(tok); k++){
if (( tok[k] == '\n') || (tok[k] == '\r' )){
tok[k] = '\0';
}
}
if ((inFile = fopen( tok , "rb")) == NULL){
perror("\nError opening mr file:");
fclose(inFile);
return 0;
}
while( ( readByte = fgetc(inFile) ) != EOF ){
fputc(readByte, outFile);
}
Item.size = ftell(inFile);
fprintf(stdout, "\n%d" , Item.size);
for ( k = 0 ; k < (blockSize - (Item.size % blockSize)) ; k++){
fputc(padByte, outFile);
}
Item.sizeWithPadding = BlockIt(Item.size);
totalDataSize += Item.sizeWithPadding;
if (i == 0){
Item.offset = BlockIt(hs);
} else {
Item.offset = ((Item[ i - 1 ].sizeWithPadding) + (Item[ i - 1 ].offset));
}
fprintf(stdout, "\n%ld", Item.offset);
i++;
fclose(inFile);
}
fseek(outFile, 0 , SEEK_SET);
fwrite(&header, sizeof header, 1 , outFile);
fwrite(&hs, 4, 1 ,outFile);
fprintf(stdout, "\n Size of Header is %d.", hs);
for (i = 0 ; i < images ; i++ ){
fwrite(&Item.name, 1 , 24 , outFile);
fwrite(&Item.offset, 4, 1 , outFile);
fwrite(&Item.size, 4, 1, outFile);
}
fclose(outFile);
fclose(inFile);
return totalDataSize;
}
unsigned int GetHeaderSize(void){
unsigned int ret = BlockIt(13 + ( 32 * images));
return ret;
}
unsigned long int BlockIt(unsigned long int isize){
if ((isize % blockSize) == 0){
return isize;
}else{
return isize + (blockSize - (isize %blockSize));
}
}
int main(int argc, char **argv){
int c;
while ((c = getopt (argc, argv, "o:n:")) != -1){
switch(c)
{
case 'o':
outputFileName = optarg;
break;
case 'n':
images = atoi(optarg);
break;
}
}
ReadList();
return;
}[/code]
SOURCE:
MotoLogo_Injectorv.97b.bat
Code:
@echo off&setlocal enabledelayedexpansion
MODE CON:COLS=78 LINES=1024&set "vers=.97b"
title BETA BETA BETA BETA BETA Motorola Image Injector v%vers% BETA BETA BETA BETA BETA
cd /d "%~dp0"
set "file=%~1"
set /a "aspectMultiplier=100000"
set "useDefaultViewer="
set "syslog=>>"%~dp0sys\log.txt""
set "ffmpeglog="
set "validlog="
set "codeclog="
set "rawBGRDir=Raw_BGR_Files"
set "imagesDir=Images"
set "mrDir=Raw_MR_Files"
set "workHere=Projects"
set "IDfile=MoID.ID"
set "buildFile=build.ID"
set "dontShowInfo=1"
set "autoOpenFolders=1"
set "prevailExt=Png"
if not exist "%~dp0sys\" mkdir "%~dp0sys"
if exist "%~dp0sys\settings.cfg" (call :LoadSetFile)
if "%dontShowInfo%"=="1" set "validlog=>>"%~dp0sys\validation_log.txt" 2>&1" &set "codeclog=>>"%~dp0sys\codec_log.txt" 2>&1" &set "ffmpeglog=>>"%~dp0sys\ffmpeg_log.txt" 2>&1"
if exist "%~dp0sys\last_file" if "[%file%]"=="[]" call :Existing
if /i "[%file%]" equ "[$$$convert$$$]" set "file=%~2" &set "home=%~3" &call :SaveSettings &goto :ConvertFolder
if /i "[%file%]" equ "[$$notstrict$$]" set "file=%~2" &set "home=%~3" &call :SaveSettings &goto :NotStrictConvert
if "[%file%]" neq "[]" if exist "%file%" call :New &goto :Menu
call :help
:Settings
call :DrawHead
echo( ____________________________________________________________________________
echo(
if %dontShowInfo%==1 (
echo( 1 - Show Info On The Screen ^(currently data is logged^)) else (echo( 1 - Log Info To A Text File ^(currently data is shown on screen^))
)
echo(
if %autoOpenFolders%==1 (
echo( 2 - Auto Open Folders After A New File Is Created ^(currently is On^)) else (echo( 2 - Auto Open Folders After A New File Is Created ^(currently is Off^))
echo(
echo( 3 - Change Which Image Format To Use ^(currently it is %prevailExt%^)
echo(
echo( 4 - Clear Logs In Sys Folder
echo(
echo( 5 - Exit
echo(
choice /n /m " Please Select A Menu Number:" /c:12345
if errorlevel 1 set k=1
if errorlevel 2 set k=2
if errorlevel 3 set k=3
if errorlevel 4 set k=4
if errorlevel 5 set k=5
if %k%==1 if %dontShowInfo%==1 (set "dontShowInfo=0") else (set "dontShowInfo=1")
if %k%==2 if %autoOpenFolders%==1 (set "autoOpenFolders=0") else (set "autoOpenFolders=1")
if %k%==3 call :ImageFormat
if %k%==4 2>nul del /q "%~dp0sys\*log*.txt
if %k%==5 goto :Menu
call :SaveSetFile
goto :Settings
:ImageFormat
call :DrawHead
echo(&echo( If you change the extension used in the program, you will no longer
echo( be able to edit older project folders that used the current image extension.
echo( You would have to switch back to what ever image format was used if you wanted
echo( to open an older project. Unless you rebuild a folder in Non Strict, which
echo( would allow you to use all different image types.
echo(&echo( Enter The Extension ^(without the "."^) That You Want To Use.
echo( Currently it is %prevailExt%
set /p prevailExt=: || set "prevailExt=Png"
call :SaveSetFile
goto :eof
:LoadSetFile
<"%~dp0sys\settings.cfg" (
set /p dontShowInfo=
set /p autoOpenFolders=
set /p prevailExt=
)
goto :eof
:SaveSetFile
>"%~dp0sys\settings.cfg" (
echo(%dontShowInfo%
echo(%autoOpenFolders%
echo(%prevailExt%
)
goto :eof
:Existing
call :LoadSettings
call :SaveSettings
if not exist "%file%" call :NotThere
if not exist "%home%\%IDfile%" call :NotThere
if not exist "%home%\%buildFile%" call :NotThere
call :LoadDetails "%home%\%IDfile%"
goto :menu
pause
:New
call :DrawHead
call :LoadNewFile
%codeclog% "%~dp0bin\MotoLogoCodec.exe" -i "%file%" -o "%name%" -p "%home%" || (if defined "%home%" if exist "%home%\" rd /q "%home%" &call :NoLogo)
echo(&echo( MotoLogo container found, validating data...
%validlog% "%~dp0bin\MotoLogoValidator.exe" -i "%file%" || (
if exist "%home%\logo.bin" (
set "file=%home%\Logo.bin"
%validlog% "%~dp0bin\MotoLogoValidator.exe" -i "!file!" || (if defined home if exist "%home%\" del /q "%home%\*.bin" &rd /q "%home%" &call :ValidFail)
) else (if defined home if exist "%home%\" del /q "%home%\*.bin" &rd /q "%home%" &call :ValidFail)
)
set "file=%home%\logo.bin"
call :SaveSettings
echo(&echo( VALIDATION SUCCESSFUL&echo(
%syslog% move "%~dp0%IDfile%" "%home%\"
call :LoadDetails "%home%\%IDfile%"
call :MakeFolders
echo(&echo( Extracting images....Please wait...&echo(
%codeclog% "%~dp0bin\MotoLogoCodec.exe" -z -c -d -i "%file%" -o "%name%" -p "%home%\%mrDir%"
%syslog% move "%~dp0%buildFile%" "%home%\"
%syslog% move "%home%\%mrDir%\*.bgr24" "%home%\%rawBGRDir%\"
call :ffmpegit "%home%\%rawBGRDir%" "%home%\%imagesDir%"
goto :eof
:ValidFail
call :DrawHead
echo(&echo(&echo( Container Failed Validataion..
echo( Press any key to exit.
pause>nul
exit
goto :eof
:MakeFolders
2>nul mkdir "%home%\%rawBGRDir%"
2>nul mkdir "%home%\%mrDir%"
2>nul mkdir "%home%\%imagesDir%"
goto :eof
:Menu
call :DrawHead
call :DrawDetails
echo( ____________________________________________________________________________
echo(
echo( 1 - Rebuild %imagesDir% Directory ^(Strict-In Order-Resolution Checks^)
echo(
echo( 2 - Rebuild %imagesDir% Directory ^(Not Strict^)
echo(
echo( 3 - Open Current Project Folder
echo(
echo( 4 - Settings
echo(
echo( 5 - Fastboot Flash Current File
echo(
echo( 6 - Exit
echo(
choice /n /m " Please Select A Menu Number:" /c:123456
if errorlevel 1 set k=1
if errorlevel 2 set k=2
if errorlevel 3 set k=3
if errorlevel 4 set k=4
if errorlevel 5 set k=5
if errorlevel 6 set k=6
if %k%==1 call :ConvertFolder
if %k%==2 call :NotStrictConvert
if %k%==3 start "" "%home%"
if %k%==4 call :Settings
if %k%==5 call :Fla****
if %k%==6 goto :finish
goto :Menu
:Fla****
call :DrawHead
call :DrawDetails
echo(&echo( Your logo is ready to be flashed.&echo( File:%file%
echo(&echo( Make sure that your device is connected and in Bootloader Mode.
echo(&echo( The following command will be issued:
echo( fastboot flash logo "%file%"
echo(&echo( Press 1 to flash the logo partition, or 2 to go back.&echo(
echo(&echo( 1 - Flash
echo(&echo( 2 - Go Back
echo(
choice /n /m " Please select a menu number:" /c:12
if errorlevel 1 set k=1
if errorlevel 2 set k=2
if !k!==1 (call )
if !k!==2 goto :Menu
"%~dp0bin\fastboot.exe" flash logo "%file%" &&echo. Finished..Press any key to Reboot your device.&&pause>nul&&"%~dp0bin\fastboot.exe" reboot
goto :eof
:NotStrictConvert
call :DrawHead
echo(&echo( This will rebuild all images in the %imageDir% folder.
echo( It will rebuild in alphabetical order while disregarding
echo( original width, height, position in bin file. You can pretty
echo( much put any image format in here and get an encoded bin file.
echo( Press 1 to Continue or 2 to Go Back
echo(&echo( 1 - Continue
echo(&echo( 2 - Go Back
echo(
choice /n /m "please select a menu number:" /c:12
if errorlevel 1 set k=1
if errorlevel 2 set k=2
if !k!==1 (call )
if !k!==2 goto :Menu
if exist "%home%\errors.txt" del /q "%home%\errors.txt"
if not exist "%home%\%IDfile%" call :NotThere
if not exist "%home%\%buildFile%" call :NotThere
call :LoadDetails "%home%\%IDfile%"
if defined home if exist "%home%\" rd /s /q "%home%\Not_Strict_Modified\" 2>nul
2>nul md "%home%\Not_Strict_Modified"
2>nul md "%home%\Not_Strict_Modified\%rawBGRDir%"
2>nul md "%home%\Not_Strict_Modified\%mrDir%"
set /a imageCount=0
2>nul del /q "%home%\%imagesDir%\Thumbs.db"
for /f %%a in ('dir /b /a-d-h "%home%\%imagesDir%\*.*"') do (
set /a imageCount=!imageCount!+1
echo( Converting: %%a
set "name=%%~na"
set name=!name:~0,24!
for /f "tokens=1-8* delims=," %%A in ('bin\ffmpeg -hide_banner -i "%home%\%imagesDir%\%%a" -f rawvideo -vcodec rawvideo -pix_fmt bgr24 -y "%home%\Not_Strict_Modified\%rawBGRDir%\!name!.bgr24" 2^>^&1^|findstr /rxic:".*stream #0:0.*[0-9]x[0-9].*"') do (
echo(%%A >"%home%\imageres"
echo(%%B >>"%home%\imageres"
echo(%%C >>"%home%\imageres"
echo(%%D >>"%home%\imageres"
echo(%%E >>"%home%\imageres"
echo(%%F >>"%home%\imageres"
echo(%%G >>"%home%\imageres"
echo(%%H >>"%home%\imageres"
)
for /f "tokens=1-3 delims=x " %%I in ('type "%home%\imageres"^|findstr /rxic:".*[0-9]x[0-9].*"') do set /a width=%%I &set /a height=%%J
if not defined width echo( Error: "Width undefined in %%a">>"%home%\errors.txt"
if not defined height echo( Error: "Height undefined in %%a">>"%home%\errors.txt"
if not exist "%home%\Not_Strict_Modified\%rawBGRDir%\!name!.bgr24" echo( Error: "%home%\Not_Strict_Modified\%rawBGRDir%\!name!.bgr24" Was not created.>>"%home%\errors.txt"
echo( Encoding: !name!.bgr24
%codeclog% "%~dp0bin\MotoLogoCodec.exe" -e -i "%home%\Not_Strict_Modified\%rawBGRDir%\!name!.bgr24" -o "%home%\Not_Strict_Modified\%mrDir%\!name!.mr" -w !width! -h !height!
if not exist "%home%\Not_Strict_Modified\%mrDir%\!name!.mr" echo( Error: "%home%\Not_Strict_Modified\%mrDir%\!name!.mr" Was not sucessfully encoded.>>"%home%\errors.txt"
echo(!name!?%home%\Not_Strict_Modified\%mrDir%\!name!.mr>>"%home%\Not_Strict_Modified\%buildFile%"
set check=
)
del /q "%home%\imageres"
if exist "%home%\errors.txt" call :Error
echo( Rebuilding Encoded Files...
"%~dp0bin\BuildMotoLogo.exe" <"%home%\Not_Strict_Modified\%buildFile%" -o "%home%\Not_Strict_Modified\build.bin" -n %imageCount%
%validlog% "%~dp0bin\MotoLogoValidator.exe" -i "%home%\Not_Strict_Modified\build.bin" || goto :RebuildError
set "file=%home%\Not_Strict_Modified\build.bin"
set "home=%home%\Not_Strict_Modified"
call :SaveSettings
%syslog% move "%~dp0%IDfile%" "%home%\"
call :LoadDetails "%home%\%IDfile%"
echo( Validation succesful
2>nul md "%home%\%imagesDir%"
call :ffmpegit
goto :Menu
:ConvertFolder
call :DrawHead
if exist "%home%\errors.txt" del /q "%home%\errors.txt"
if not exist "%home%\%IDfile%" call :NotThere
if not exist "%home%\%buildFile%" call :NotThere
call :LoadDetails "%home%\%IDfile%"
echo(&echo( Checking Resolutions..
if defined home if exist "%home%\" rd /s /q "%home%\Modified\" 2>nul
2>nul md "%home%\Modified"
2>nul md "%home%\Modified\%rawBGRDir%"
2>nul md "%home%\Modified\%mrDir%"
for /l %%a in (1,1,%images%) do (
echo( Converting: !logoName[%%a]!
if not exist "%home%\%imagesDir%\!logoName[%%a]!.%prevailExt%" (
call :DrawHead
echo(&echo( An image for !logoName[%%a]! is missing in the %imagesDir% folder.
echo(&echo( If you are trying to remove an image from you bin file, you need
echo( to rebuild the %imagesDir% folder in Non Strict Mode.
echo(&echo( Press any key to return to the menu.
pause>nul
goto :Menu
)
for /f "tokens=1-8* delims=," %%A in ('bin\ffmpeg -hide_banner -i "%home%\%imagesDir%\!logoName[%%a]!.%prevailExt%" -f rawvideo -vcodec rawvideo -pix_fmt bgr24 -y "%home%\Modified\%rawBGRDir%\!logoName[%%a]!.bgr24" 2^>^&1^|findstr /rxic:".*stream #0:0.*[0-9]x[0-9].*"') do (
echo(%%A >"%home%\imageres"
echo(%%B >>"%home%\imageres"
echo(%%C >>"%home%\imageres"
echo(%%D >>"%home%\imageres"
echo(%%E >>"%home%\imageres"
echo(%%F >>"%home%\imageres"
echo(%%G >>"%home%\imageres"
echo(%%H >>"%home%\imageres"
)
for /f "tokens=1-3 delims=x " %%I in ('type "%home%\imageres"^|findstr /rxic:".*[0-9]x[0-9].*"') do set /a width=%%I &set /a height=%%J
if not defined width echo( Error: "Width undefined in !logoName[%%a]!.%prevailExt%">>"%home%\errors.txt"
if not defined height echo( Error: "Height undefined in !logoName[%%a]!.%prevailExt%">>"%home%\errors.txt"
if !width! neq !logoWidth[%%a]! set check=1
if !height! neq !logoHeight[%%a]! set check=1
if defined check call :Aspect !width! !height! !logoWidth[%%a]! !logoHeight[%%a]! "%home%\%imagesDir%\!logoName[%%a]!.%prevailExt%" "%home%\Modified\%rawBGRDir%\!logoName[%%a]!.bgr24" "!logoName[%%a]!"
if not exist "%home%\Modified\%rawBGRDir%\!logoName[%%a]!.bgr24" echo( Error: "%home%\Modified\%rawBGRDir%\!logoName[%%a]!.bgr24" Was not created.>>"%home%\errors.txt"
echo( Encoding: !logoName[%%a]!
%codeclog% "%~dp0bin\MotoLogoCodec.exe" -e -i "%home%\Modified\%rawBGRDir%\!logoName[%%a]!.bgr24" -o "%home%\Modified\%mrDir%\!logoName[%%a]!.mr" -w !width! -h !height!
if not exist "%home%\Modified\%mrDir%\!logoName[%%a]!.mr" echo( Error: "%home%\Modified\%mrDir%\!logoName[%%a]!.mr" Was not sucessfully encoded.>>"%home%\errors.txt"
echo(!logoName[%%a]!?%home%\Modified\%mrDir%\!logoName[%%a]!.mr>>"%home%\Modified\%buildFile%"
set check=
set width=
set height=
)
del /q "%home%\imageres"
if exist "%home%\errors.txt" call :Error
echo( Rebuilding Encoded Files...
"%~dp0bin\BuildMotoLogo.exe" <"%home%\Modified\%buildFile%" -o "%home%\Modified\build.bin" -n %images%
%validlog% "%~dp0bin\MotoLogoValidator.exe" -i "%home%\Modified\build.bin" || goto :RebuildError
set "file=%home%\Modified\build.bin"
set "home=%home%\Modified"
call :SaveSettings
%syslog% move "%~dp0%IDfile%" "%home%\"
call :LoadDetails "%home%\%IDfile%"
echo( Validation succesful
2>nul md "%home%\%imagesDir%"
call :ffmpegit
goto :Menu
:Aspect
set check=
set /a border=5
set /a border2=2*%border%
echo(&echo( Image: %~7
set /a newAspect=%aspectMultiplier%*%1/%2
set /a originalAspect=%aspectMultiplier%*%3/%4
echo(
echo( The resolution for %7 is different from the original image.
echo( New : %1x%2
echo( Original: %3x%4
echo(
echo( ____________________________________________________________________________
if "%originalAspect%"=="%newAspect%" (
echo(
echo( 1 - Stretch Or Shrink The Image To Fit The Original Size
echo(
echo( 2 - Do Nothing And Continue
echo(
choice /n /m "please select a menu number:" /c:12
if errorlevel 1 set k=1
if errorlevel 2 set k=2
if !k!==1 set "videoFilters=-vf "scale=%3:%4""
if !k!==2 goto :eof
) else (
echo(
if %3 gtr %4 (echo( 1 - Resize And Crop While Keeping The Original Aspect And Size ^(Upper Image^)) else (echo( 1 - Resize And Crop While Keeping The Original Aspect And Size ^(Left Image^))
echo(
if %3 gtr %4 (echo( 2 - Stretch Or Shrink The Image To Fit The Original Size ^(Lower Image^)) else (echo( 2 - Stretch Or Shrink The Image To Fit The Original Size ^(Right Image^))
echo(
echo( 3 - Do Nothing And Continue With %1x%2 Image
echo(
if %4 lss %3 (set /a ffw=%3+2*%border%&set /a ffh=%4*2+3*%border%&set "overlay=overlay=%border%:h+%border2%") else (set /a ffw=%3*2+3*%border%&set /a ffh=%4+2*%border%&set "overlay=overlay=w+%border2%:%border%")
if %originalAspect% lss %newAspect% (set "scale=scale=-1:%4") else (set "scale=scale=%3:-1")
"%~dp0bin\ffmpeg.exe" -loglevel fatal -i "%~5" -i "%~5" -filter_complex "color=red:!ffw!x!ffh!:1[bg];[0]!scale!, crop=%3:%4[sc0];[1]scale=%3:%4[sc1];[bg][sc0]overlay=%border%:%border%[x];[x][sc1]!overlay!" -y "%home%\test.png"%ffmpeglog%
if exist "%home%\test.png" if defined useDefaultViewer (start "" "%home%\test.png") else (rundll32 "%ProgramFiles%\Windows Photo Viewer\PhotoViewer.dll", ImageView_Fullscreen %home%\test.png)
choice /n /m "please select a menu number:" /c:123
if errorlevel 1 set k=1
if errorlevel 2 set k=2
if errorlevel 3 set k=3
if !k!==1 (
if %originalAspect% gtr %newAspect% set "videoFilters=-vf "scale=%3:-1, crop=%3:%4""
if %originalAspect% lss %newAspect% set "videoFilters=-vf "scale=-1:%4, crop=%3:%4""
)
if !k!==2 set "videoFilters=-vf "scale=%3:%4""
if !k!==3 goto :eof
2>nul del /q "%home%\test.png"
)
set /a width=%3
set /a height=%4
%ffmpeglog% "%~dp0bin\ffmpeg.exe" %ffdebug% %ffshowb% -i "%~5" !videoFilters! -f rawvideo -vcodec rawvideo -pix_fmt bgr24 -y "%~6"
goto :eof
:RebuildError
echo( There was a problem rebuilding the images..
echo( Press any key to exit.
pause>nul
goto :Finish
:Error
call :DrawHead
echo(&type "%home%\errors.txt"
echo(&echo( Press any key to exit..
pause >nul
goto :Finish
:DrawHead
cls echo( _________________________________________________________________________-_-
echo( Motorola Image Injector v%vers%
echo(
echo( written by Makers_Mark
echo( ____________________________________________________________________________
goto :eof
:DrawFileInfo
echo( File: %file% &echo( Size: %fileSize% Bytes ^(%megaSize%.%megaDeci% MB^)&echo( ____________________________________________________________________________
goto :eof
:DrawDetails
call :DrawFileInfo
"%~dp0bin\DrawDetails.exe" <"%home%\%IDfile%"
goto :eof
:NoLogo
call :DrawHead
echo(&echo( No Motorola Logo Images were found in the file.
echo( Press any key to exit....
pause>nul
exit
:LoadDetails
set /a images=0
for /f "tokens=1-7 delims=," %%t in ('type "%~1"') do (
set /a images+=1
set "logoName[!images!]=%%t" &set /a logoOffset[!images!]=%%y &set /a logoSize[!images!]=%%z &set /a logoSizeTotal[!images!]=%%w
set /a logoBlocks[!images!]=%%x &set /a logoWidth[!images!]=%%u &set /a logoHeight[!images!]=%%v
)
goto :eof
:dupename
if not exist "%~dp0%workhere%\!%~1!\" (goto :eof)
set /a unique=1
:dupe
if not exist "%~dp0%workhere%\!%~1!.%unique%\" (
set "%~1=!%~1!.%unique%"
goto :eof
) else (
set /a unique+=1
goto :dupe
)
goto :eof
:LoadNewFile
for %%? in ("%file%") do set /a "size=%%~z?" &set "filename=%%~nx?" &set "ext=%%~x?" &set "name=%%~n?"
set "newDir=%name%"
call :dupename "newDir"
set "home=%~dp0%workHere%\%newDir%"
2>nul mkdir "%home%"
goto :eof
:LoadSettings
<"%~dp0sys\last_file" (
set /p file=
set /p home=
set /p fileSize=
)
call :StripQuotes %file% %home%
goto :eof
:StripQuotes
set "file=%~1"
set "home=%~2"
goto :eof
:SaveSettings
for %%? in ("%file%") do set fileSize=%%~z?
set /a fileSize
set /a megaSize=%fileSize%/(1024*1024)
set /a remain=%fileSize% %% (1024*1024)
set /a megaDeci=(%remain%*1000)/(1024*1024)
>"%~dp0sys\last_file" (
echo("%file%"
echo("%home%"
echo(%fileSize%
)
goto :eof
:ffmpegit
echo( Converting Images Into %prevailExt% Images...
(for /f %%a in ('dir /b/a-d "%home%\%rawBGRDir%\*.bgr24"') do (
for /l %%? in (1, 1, %images%) do (
if "%%~na"=="!logoName[%%?]!" (
call set /a width=!logoWidth[%%?]!"
call set /a height=!logoHeight[%%?]!
)
)
"%~dp0bin\ffmpeg.exe" %ffdebug% %ffshowb% -loglevel fatal -f rawvideo -vcodec rawvideo -s !width!x!height! -pix_fmt bgr24 -i "%home%\%rawBGRDir%\%%~nxa" -y "%home%\%imagesDir%\%%~na.%prevailExt%"
))%ffmpeglog%
>"%home%\Make MotoLogo Bin From %imagesDir% Folder.bat" (
echo(@echo off
echo(cmd ^/c ^""%~dpnx0" $$$convert$$$ "%file%" "%home%"^"
echo(
)
>"%home%\Make MotoLogo Bin (Not Strict) From %imagesDir% Folder.bat" (
echo(@echo off
echo(cmd ^/c ^""%~dpnx0" $$notstrict$$ "%file%" "%home%"^"
echo(
)
if %autoOpenFolders%==1 start "" "%home%\"
goto :eof
:help
call :DrawHead
echo(&echo(
echo( You have to drag a file onto this batch file,
echo( in order to load a file into it.
echo( Press a key to close this window and exit.
pause >nul
goto :finish
:NotThere
call :Drawhead
echo(&echo(
echo( File^(s^) are missing. Reload File by dragging and dropping onto
echo( this batch file again.
echo( Press a key to close this window and exit.
pause>nul
goto :finish
:Finish
cls&exit
goto :eof
DrawDetails.c
Code:
#include <string.h>
#include <stdio.h>
#include <windows.h>
int main()
{
char *s = "," ;
char *token ;
int i , j = 1 , k , color ;
char line[80];
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
WORD originalColor;
GetConsoleScreenBufferInfo(hConsole, &consoleInfo);
originalColor = consoleInfo.wAttributes;
printf(" ____________________________________________________________________________\n");
printf(" Image Name WxH Size+ Blocks Offset Raw Size \n");
printf(" _________________________________________________________________________-_-\n");
while(fgets(line, sizeof line, stdin) != NULL){
if (( j % 2 ) == 0) {
color = 0x0B;
} else {
color = 0xB0;
}
SetConsoleTextAttribute(hConsole, color);
token = strtok(line, s);
for ( i = 0; i < 7; i++){
if (i==0){
printf(" %2d.%-24s", j,token);
token = strtok(NULL,s);
} else if ( i == 1 ){
printf("%dx", atoi(token));
token = strtok(NULL,s);
} else if ( i == 2 ){
printf("%d\t", atoi(token));
token = strtok(NULL,s);
} else if (( i > 2) && ( i < 6 )){
printf("%d\t", atoi(token));
token = strtok(NULL,s);
} else {
printf("%-13d\r\n", atoi(token));
token = strtok(NULL,s);
}
}
j++;
}
SetConsoleTextAttribute(hConsole, originalColor);
}
It looks to be 8MB. I can't upload though.
grim489 said:
It looks to be 8MB. I can't upload though.
Click to expand...
Click to collapse
Thats cool, no upload needed. Just curious about the filesize. Thanks again!
No problem! I can't help with much else though ?
grim489 said:
No problem! I can't help with much else though ?
Click to expand...
Click to collapse
Hey you've done enough, I almost forgot to thank you for testing my initial image in the other thread, added to the OP.
I'll poke around later with this. Kinda missed having this ability coming from the nexus 5.
any youtube video on the startup animations? i wouldn't mind changing the google screen to saying NeXus 6 logo with the X colored logo
cobyman7035 said:
any youtube video on the startup animations? i wouldn't mind changing the google screen to saying NeXus 6 logo with the X colored logo
Click to expand...
Click to collapse
Thanks fellow XDAlien, almost forgot.. added to OP:
The logo partition has nothing to do with your boot animation. Your boot animation actually comes right after the static image, that in this case says "Google" in catull font; and if you have an unlocked bootloader, additionally there will be a little lock that appears to be open (aka "dummy locked") in the bottom center of the screen. Your boot animation follows after this screen goes away, your boot animation is typically animated or dynamic. The static screen with "Google" is known as your splash screen to some, or boot screen to others. This tool allows you to change the static image (splash screen) and not your boot animation.
So I got it working. But the bootloader rejects anything that doesn't use the original resolution.
GrayBoltWolf said:
So I got it working. But the bootloader rejects anything that doesn't use the original resolution.
Click to expand...
Click to collapse
Thanks for that information. But for clarification, are you talking about images from just the bootloader screen? For example, if you try to change the logo_boot (the "GOOGLE" splash screen), can you use different resolutions?
makers_mark said:
Thanks for that information. But for clarification, are you talking about images from just the bootloader screen? For example, if you try to change the logo_boot (the "GOOGLE" splash screen), can you use different resolutions?
Click to expand...
Click to collapse
Same for all of them. If it is a higher resolution than the original then the bootloader freaks out and won't flash it.
Here is a video of how to change the boot logo:
Add it to the OP if you want.
Hello,
since I normally try to use as less Google services as possible and buy the Nexus devices always for the "open" HW, I was always a little anoyed by the Google logo on startup.
So thank you very much fpr this great tool. I directly tried it and replaced the Google logo on my Nexus 6 by a white NEXUS logo. I also removed the "UN"LOCK icon from the bootscreen.
Thank you very much again. Everthing works as expected
I attach the NEXUS logo I created for myself if somebody else wants it maybe.
makers_mark said:
Thanks for that information. But for clarification, are you talking about images from just the bootloader screen? For example, if you try to change the logo_boot (the "GOOGLE" splash screen), can you use different resolutions?
Click to expand...
Click to collapse
That's odd. I've changed min several times using all kinds of pictures. I just keep them under 300kb. I use a 1400x2560 photo and flash in TWRP. Never changed it in fastboot mode. I also put a transparent "lock" otherwise it'll show up on splash.
makers_mark said:
Thanks for that information. But for clarification, are you talking about images from just the bootloader screen? For example, if you try to change the logo_boot (the "GOOGLE" splash screen), can you use different resolutions?
Click to expand...
Click to collapse
That's odd. I've changed min several times using all kinds of pictures. I just keep them under 300kb. I use a 1400x2560 photo and flash in TWRP. Never changed it in fastboot mode.
BlockbusterF said:
Hello,
since I normally try to use as less Google services as possible and buy the Nexus devices always for the "open" HW, I was always a little anoyed by the Google logo on startup.
So thank you very much fpr this great tool. I directly tried it and replaced the Google logo on my Nexus 6 by a white NEXUS logo. I also removed the "UN"LOCK icon from the bootscreen.
Thank you very much again. Everthing works as expected
I attach the NEXUS logo I created for myself if somebody else wants it maybe.
Click to expand...
Click to collapse
Did you make this wall? Also how did u remove the " un"lock icon?
---------- Post added at 03:51 PM ---------- Previous post was at 03:20 PM ----------
Can I switch the "un" lock icon with maybe a iron man face?
Yes
---------- Post added at 02:40 PM ---------- Previous post was at 02:38 PM ----------
Galaxysm said:
Did you make this wall? Also how did u remove the " un"lock icon?
---------- Post added at 03:51 PM ---------- Previous post was at 03:20 PM ----------
Can I switch the "un" lock icon with maybe a iron man face?
Click to expand...
Click to collapse
I used a transparent one. So yes you can. I'd keep aspect ratio the same
713brianp27 said:
Yes
---------- Post added at 02:40 PM ---------- Previous post was at 02:38 PM ----------
I used a transparent one. So yes you can. I'd keep aspect ratio the same
Click to expand...
Click to collapse
I was able to do it. And changed the "unlock" icon for a Samus icon. Couldn't find a good iron man face/helmet at 96×96 size.
This is a program that I wrote to decode the newer style "logo.bin" files used in some OPPO, and OnePlus devices. Please read below so you can better understand this type of encoding being used:
What Is A Raw Image?
A raw image, whether it be a file or an image in memory, is simply pixel data. There is no extra information like width, height, name, end of line... Absolutely nothing, just pixel data. If you have an image that is raw and the resolution is 1080x1920 and you are using a typical RGB24 or BGR24 (like the ones used here), then your exact filesize or size in memory will be 1080x1920x3! We use 3 here because there is one byte for the R or red component, one for the G (green), and one for the B(blue).
What Is A Run Length Encoded Image?
A run length image encoding uses a count ;usually a single byte (char), 2 bytes (short int), or 4 bytes (long int); and then the pixel components. So instead of writing out 300 bytes of '0's to make a line of 100 black pixels. Black is RGB(0,0,0). You could encode this as 100, 0, 0, 0. And only use 4 bytes of data to get the exact same image as the 300 byte raw image. All the run length encoding I've found, except the Motorola style which is a little different, use a run length encoding that is pixel-oriented like this.
Now I've figured out this new one and it is a byte-oriented run length encoding. This is for runs of bytes, not pixels. You may think, well whats the big deal? When you add a little area of color, you increase the run length encoded image in you logo.bin immensely! You use 6 bytes per pixel if there aren't any runs of color data. If you had an image that was a 1080x1920 black image with a 25 pixel wide, by 25 pixel high red box in the middle. The encoder would be doing runs of black data efficiently until it reached the red area.
.....0 255 0 255 0 255 0 255 0 255 0 133 /// we've reached the top left corner of the red square /// 13 1 30 1 255 1 // << that was just one red pixel!! in bgr color order (13, 30, 255) <<// And it keeps going through the rest of the red pixels on that line using 6 bytes per pixel, which is the opposite of compression. Before reaching the red square the encoding was decoding to 255 zeros over and over, until finally 133 zeros. 255 zeros is 85 black pixels stored in just 2 bytes!
This type of encoding is only good for grey scale images. It is not good with color, but it still will handle color of course. In grey scale, the Red, Blue, and Green data components are always the same values. All the way from black (0,0,0) to white (255, 255, 255); including every shade of grey in between>>>(1,1,1) (2,2,2) (3,3,3)....(243, 243, 243) (244, 244, 244)<<<
One other difference in this method of run length encoding is that the color byte is before the count, which is backwards from all of the other methods.
The attachment contains the C source code (which is also in the 2nd post) and the executable that was compiled using mingw32 on a 64 bit Windows 7 pc. The png library that I used is LodePng, the source is in the download.
To use logoinjector:
Decode your logo.bin:
Code:
logoInjector.exe -i logo.bin -d
All the PNG 's will be extracted from logo.bin. Edit the PNGs that you want to change...
Note:
Your original "logo.bin" file is never changed, it is just read. If the file you try to load isn't a logo.bin file, or if it is the older style, then the program will tell you and exit
Inject the image(s) back in to the logo.bin:
Code:
logoinjector.exe -i logo.bin -j image_name_1 image_name_3
To list whats in your logo file:
Code:
logoinjector.exe -i logo.bin -l
For a more detailed list:
Code:
logoinjector.exe -i logo.bin -L
If the colors are messed up use the "-s" switch while decoding.
Code:
logoinjector.exe -i logo.bin -d -s
If you had to use the "-s" switch to decode properly, you'll have to use it to inject also:
Code:
logoinjector.exe -i logo.bin -j image_name -s
Note:
With version 1.2, you can put as many names after "-j" as you want, and it's not case sensitive. You also don't have to put the whole name. If you just put "-j fhd" every image in the logo.bin that starts with "fhd" will be injected. There has to be a PNG with the name in the directory though
The size of your modified.logo.bin will displayed along with the original size, if everything went good. Please know the size of you logo partition. I made this program to encompass any device using this format, and there is no set size of the logo partition between devices. Fastboot will just error out if you try to flash data bigger than the partition before it writes anything. But if someone gets brave and trys to "DD" to the logo partition, it could get ugly.:cyclops:
Flash the "modified.logo.bin" file through fastboot.
v1.2
made it possible for multiple injections in one command
doesn't add png to the decoded png if it was already in the name
fixed out of scope with image 26 in OPPO find 7 logo.bin
added LodePng source in the download
made the default color order BGR
displays the modified logo file size as well as the original file size
runs the modified.logo.bin back through the list function after injecting
checks the number of offsets between the original and modified logo.bin
Use this at your own risk.
Always make backups.
Always.
Code:
/*
/*
* Logo Injector v1.2
*
* Copyright (C) 2015 Joseph Andrew Fornecker
* makers_mark @ xda-developers.com
* [email protected]
*
* 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 3 of the License, or (at your
* opinion) any later version. See <http://www.gnu.org/licenses/gpl.html>
*
* New in v1.2:
*
* - Fixed out of scope crash involving image #26 in oppo find 7 logo.bin (26 IS BIG)
* - Multiple injection names possible after the -j parameter
* - Injection names are now case insensitive
* - BGR is the the default color order, instead of RGB
* - Added more error checks
* - Show the change in file size of original logo.bin compare to the modified logo.bin
* - Several small changes dealing with readability
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdint.h>
#include "lodepng.h"
#define SWAP32(x) (( x >> 24 )&0xff) | ((x << 8)&0xff0000) | ((x >> 8)&0xff00) | ((x << 24)&0xff000000)
#define BLOCK 512
#define OFFSETSTART 48
#define BYTESPERPIXEL 3
#define MAXOFFSETS 28
#define SIZEOFLONGINT 4
#define TWOTOTHETEN 1024
typedef struct {
uint8_t header[8];
uint8_t blank[24];
uint32_t width;
uint32_t height;
uint32_t lengthOfData;
uint32_t special;
uint32_t offsets[MAXOFFSETS];
uint8_t name[64];
uint8_t metaData[288];
} IMAGEHEAD;
uint16_t Copy(FILE *, IMAGEHEAD *, uint16_t , uint16_t, FILE *);
int32_t InjectNewStyle(FILE *, IMAGEHEAD *, uint16_t , uint8_t *, uint16_t, FILE *, uint32_t * );
int32_t RewriteHeaderZero( uint32_t , uint16_t, FILE* , int32_t, uint32_t * );
uint32_t Encode(uint8_t*, uint8_t*, uint32_t);
uint32_t GetEncodedSize(uint8_t*, uint32_t);
uint32_t GetWidth(FILE*);
uint32_t GetHeight(FILE*);
uint64_t BlockIt(uint32_t);
uint16_t GetNumberOfOffsets(FILE*);
int32_t DecodeLogoBin(FILE*, IMAGEHEAD *);
int32_t ListFileDetails(FILE*, IMAGEHEAD *);
uint8_t* Decode(FILE*, uint32_t, uint32_t, uint32_t, uint8_t*);
int32_t IsItTheNewStyle(FILE*);
IMAGEHEAD* ParseHeaders(FILE*, uint16_t);
int32_t IsItALogo(FILE*);
void PrintFileSize(uint32_t);
uint32_t GetFileSize(FILE *);
uint16_t badAss = 0;
int16_t rgb2bgr = 1;
uint16_t convertToPNG = 1;
uint8_t HEADER[] = {0x53,0x50,0x4C,0x41,0x53,0x48,0x21,0x21};
int32_t IsItALogo(FILE *originalLogoBin){
uint8_t string[9];
uint16_t i;
fread(string, 1, 8, originalLogoBin);
for (i = 0 ; i < 8 ; i++){
if (string[i] == HEADER[i]){
continue;
} else {
return 0;
}
}
return 1;
}
int32_t IsItTheNewStyle(FILE *originalLogoBin){
int32_t newStyle = 0;
fread(&newStyle, 1, SIZEOFLONGINT, originalLogoBin);
if (newStyle == 0){
return 1;
} else {
return 0;
}
}
IMAGEHEAD *ParseHeaders(FILE *originalLogoBin, uint16_t numberOfOffsets){
uint8_t i = 0;
IMAGEHEAD *imageHeaders;
imageHeaders = malloc(BLOCK * numberOfOffsets);
memset(imageHeaders, 0, BLOCK * numberOfOffsets);
fseek(originalLogoBin, 0, SEEK_SET);
fread(&imageHeaders[i], 1 , BLOCK, originalLogoBin);
for ( i = 1 ; i < numberOfOffsets ; ++i ){
fseek(originalLogoBin, imageHeaders[0].offsets[i], SEEK_SET);
fread(&imageHeaders[i], 1 , BLOCK, originalLogoBin);
}
return imageHeaders;
}
uint16_t GetNumberOfOffsets(FILE *originalLogoBin){
uint16_t i = 0;
uint32_t readAs = 0;
fseek(originalLogoBin, OFFSETSTART, SEEK_SET);
while(i < MAXOFFSETS){
fread(&readAs, 1, SIZEOFLONGINT, originalLogoBin);
if ((readAs == 0) && (i != 0)){
break;
} else {
i++;
}
}
return i;
}
uint8_t* Decode(FILE *originalLogoBin, uint32_t start, uint32_t length, uint32_t imageBytes, uint8_t* image){
uint32_t decodedBytes = 0, i = 0;
uint8_t* data;
fseek(originalLogoBin, start, SEEK_SET);
data = (uint8_t*)malloc(length);
if (fread(data, 1, length, originalLogoBin) != length) {
fprintf(stderr, "Could not read file!!\n");
exit(0);
}
while((i < length) && (decodedBytes < imageBytes)){
memset(&image[decodedBytes], data[i], (data[i + 1]));
decodedBytes += (uint8_t)data[i+1];
i += 2;
if ((i < length) && (imageBytes - decodedBytes < (uint8_t)data[i + 1])){
memset(&image[decodedBytes], data[i], imageBytes - decodedBytes);
decodedBytes = imageBytes;
fprintf(stdout, "More information was in encoding than resolution called for.\n");
break;
}
}
fprintf(stdout, "%ld decoded bytes\n", decodedBytes);
free(data);
if( rgb2bgr == 1 ){
uint8_t old;
i = 0;
while( i < imageBytes){
old = image[i];
memset(&image[i], image[i + 2], 1);
memset(&image[i + 2], old, 1);
i += BYTESPERPIXEL;
}
}
return image;
}
int32_t DecodeLogoBin(FILE *originalLogoBin, IMAGEHEAD *imageHeaders){
uint32_t size, imageBytes, start;
uint8_t* image;
uint8_t name[65];
uint8_t r = 0;
uint16_t i , numberOfOffsets = GetNumberOfOffsets(originalLogoBin);
for ( i = 0 ; i < numberOfOffsets ; i++ ){
fprintf(stdout,"\n\n\n#%d: Offset:%ld\n", i + 1, imageHeaders[0].offsets[i]);
if ((imageHeaders[i].width == 0) || (imageHeaders[i].height == 0)){
fprintf(stdout, "Placeholder for %s\n", imageHeaders[i].metaData);
continue;
}
fprintf(stdout, "Header=%s\nWidth=%ld\nHeight=%ld\nData Length=%ld\nSpecial=%ld\nName=%s\nMetadata=%s\n",
imageHeaders[i].header, imageHeaders[i].width, imageHeaders[i].height,
imageHeaders[i].lengthOfData, imageHeaders[i].special, imageHeaders[i].name, imageHeaders[i].metaData);
if (convertToPNG){
start = imageHeaders[0].offsets[i] + BLOCK;
imageBytes = imageHeaders[i].width * (imageHeaders[i].height) * BYTESPERPIXEL;
image = malloc(imageBytes);
uint8_t lengthOfName = strlen(imageHeaders[i].name);
uint8_t *ext;
ext = strrchr(imageHeaders[i].name, '.');
if (((ext[1] == 'p') || (ext[1] == 'P')) &&
((ext[2] == 'n') || (ext[2] == 'N')) &&
((ext[3] == 'g') || (ext[3] == 'G')) &&
((ext[0] == '.'))){
sprintf(name, "%s", imageHeaders[i].name);
} else {
sprintf(name, "%s.png", imageHeaders[i].name);
}
lodepng_encode24_file(name, Decode(originalLogoBin, (uint32_t)start, (uint32_t)imageHeaders[i].lengthOfData, (uint32_t)imageBytes, image) , (unsigned)imageHeaders[i].width, (unsigned)imageHeaders[i].height);
free(image);
}
}
return 0;
}
int32_t ListFileDetails(FILE *originalLogoBin, IMAGEHEAD *imageHeaders){
uint32_t i = 0, j = 0;
fseek(originalLogoBin, 0, SEEK_SET);
uint16_t numberOfOffsets = GetNumberOfOffsets(originalLogoBin);
fprintf(stdout, "Resolution\tOffset\tName\n");
fprintf(stdout, "-------------------------------------------------------------\n");
for ( i = 0 ; i < numberOfOffsets ; i++ ){
if ((imageHeaders[i].width == 0) || (imageHeaders[i].height == 0)){
fprintf(stdout, "(placeholder) for %s\n", imageHeaders[i].metaData);
continue;
}
fprintf(stdout,"%dx%d\t", imageHeaders[i].width, imageHeaders[i].height);
if ((imageHeaders[i].width < 1000) && (imageHeaders[i].height <1000)){fprintf(stdout, "\t");}
fprintf(stdout, "%ld\t%s\n", imageHeaders[0].offsets[i], imageHeaders[i].name );
}
return 1;
}
uint16_t Copy(FILE *originalLogoBin, IMAGEHEAD *imageHeaders, uint16_t numberOfOffsets, uint16_t injectionNumber, FILE *modifiedLogoBin){
uint8_t *data;
uint32_t offset, originalOffset;
uint32_t imageSize = BlockIt(BLOCK + imageHeaders[injectionNumber].lengthOfData);
if( imageHeaders[injectionNumber].name[0] == 0){
fprintf(stdout, "Copying \t#%d:(placeholder) %s\n", injectionNumber + 1 , imageHeaders[injectionNumber].metaData);
} else {
fprintf(stdout, "Copying \t#%d:%s\n", injectionNumber + 1 , imageHeaders[injectionNumber].name);
}
data = malloc(imageSize);
memset(data, 0 , imageSize);
fread(data, 1, imageSize, originalLogoBin);
fwrite(data, 1 , imageSize, modifiedLogoBin);
free(data);
}
int32_t InjectNewStyle(FILE *originalLogoBin, IMAGEHEAD *imageHeaders, uint16_t numberOfOffsets, uint8_t *injectionName, uint16_t injectionNumber, FILE *modifiedLogoBin, uint32_t *ihMainOffsets ){
uint32_t encodedSize = 0, actualWritten = 0, imageSize = 0;
uint8_t *data, *header;
int8_t inFileName[69];
int32_t blockDifference;
uint32_t offset, originalOffset;
FILE *pngFile;
sprintf(inFileName, "%s", injectionName);
if (imageHeaders[injectionNumber].special != 1){
fprintf(stdout, "ERROR: \"Special\" is not equal to '1' \nThis would not be safe to flash!\nPlease email logo.bin in question to:\[email protected]\n");
fclose(originalLogoBin);
fclose(modifiedLogoBin);
return 0;
}
if ((pngFile = fopen(inFileName, "rb")) == NULL){
sprintf(inFileName, "%s.png", injectionName);
if ((pngFile = fopen(inFileName, "rb")) == NULL){
fclose(pngFile);
fclose(modifiedLogoBin);
fclose(originalLogoBin);
fprintf(stderr, "%s could not be read\n", inFileName);
return 0;
}
}
IMAGEHEAD new;
memset(new.blank, 0, sizeof(new.blank));
memset(new.metaData, 0, sizeof(new.metaData));
memset(new.offsets, 0, SIZEOFLONGINT * MAXOFFSETS);
strncpy(new.header, HEADER , 8);
strncpy(new.metaData, imageHeaders[injectionNumber].metaData, sizeof(imageHeaders[injectionNumber].metaData));
strncpy(new.name, injectionName, 64);
new.special = 1;
fprintf(stdout, "Injecting\t#%d:%s\n", injectionNumber + 1 , imageHeaders[injectionNumber].name);
if (((new.width = GetWidth(pngFile)) != imageHeaders[injectionNumber].width) && (!badAss)){
fprintf(stderr, "Error: Width of PNG to be injected is %d, it must be %d!\n", new.width, imageHeaders[injectionNumber].width);
fclose(pngFile);
fclose(modifiedLogoBin);
fclose(originalLogoBin);
return 0;
}
if (((new.height = GetHeight(pngFile)) != imageHeaders[injectionNumber].height) && (!badAss)){
fprintf(stderr, "Error: Height of PNG to be injected is %d, it must be %d!\n", new.height, imageHeaders[injectionNumber].height);
fclose(pngFile);
fclose(modifiedLogoBin);
fclose(originalLogoBin);
return 0;
}
uint32_t rawBytes = new.width * new.height * BYTESPERPIXEL;
uint8_t *decodedPNG = malloc(rawBytes);
lodepng_decode24_file(&decodedPNG, (uint32_t*)&new.width, (uint32_t*)&new.height , (const uint8_t*)inFileName);
if (rgb2bgr == 1){
uint8_t old;
uint32_t k = 0;
while( k < rawBytes ){
old = decodedPNG[k];
memset(&decodedPNG[k], decodedPNG[k + 2], 1);
memset(&decodedPNG[k + 2], old, 1);
k += BYTESPERPIXEL;
}
}
encodedSize = GetEncodedSize(decodedPNG, (new.width * new.height * BYTESPERPIXEL));
new.lengthOfData = encodedSize;
uint8_t *rlEncoded = malloc(BlockIt(encodedSize));
memset(rlEncoded, 0, BlockIt(encodedSize));
actualWritten = Encode(decodedPNG, rlEncoded, (new.width * new.height * BYTESPERPIXEL));
blockDifference = (((BLOCK + BlockIt(actualWritten)) - (BLOCK + BlockIt(imageHeaders[injectionNumber].lengthOfData))) / BLOCK);
fwrite(&new, 1 , BLOCK, modifiedLogoBin);
fwrite(rlEncoded, 1 , BlockIt(actualWritten), modifiedLogoBin);
free(decodedPNG);
free(rlEncoded);
RewriteHeaderZero( injectionNumber , numberOfOffsets , modifiedLogoBin , blockDifference, ihMainOffsets);
fclose(pngFile);
return 1;
}
int32_t RewriteHeaderZero( uint32_t injectionImageNumber , uint16_t numberOfOffsets, FILE *modifiedLogoBin , int32_t blockDifference, uint32_t *ihMainOffsets){
uint8_t i, j = injectionImageNumber + 1 ;
uint32_t filePosition = ftell(modifiedLogoBin);
uint32_t offset = 0;
for( ; j < numberOfOffsets; j++){
fseek(modifiedLogoBin, OFFSETSTART + (SIZEOFLONGINT * j), SEEK_SET);
offset = ihMainOffsets[j];
offset += (blockDifference * BLOCK);
fseek(modifiedLogoBin, OFFSETSTART + (SIZEOFLONGINT * j), SEEK_SET);
fwrite(&offset, 1 , SIZEOFLONGINT , modifiedLogoBin);
ihMainOffsets[j] = offset;
}
fseek(modifiedLogoBin, filePosition , SEEK_SET);
return;
}
uint32_t GetEncodedSize(uint8_t* data, uint32_t size){
uint32_t pos = 0, ret = 0;
uint16_t count = 1;
for( pos = 0 ; pos < size ; ++pos , count = 1){
while((pos < size - 1) && (count < 0xFF) && ((memcmp(&data[pos], &data[pos+1], 1)) == 0)){
count++;
pos++;
}
ret += 2;
}
return ret;
}
uint32_t Encode(uint8_t* rawRgbReading, uint8_t* rlEncoded, uint32_t rawSize){
uint32_t writePosition = 0 , readPosition = 0;
uint16_t count = 1;
for( readPosition = 0 ; readPosition < rawSize ; ++readPosition , count = 1){
while((readPosition < rawSize - 1 ) && (count < 0xFF) && ((memcmp(&rawRgbReading[readPosition], &rawRgbReading[readPosition+1], 1)) == 0)){
count++;
readPosition++;
}
rlEncoded[writePosition] = rawRgbReading[readPosition];
rlEncoded[writePosition + 1] = count;
writePosition += 2;
}
return writePosition;
}
uint32_t GetWidth(FILE *pngFile){
uint32_t width;
fseek(pngFile, 16, SEEK_SET);
fread(&width, 1, SIZEOFLONGINT, pngFile);
return(SWAP32(width));
}
uint32_t GetHeight(FILE *pngFile){
uint32_t height;
fseek(pngFile, 20, SEEK_SET);
fread(&height, 1, SIZEOFLONGINT, pngFile);
return(SWAP32(height));
}
uint64_t BlockIt(uint32_t isize){
uint32_t blockSize = BLOCK;
if ((isize % blockSize) == 0){
return isize;
}else{
return isize + (blockSize - (isize % blockSize));
}
}
void Usage(){
fprintf(stdout, "Usage: logoinjector -i \"input file\" [-l] | [-L] | [-d [-s]] | [-j \"image to be replaced\" [-b] | [-s]]\n\n");
fprintf(stdout, "Mandatory Arguments:\n\n");
fprintf(stdout, "\t-i \"C:\\xda\\logo.bin\"\n");
fprintf(stdout, "\t This is the logo.bin file to analyze or inject an image\n\n");
fprintf(stdout, "Optional Arguments:\n\n");
fprintf(stdout, "\t-d Decode all images into PNGs, (-s)wap parameter may be needed for proper color.\n");
fprintf(stdout, "\t-l Lower case 'L' is to display a short list of what is inside the input file.\n");
fprintf(stdout, "\t-L Upper case 'L' is for a more detailed list of logo.bin image contents.\n");
fprintf(stdout, "\t-b 'b' is used to tell the program to disregard width or height differences\n");
fprintf(stdout, "\t when encoding an image, the program also won't fail if it can't find a name\n");
fprintf(stdout, "\t that can't be found on the inject list when encoding images\n");
fprintf(stdout, "\t-s 's' is used to swap RGB and BGR color order. Can be used on decoding or encoding.\n");
fprintf(stdout, "\t NEW IN THIS V1.2: Swap is on by default, meaning the color order will be BGR. Using\n");
fprintf(stdout, "\t the \"-s\" switch will result in a RGB color order. Bottom line: If you (-d)ecode the\n");
fprintf(stdout, "\t images (that have color) and the colors aren't right, then you should use (-s) to \n");
fprintf(stdout, "\t decode and inject images.\n");
fprintf(stdout, "\t-j \"image(s) to be replaced\"\n");
fprintf(stdout, "\t The image(s) name to be replaced as seen in the (-l)ist\n");
fprintf(stdout, "\t NEW IN THIS V1.2: Multiple image names may be put after \"-j\"\n");
fprintf(stdout, "\t The names simply need to be separated by a space. The names now also are not case\n");
fprintf(stdout, "\t sensitive, and it doesn't matter if you put the extension at the end of the name.\n");
fprintf(stdout, "\t You actually only need to put the first characters of the name.\nExample:\n");
fprintf(stdout, "\t logoinjector -i \"your_logo.bin\" -j FHD \n\n");
fprintf(stdout, "\t This will inject a PNG for every name in the logo bin that begins with \"fhd\"\n");
return;
}
void PrintFileSize(uint32_t bytes){
float megaBytes = 0, kiloBytes = 0;
kiloBytes = (float)bytes / (float)TWOTOTHETEN;
megaBytes = kiloBytes / (float)TWOTOTHETEN;
if (kiloBytes < (float)TWOTOTHETEN){
fprintf(stdout, "\t%.2f KB\n", kiloBytes);
} else {
fprintf(stdout, "\t%.2f MB\n", megaBytes);
}
return;
}
uint32_t GetFileSize(FILE *temp){
fseek(temp, 0 , SEEK_END);
uint32_t fileSizeZ = ftell(temp);
return(fileSizeZ);
}
int32_t main(int32_t argc, int8_t **argv){
int32_t c;
int16_t h, i , j , k = 0;
FILE *originalLogoBin = NULL, *modifiedLogoBin = NULL;
uint8_t *inputFile = NULL;
uint8_t *injectNames[MAXOFFSETS];
int16_t decodeAllOpt = 0;
int16_t encodeOpt = 0;
int16_t inject = 0;
int16_t listFile = 0;
uint16_t numberOfOffsets = 0, injected = 0;
for(i = 0; i < MAXOFFSETS; i++){
injectNames[i] = NULL;
}
fprintf(stdout, "__________________________________________________________-_-\n");
fprintf(stdout, "Logo Injector v1.2\n\nWritten By Makers_Mark @ XDA-DEVELOPERS.COM\n");
fprintf(stdout, "_____________________________________________________________\n\n");
while ((c = getopt (argc, (char**)argv, "sSj:J:hHbBdDlLi:I:")) != -1){
switch(c)
{
case 'l':
listFile = 1;
break;
case 'L':
decodeAllOpt = 1;
convertToPNG = 0;
break;
case 'i':
case 'I':
inputFile = optarg;
break;
case 'b':
case 'B':
badAss = 1;
break;
case 'j':
case 'J':
h = optind - 1 ;
uint8_t *nextArg;
while(h < argc){
inject = 1;
nextArg = strdup(argv[h]);
h++;
if(nextArg[0] != '-'){
injectNames[k++] = nextArg;
} else {
break;
}
}
optind = h - 1;
break;
case 'd':
case 'D':
decodeAllOpt = 1 ;
break;
case 's':
case 'S':
rgb2bgr = -1 ;
break;
case 'h':
case 'H':
Usage();
return 0;
break;
default:
Usage();
return 0;
break;
}
}
if (inputFile == NULL){
Usage();
return 0;
}
fprintf(stdout, "FILE: %s\n_____________________________________________________________\n\n", inputFile);
if (rgb2bgr == 1){
fprintf(stdout, "BGR is the color order. Use \"-s\" switch to change it to RGB.\n\n");
} else {
fprintf(stdout, "RGB is the color order. Use \"-s\" switch to change it to BGR.\n\n");
}
if ((originalLogoBin = fopen(inputFile, "rb")) == NULL){
fprintf(stderr, "%s could not be opened\n", inputFile);
return 0;
}
if (!IsItALogo(originalLogoBin)){
fprintf(stdout, "\nThis is NOT a valid Logo.bin\n\n");
fclose(originalLogoBin);
return 0;
}
if (!IsItTheNewStyle(originalLogoBin)){
fprintf(stdout, "\nThis is the old style logo.bin\n\n");
fclose(originalLogoBin);
return 0;
}
numberOfOffsets = GetNumberOfOffsets(originalLogoBin);
IMAGEHEAD *imageHeaders = ParseHeaders(originalLogoBin, numberOfOffsets);
if (listFile){
ListFileDetails(originalLogoBin, imageHeaders);
return 1;
}
if(inject){
uint32_t ihMainOffsets[MAXOFFSETS];
uint8_t found = 0, exitFlag = 0;
for (i = 0; i < MAXOFFSETS ; i++){
ihMainOffsets[i] = 0;
}
for (j = 0; j < k ; j++){
for (i = 0 ; i < numberOfOffsets ; i++ ){
if((strcasecmp(imageHeaders[i].name, injectNames[j]) == 0) ||
(strncasecmp(imageHeaders[i].name, injectNames[j], strlen(injectNames[j])) == 0)){
found = 1;
break;
} else {
found = 0;
}
}
if (!found){
fprintf(stdout, "ERROR: \"%s\" is not in the logo bin !!!!\n", injectNames[j]);
exitFlag = 1;
}
}
if ((exitFlag) && (!badAss)){
fclose(originalLogoBin);
exit(0);
}
memcpy(&ihMainOffsets , &imageHeaders[0].offsets, SIZEOFLONGINT * MAXOFFSETS);
fseek(originalLogoBin, 0, SEEK_SET);
if ((modifiedLogoBin = fopen("modified.logo.bin", "wb+")) == NULL){
fclose(modifiedLogoBin);
fclose(originalLogoBin);
fprintf(stderr, "modified.logo.bin could not be opened\n");
return 0;
}
for (i = 0 ; i < numberOfOffsets ; i++ , injected = 0 ){
for (j = 0; j < k ; j++){
if((strcasecmp(imageHeaders[i].name, injectNames[j]) == 0) ||
(strncasecmp(imageHeaders[i].name, injectNames[j], strlen(injectNames[j])) == 0)){
if (InjectNewStyle(originalLogoBin, imageHeaders , numberOfOffsets, imageHeaders[i].name, i, modifiedLogoBin, ihMainOffsets) == 0){
fprintf(stderr, "Error: Injecting %s\n", imageHeaders[i].name);
fclose(originalLogoBin);
fclose(modifiedLogoBin);
return 0;
}
if ( i != numberOfOffsets - 1 ){
fseek(originalLogoBin, imageHeaders[0].offsets[i+1], SEEK_SET);
}
injected = 1;
break;
}
}
if (!injected){
Copy(originalLogoBin , imageHeaders, numberOfOffsets, i, modifiedLogoBin);
}
}
uint16_t modifiedNumberOfOffsets = 0;
if (GetNumberOfOffsets(modifiedLogoBin) != numberOfOffsets){
fprintf(stderr, "ERROR: The number of offsets doesn't match the Original file!!\n");
fclose(modifiedLogoBin);
if (!badAss){
unlink("modified.logo.bin");
}
exit(0);
}
fprintf(stdout, "\n\nContents of the NEW \"modified.logo.bin\":\n");
fprintf(stdout, "VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV\n\n");
ListFileDetails(modifiedLogoBin, imageHeaders);
fprintf(stdout, "\n\n_____________________________________________________________\nOriginal filesize: ");
PrintFileSize(GetFileSize(originalLogoBin));
fprintf(stdout, "Modified filesize: ");
PrintFileSize(GetFileSize(modifiedLogoBin));
fprintf(stdout, "-------------------------------------------------------------\n");
fclose(originalLogoBin);
fclose(modifiedLogoBin);
return 1;
}
if (decodeAllOpt){
DecodeLogoBin(originalLogoBin, imageHeaders);
fclose(originalLogoBin);
return 1;
}
fclose(originalLogoBin);
return 1;
}
Terrific, this works. Thank you a lot!
After a little trial-and-error and some time in our beloved QHSUSB_DLOAD mode, I finally got it to work! I own a OnePlus One, and I had to use the -s parameter to get it to work correctly. Just a heads-up for any OPO owners who wants to use this. Great work, OP!
treChoy said:
After a little trial-and-error and some time in our beloved QHSUSB_DLOAD mode, I finally got it to work! I own a OnePlus One, and I had to use the -s parameter to get it to work correctly. Just a heads-up for any OPO owners who wants to use this. Great work, OP!
Click to expand...
Click to collapse
Thanks for chiming in, I was going to ask you to test for me initially. Can you elaborate on what happened?
makers_mark said:
Thanks for chiming in, I was going to ask you to test for me initially. Can you elaborate on what happened?
Click to expand...
Click to collapse
Just a foreword that I was using a Windows 8.1 machine, which is bound to be the cause of some of the issues I ran into.
After I unzipped the program and put the logo.bin in the extracted folder, I kept running the commands, but each time, I'd get an error message saying that the program didn't support my OS version, or something to that effect. I tried rewording the commands, but to no avail. Eventually, I just deleted the whole folder and extracted the package again. That seemed to do the trick.
So I had all the images extracted, and I created the ones I wanted to replace. There was a bit of confusion repackaging the image, since the OPO's logo.bin places the ".png" into the name of the images, but eventually, I got it all right. I flashed the modified logo.bin, but when I tried to reboot, my computer started installing drivers for QHSUSB. This had happened before when I was playing around with the LOGO partition, and it was an easy fix. I just jammed the power button for 30 seconds, and prayed to God. Thankfully, the phone booted up, but the splash screen I had created had its colors messed up. I assumed that I needed to swap the red and the blue, so I used the parameter you provided and packaged a new splash screen. I flashed it, and everything looked fine.
It's definitely a little more intimidating than the tool that @chillstep1998 created, but with a little trial-and-error, it's certainly doable. Great work!
Oh, yeah. I needed to use the -s parameter too and I skipped putting the logo.bin in through fastboot - I just modded an install zip and flashed it in with TWRP.
Thanks for this program. Glad that it's back from someone for CM12 as we waited for quite some time now. I have a query though about repacking.
logoinjector.exe -i logo.bin -j (image name you want to replace)
Is it possible to put different file names at the same time if I want to replace two or three files at the same time like this
logoinjector.exe -i logo.bin -j 4-fastboot.png 5-lowpower.png
because it doesn't work for me, I will have to run this command for the number of times I have files to replaced?
Does this method work with custom roms based on nightly cm 12.1?I'm currently on exodus rom.
Spyrious said:
Does this method work with custom roms based on nightly cm 12.1?I'm currently on exodus rom.
Click to expand...
Click to collapse
I suppose it should because logo.bin would be same for all those roms.
Sent from my "GT-I9300/1+1" powered by Carbon Rom & Boeffla/ak Kernel
Fueled by 7000mAh ZeroLemon Battery
Awesome! I had to also use the -s parameter but it worked great. Thanks OP.
Is this an appropriate place to start sharing logos or do we need a separate thread for that?
makers_mark said:
Code:
/*
* Logo Injector v1.0
[/QUOTE]
WOW - Thanks !
I've waited a LONG time for this !
Few things to let you know
1. On my Win 8.1 x64 I run Comodo CIS - which prevents LogoInjector.exe from creating the PNG images after I run "logoInjector.exe -i logo.bin -d".
This is of course the behavior of a false-positive, the overprotection of comodo A/V.
So once I temporary disable it -LogoInjector can successfully create the PNGs.
2. I also, as already reported, needed to use the -s switch inorder to get the right colors
3. I would also very much appreciate if it will be possible to inject multiple images at once with one command.
4. I can advise to update the OP with the size limits of the logo.bin ( if there is at all )
I injected a 276KB png into 335KB logo.bin and got a modified logo.bin size 12,171KB ( 12MB ! ) - never the less - After I flashed it - everything is OK.
5. I can advise to put in the OP a link to a tool/method ( if exist at all ) that can enable extraction of the current installed logo.bin from the phone it self.
button line - VERY GOOD WORK ! :good: :good: :good::highfive:
[B][U]EDIT:[/U][/B]
I attach a[B] FLASHABLE ZIP FILE that INSTALLS the logo.bin[/B] found inside the zip.
just replace the logo.bin in the root of the zip with your custom made "logo.bin".
This method is an alternative to the fastboot command "fastboot flash LOGO logo.bin"
Click to expand...
Click to collapse
330kb modified bootlogo
I got a 330KB modified logo.bin file
Isn't it supposed to be around 16MB?
I'm currently on cm12.1 06/08/2015 (DD/MM/YYYY)
ranger1021994 said:
I got a 330KB modified logo.bin file
Isn't it supposed to be around 16MB?
I'm currently on cm12.1 06/08/2015 (DD/MM/YYYY)
Click to expand...
Click to collapse
Size depends on the size of embedded images.
Sent from my "GT-I9300/1+1" powered by Carbon Rom & Boeffla/ak Kernel
Fueled by 7000mAh ZeroLemon Battery
LOGO.bin file size
nicesoni_ash said:
Size depends on the size of embedded images.
Sent from my "GT-I9300/1+1" powered by Carbon Rom & Boeffla/ak Kernel
Fueled by 7000mAh ZeroLemon Battery
Click to expand...
Click to collapse
My original LOGO file is 16MB big.
How can my modified file be only 330KB?
I don't know what is causing the file size to come down drastically from 16MB to just 330KB. Is it normal? Because I'm not sure it is
ranger1021994 said:
My original LOGO file is 16MB big.
How can my modified file be only 330KB?
I don't know what is causing the file size to come down drastically from 16MB to just 330KB. Is it normal? Because I'm not sure it is
Click to expand...
Click to collapse
Check all image files size individually and if the difference is not that huge then surely something is wrong.
Sent from my "GT-I9300/1+1" powered by Carbon Rom & Boeffla/ak Kernel
Fueled by 7000mAh ZeroLemon Battery
nicesoni_ash said:
Check all image files size individually and if the difference is not that huge then surely something is wrong.
Click to expand...
Click to collapse
ranger1021994 said:
My original LOGO file is 16MB big.
How can my modified file be only 330KB?
I don't know what is causing the file size to come down drastically from 16MB to just 330KB. Is it normal? Because I'm not sure it is
Click to expand...
Click to collapse
gps3dx said:
I injected a 276KB png into 335KB logo.bin and got a modified logo.bin size 12,171KB ( 12MB ! ) - never the less - After I flashed it - everything is OK.
Click to expand...
Click to collapse
@read my quote.
if you enter an image with only ONE COLOR background ( Same RBG values, not gradient ! ) it can drastically lower the final file size.
You can of course use black as background color and crop the images size to your content, so that the cropped areas will be filled automatically by the OPO as black color.
The idea here is that if you'll have full sized photo (1080x1920) with small area content (like 300x400), it contains black areas ( for no reason ) which enlarges the final file size - which make no sense.
nevertheless, Read my quote, as you can see I flash a ~12MB file while the original file was 335KB - and everything works!
I have a stupid question, how can I know whether I have a CM12 or CM11 logo in my oneplus? I have flashed CM11 as a primary rom and flashed CM12 as a secondary rom. I do remember that I flashed a CM12 zip to be able to flash CM12 as a secondary rom but that's a faint memory and I want to be sure before flashing a logo because last time I did that, I lost everything in my Oneplus and had to start from the beginning first by reviving it from its dead state.
Thanks.
nicesoni_ash said:
I have a stupid question, how can I know whether I have a CM12 or CM11 logo in my oneplus? I have flashed CM11 as a primary rom and flashed CM12 as a secondary rom. I do remember that I flashed a CM12 zip to be able to flash CM12 as a secondary rom but that's a faint memory and I want to be sure before flashing a logo because last time I did that, I lost everything in my Oneplus and had to start from the beginning first by reviving it from its dead state.
Thanks.
Click to expand...
Click to collapse
EDIT: Deleted for misinformation
It works!!
gps3dx said:
@read my quote.
if you enter an image with only ONE COLOR background ( Same RBG values, not gradient ! ) it can drastically lower the final file size.
You can of course use black as background color and crop the images size to your content, so that the cropped areas will be filled automatically by the OPO as black color.
The idea here is that if you'll have full sized photo (1080x1920) with small area content (like 300x400), it contains black areas ( for no reason ) which enlarges the final file size - which make no sense.
nevertheless, Read my quote, as you can see I flash a ~12MB file while the original file was 335KB - and everything works!
Click to expand...
Click to collapse
AMAZING!
It works!!
Finally
Thanks a lot!
Hey, I'm fairly new to using android studios and I am trying to make an app that updates its display every few seconds.
The method I am currently using is to update when a button is pressed using the following:
public void Refreshing(View view) {
// do stuff here...
}
Where Refreshing is the onClick of a button I placed.
How can I use a similar format but instead of doing things on a button press just have it done automatically after a few seconds?
You can use a android.os.Handler for that. It allows you to interact with the event loop and post a Runnable that will be executed after a given delay
In your Activity's onCreate() method:
Code:
final int delayMs = 1000;
final Handler handler = new Handler(this);
final Runnable runnable = new Runnable() {
@Override public void run() {
// Call your refresh method
Refreshing();
// Restart the timer
handler.postDelayed(runnable, delayMs);
};
}
handler.postDelayed(runnable, delayMs);
Thanks, this is exactly what I'm looking for. I add the code to the onCreate but I had an semicolon error. So I added another semicolon but its having trouble with a few other parts. Here is what I have.
Code:
final int delayMs = 1000;
final Handler handler = new Handler([B]this[/B]);
final Runnable runnable = new Runnable() {
@Override public void run() {
// Call your refresh method
Refreshing();
// Restart the timer
handler.postDelayed([B]runnable[/B], delayMs);
};
};
handler.postDelayed(runnable, delayMs);
The error listed is:
Error : (134, 33) error: no suitable constructor found for Handler(MainActivity)
constructor Handler.Handler(Looper,Callback) is not applicable
(actual and formal argument lists differ in length)
constructor Handler.Handler(Looper) is not applicable
(actual argument MainActivity cannot be converted to Looper by method invocation conversion)
constructor Handler.Handler(Callback) is not applicable
(actual argument MainActivity cannot be converted to Callback by method invocation conversion)
constructor Handler.Handler() is not applicable
(actual and formal argument lists differ in length)
The words I bolded are underlined in red in Android Studios.
this ----------------has a constructor error
runnable ----------has a initialization error
I tried troubleshooting for a little bit and took out the this and the only error left is with runnable. It says: Error: (141, 37) error: variable runnable might not have been initialized
Yep, I wrote the code without testing it. It might need some adaptation.
Here is a version that should work:
Code:
final int delayMs = 1000;
final Handler handler = new Handler([B]this[/B]);
final Runnable runnable = new Runnable() {
@Override public void run() {
// Call your refresh method
Refreshing();
// Restart the timer
handler.postDelayed([B]this[/B], delayMs);
};
};
handler.postDelayed([B]runnable[/B], delayMs);
Thank you so much, it worked. I just had to change
Code:
final Handler handler = new Handler(this);
to
Code:
final Handler handler = new Handler();
I´m working on compiling an kernel from SonyXperiaDev source, have already build kernel zImage with:
HTML:
make ARCH=<arch> CROSS_COMPILE=$CROSS_COMPILE <device_defconfig>
make ARCH=<arch> CROSS_COMPILE=$CROSS_COMPILE -j <cpu_thread_number>
make ARCH=arm CROSS_COMPILE=$CROSS_COMPILE -j12 -C M=$PWD CONFIG_PRIMA_WLAN=m CONFIG_PRIMA_WLAN_LFR=y KERNEL_BUILD=1 WLAN_ROOT=$PWD
I extract the ramdisk.cpio.gz from my device now i´m able to assemble the new boot image. But i'm not sure about the mkbootimg file that is neccessary for assemble the boot.img here a request of the compiling guide:
Assemble the boot image file The kernel image and the RAM image need to be assembled in a boot image file. The boot image file will then be flashed to your phone or tablet. Depending on your device, you need to use the tool mkqcdtbootimg, provided by SonyXperiaDev on GitHub, or mkbootimg, provided by the Android Open Source Project, to create the boot image. Please note that the program must be compiled differently depending on which system you are running.
Click to expand...
Click to collapse
In my case i need the mkbootimg from AOSP but how can i find the right one?
here the command for the next step:
HTML:
./mkbootimg --base 0x80200000 --kernel zImage --ramdisk_offset 0x02000000 --cmdline "androidboot.hardware=qcom user_debug=31 msm_rtb.filter=0x3F ehci-hcd.park=3 vmalloc=400M androidboot.emmc=true" --ramdisk ramdisk.cpio.gz -o boot.img
Details to my Device:
[ro.product.cpu.abilist32]: [armeabi-v7a,armeabi]
[Xperia Z]
[ro.com.google.gmsversion]: [5.1_r2]
[Sony/C6603/C6603:5.1.1/10.7.A.0.222]
Click to expand...
Click to collapse
I was looking here for the source mkbootimg:
https://android.googlesource.com/platform/system/core/+/android-5.1.1_r2
https://android.googlesource.com/platform/system/core/+refs
it contains the mkbootimmg.c but the kernel and ramdisk offset are diffrent to the sony instrucktion.
HTML:
boot_img_hdr hdr;
char *kernel_fn = 0;
void *kernel_data = 0;
char *ramdisk_fn = 0;
void *ramdisk_data = 0;
char *second_fn = 0;
void *second_data = 0;
char *cmdline = "";
char *bootimg = 0;
char *board = "";
unsigned pagesize = 2048;
int fd;
SHA_CTX ctx;
const uint8_t* sha;
unsigned base = 0x10000000;
unsigned kernel_offset = 0x00008000;
unsigned ramdisk_offset = 0x01000000;
unsigned second_offset = 0x00f00000;
unsigned tags_offset = 0x00000100;
size_t cmdlen;
How can i identify the right mkbootimg file for assembly zImage and ramdisk.gz?
Thank you
You can just use AnyKernel2, it has mkbootimg included, so it automatically makes boot image with ramdisk of currently installed kernel when flashed.
UPDATE: ISSUE HAS BEEN FIXED, THANK YOU
Hi all,
I am trying to compile Magisk after cloning it from the Github repository (https://github.com/topjohnwu/Magisk).
I cloned it via
Code:
git clone [B]-recursive[/B] https://github.com/topjohnwu/Magisk.git
in order to download the proper submodules as well.
After running
Code:
python3 build.py all 14.3 143
(btw, I am simply guessing the versioncode argument. Does it matter?)
the error I get is the following:
pastebin: https://pastebin.com/eVwGhvXa
Code:
* Building Magisk binaries
[x86] Compile : b64xz <= b64xz.c
[x86] Compile : magisk <= magisk.c
[x86] Compile : magisk <= daemon.c
[x86] Compile : magisk <= socket_trans.c
[x86] Compile : magisk <= log_monitor.c
[x86] Compile : magisk <= bootstages.c
[x86] Compile : magisk <= misc.c
[x86] Compile : magisk <= vector.c
[x86] Compile : magisk <= xwrap.c
[x86] Compile : magisk <= list.c
[x86] Compile : magisk <= img.c
[x86] Compile : magisk <= file.c
[x86] Compile : magisk <= magiskhide.c
[x86] Compile : magisk <= proc_monitor.c
[x86] Compile : magisk <= hide_utils.c
[x86] Compile : magisk <= magiskpolicy.c
[x86] Compile : magisk <= rules.c
[x86] Compile : magisk <= sepolicy.c
[x86] Compile : magisk <= api.c
[x86] Compile++ : magisk <= resetprop.cpp
[x86] Compile++ : magisk <= system_properties.cpp
In file included from jni/resetprop/resetprop.cpp:63:
In file included from jni/resetprop/_system_properties.h:40:
jni/resetprop/system_properties.h:46:64: error: expected function body after function declarator
int __system_property_set2(const char* key, const char* value) __INTRODUCED_IN(12);
^
jni/resetprop/system_properties.h:61:19: error: expected function body after function declarator
void* cookie) __INTRODUCED_IN(26);
^
jni/resetprop/system_properties.h:70:3: error: expected function body after function declarator
__INTRODUCED_IN(19);
^
jni/resetprop/system_properties.h:89:5: error: expected function body after function declarator
__INTRODUCED_IN(26);
^
jni/resetprop/resetprop.cpp:177:3: error: use of undeclared identifier '__system_property_read_callback2'; did you mean
'__system_property_read2'?
__system_property_read_callback2(pi, read_prop_info, value);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
__system_property_read2
jni/resetprop/system_properties.h:94:5: note: '__system_property_read2' declared here
int __system_property_read2(const prop_info* pi, char* name, char* value);
^
jni/resetprop/resetprop.cpp:177:40: error: cannot initialize a parameter of type 'char *' with an lvalue of type 'void (void *, const
char *, const char *, uint32_t)' (aka 'void (void *, const char *, const char *, unsigned int)')
__system_property_read_callback2(pi, read_prop_info, value);
^~~~~~~~~~~~~~
jni/resetprop/system_properties.h:94:56: note: passing argument to parameter 'name' here
int __system_property_read2(const prop_info* pi, char* name, char* value);
^
jni/resetprop/resetprop.cpp:192:2: error: use of undeclared identifier '__system_property_read_callback2'; did you mean
'__system_property_read2'?
__system_property_read_callback2(pi, cb_wrapper, cookie);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
__system_property_read2
jni/resetprop/system_properties.h:94:5: note: '__system_property_read2' declared here
int __system_property_read2(const prop_info* pi, char* name, char* value);
^
jni/resetprop/resetprop.cpp:192:39: error: cannot initialize a parameter of type 'char *' with an lvalue of type 'void (void *, const
char *, const char *, uint32_t)' (aka 'void (void *, const char *, const char *, unsigned int)')
__system_property_read_callback2(pi, cb_wrapper, cookie);
^~~~~~~~~~
jni/resetprop/system_properties.h:94:56: note: passing argument to parameter 'name' here
int __system_property_read2(const prop_info* pi, char* name, char* value);
^
In file included from jni/resetprop/system_properties.cpp:54:
In file included from jni/resetprop/_system_properties.h:40:
jni/resetprop/system_properties.h:46:64: error: expected function body after function declarator
int __system_property_set2(const char* key, const char* value) __INTRODUCED_IN(12);
^
jni/resetprop/system_properties.h:61:19: error: expected function body after function declarator
void* cookie) __INTRODUCED_IN(26);
^
jni/resetprop/system_properties.h:70:3: error: expected function body after function declarator
__INTRODUCED_IN(19);
^
jni/resetprop/system_properties.h:89:5: error: expected function body after function declarator
__INTRODUCED_IN(26);
^
jni/resetprop/resetprop.cpp:254:2: error: use of undeclared identifier '__system_property_foreach2'; did you mean
'__system_property_get2'?
__system_property_foreach2(prop_foreach_cb, &wrap);
^~~~~~~~~~~~~~~~~~~~~~~~~~
__system_property_get2
jni/resetprop/system_properties.h:96:5: note: '__system_property_get2' declared here
int __system_property_get2(const char* name, char* value);
^
jni/resetprop/resetprop.cpp:254:29: error: cannot initialize a parameter of type 'const char *' with an lvalue of type
'void (const prop_info *, void *)'
__system_property_foreach2(prop_foreach_cb, &wrap);
^~~~~~~~~~~~~~~
jni/resetprop/system_properties.h:96:40: note: passing argument to parameter 'name' here
int __system_property_get2(const char* name, char* value);
^
jni/resetprop/resetprop.cpp:271:10: error: use of undeclared identifier '__system_property_set2'; did you mean
'__system_property_get2'?
ret = __system_property_set2(name, value);
^~~~~~~~~~~~~~~~~~~~~~
__system_property_get2
jni/resetprop/system_properties.h:96:5: note: '__system_property_get2' declared herejni/resetprop/system_properties.cpp:97:3: error: unknown type name 'va_list'; did you mean '__va_list'?
va_list vl;
^~~~~~~
__va_list
/home/solar/Android/Sdk/ndk-bundle/platforms/android-21/arch-x86/usr/include/sys/types.h:129:27: note: '__va_list' declared here
int __system_property_get2(const char* name, char* value);
^
typedef __builtin_va_list __va_list;
^
jni/resetprop/resetprop.cpp:271:39: error: cannot initialize a parameter of type 'char *' with an lvalue of type 'const char *'
ret = __system_property_set2(name, value);
^~~~~
jni/resetprop/system_properties.h:96:52: note: passing argument to parameter 'value' here
int __system_property_get2(const char* name, char* value);
^
jni/resetprop/system_properties.cpp:98:3: error: use of undeclared identifier 'va_start'
va_start(vl, format);
^
jni/resetprop/system_properties.cpp:99:13: error: use of undeclared identifier 'vsnprintf'
int ret = vsnprintf(s, n, format, vl);
^
jni/resetprop/system_properties.cpp:100:3: error: use of undeclared identifier 'va_end'
va_end(vl);
^
jni/resetprop/resetprop.cpp:278:10: error: use of undeclared identifier '__system_property_set2'; did you mean
'__system_property_get2'?
ret = __system_property_set2(name, value);
^~~~~~~~~~~~~~~~~~~~~~
__system_property_get2
jni/resetprop/system_properties.h:96:5: note: '__system_property_get2' declared here
int __system_property_get2(const char* name, char* value);
^
jni/resetprop/resetprop.cpp:278:39: error: cannot initialize a parameter of type 'char *' with an lvalue of type 'const char *'
ret = __system_property_set2(name, value);
^~~~~
jni/resetprop/system_properties.h:96:52: note: passing argument to parameter 'value' here
int __system_property_get2(const char* name, char* value);
^
14 errors generated.
make: *** [obj/local/x86/objs/magisk/resetprop/resetprop.o] Error 1
make: *** Waiting for unfinished jobs....
jni/resetprop/system_properties.cpp:1012:3: error: unknown type name 'va_list'; did you mean '__va_list'?
va_list ap;
^~~~~~~
__va_list
/home/solar/Android/Sdk/ndk-bundle/platforms/android-21/arch-x86/usr/include/sys/types.h:129:27: note: '__va_list' declared here
typedef __builtin_va_list __va_list;
^
jni/resetprop/system_properties.cpp:1030:3: error: use of undeclared identifier 'va_start'
va_start(ap, num_args);
^
jni/resetprop/system_properties.cpp:1034:33: error: expected '(' for function-style cast or type construction
spec_entry = va_arg(ap, char**);
~~~~^
jni/resetprop/system_properties.cpp:1034:35: error: expected expression
spec_entry = va_arg(ap, char**);
^
jni/resetprop/system_properties.cpp:1037:7: error: use of undeclared identifier 'va_end'
va_end(ap);
^
jni/resetprop/system_properties.cpp:1043:7: error: use of undeclared identifier 'va_end'
va_end(ap);
^
jni/resetprop/system_properties.cpp:1048:3: error: use of undeclared identifier 'va_end'
va_end(ap);
^
jni/resetprop/system_properties.cpp:1053:3: error: unknown type name 'FILE'
FILE* file = fopen(filename, "re");
^
jni/resetprop/system_properties.cpp:1053:16: error: use of undeclared identifier 'fopen'; did you mean 'open'?
FILE* file = fopen(filename, "re");
^~~~~
open
/home/solar/Android/Sdk/ndk-bundle/platforms/android-21/arch-x86/usr/include/fcntl.h:73:12: note: 'open' declared here
extern int open(const char*, int, ...);
^
jni/resetprop/system_properties.cpp:1053:32: error: cannot initialize a parameter of type 'int' with an lvalue of type
'const char [3]'
FILE* file = fopen(filename, "re");
^~~~
/home/solar/Android/Sdk/ndk-bundle/platforms/android-21/arch-x86/usr/include/fcntl.h:73:33: note: passing argument to parameter here
extern int open(const char*, int, ...);
^
jni/resetprop/system_properties.cpp:1497:3: error: use of undeclared identifier '__system_property_wait2'; did you mean
'__system_property_add2'?
__system_property_wait2(nullptr, old_serial, &new_serial, nullptr);
^~~~~~~~~~~~~~~~~~~~~~~
__system_property_add2
jni/resetprop/system_properties.cpp:1449:5: note: '__system_property_add2' declared here
int __system_property_add2(const char* name, unsigned int namelen, const char* value,
^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
20 errors generated.
make: *** [obj/local/x86/objs/magisk/resetprop/system_properties.o] Error 1
Build Magisk binary failed!
I'm building on Ubuntu 16.04 Xenial 64 bits.
It seems like the cmake or C libraries I have are older or not compatible with the one required by Magisk.
I'm out of ideas and I can't find any tutorials on compiling Magisk or any info on the errors above via Google.
Could you please help me out with some tips on what am I missing? I'd really appreciate it.
Thank you.
@easytotype Have you made sure that you're using the latest Android NDK?
Also, have you tried "sudo apt-get update && sudo apt-get upgrade"?
And, versionString and versionCode should be 14.4 and 1440, instead of 14.3 and 143 (it isn't related to this error, though)
Sent from my Samsung Galaxy Trend Plus using XDA Labs
DodoGTA said:
@easytotype Have you made sure that you're using the latest Android NDK? (...)
Click to expand...
Click to collapse
ndk was the problem indeed!
I had NDK v14,
installing the latest v15 solved the issue.
The facepalm was huge, but without your help I would have been for stuck much much longer.
Thank you very much @DodoGTA :good::good::good::good::good: