@makers_mark : Hi, we found something called Qmage. Apparently all images in Samsung 4.4.4+ firmware are in this proprietary qmg format, so no more PNGs.
They mention RGB565 and we're wondering if this is the same stuff as you've been working with?
If so, perhaps your tool can be extended to deal with these?
Just for thread completion, alireza7991 also has some png2rle in his GitHub.
The second file down is sp1.nb0, which is a non rle image in rgb565 pixel format. It resides in mmcblk0p9 on the device, and the image only takes up ~2/5 ths of the partition.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#define BIT_SET 0x80
#define IS_BIT_SET(x) (x & BIT_SET)
unsigned int _CRT_fmode = _O_BINARY;
void motoDecode(char *inputFile, char *outputfile)
{
FILE *outStream;
FILE *inStream;
unsigned short repeats;
unsigned char data[5];
unsigned char color[3];
unsigned short counttotal = 0;
if ((inStream = fopen(inputFile, "rb")) == NULL){
fclose(inStream);
fprintf(stderr, "\n%s\nCould not be opened.", inputFile);
return;
}
if ((outStream = fopen(outputfile, "wb")) == NULL){
fclose(outStream);
fclose(inStream);
fprintf(stderr, "\n%s\nCould not be opened.", outputfile);
return;
}
int inNumber = fileno(inStream);
int outNumber = fileno(outStream);
while(read(inNumber, data, 5) == 5){
counttotal = 0;
color[0] = data[2];
color[1] = data[3];
color[2] = data[4];
if (IS_BIT_SET(data[0])){
data[0] &= ~0x80;
counttotal = (((data[0] * 256)) + data[1]);
for (repeats = 0;repeats < counttotal; repeats++){
write(outNumber, &color, 3);
}
continue;
} else {
counttotal = (data[1]);
write(outNumber, &color, 3);
for (repeats = 0; repeats < counttotal -1; repeats++){
read(inNumber, color, 3);
write(outNumber, &color, 3);
}
continue;
}
}
}
int main(int argc, char **argv)
{
char *inputFile;
char *outputfile;
int c;
while ((c = getopt (argc, argv, "i:o:")) != -1)
switch(c)
{
case 'i':
inputFile = optarg;
break;
case 'o':
outputfile = optarg;
break;
}
motoDecode(inputFile, outputfile);
return(1);
}
I will make a lock image that has a long white line ,corresponding to their oblivious pixel, and replace it in all three spots. It will contain no more and no less data (no padding in testing scenarios). If you want to "dd" it to the partition or use otherwise "cough" mentions, then feel free. Very nice find there. I used a popular internet archive to get the source (thread) that I was referring to. The cough seems about the same caliber as far as knowledge and insight.Since the Nexus 2013 is now EOL for OTA updates, here are the highlights I just found for our final bootloader:
bootloader-flo-flo-04.08.img
4 byte pp
bgr0
logo:
search string 9C030000 00000000 01000000 09090900
size 518x179
length 43768
offset 1187772 (311688 in aboot)
offset 3270044 (2393960 in aboot)
offset 3955364 (3079280 in aboot)
offset - (3167460 in aboot only)
lock:
search string 1C000000 00000000 01000000 24242400
size 72x94
length 4616
offset 1127848 (251764 in aboot)
offset 1267360 (391276 in aboot)
offset 3102124 (2226040 in aboot)
Worth restating that the corresponding partition on-device containing the images, mmcblk0p12 (as mentioned several times by @makers_mark), is named aboot. When the device is locked, abootb (mmcblk0p19) is a byte-for-byte copy of aboot with the exception of the bootloader's lockstate storage area located near 5242368 with another "ANDROID-BOOT!". When unlocked this is also the case, and the only further change is at the lockstate offset.
Also.. *cough*
Now.. to generate a replacement image and see about hacking it in...
I will make a lock image that has a long white line ,corresponding to their oblivious pixel, and replace it in all three spots. It will contain no more and no less data (no padding in testing scenarios). If you want to "dd" it to the partition or use otherwise "cough" mentions, then feel free. Very nice find there. I used a popular internet archive to get the source (thread) that I was referring to. The cough seems about the same caliber as far as knowledge and insight.
Let me know if you want me to make a 4.08 bootloader for you. I will not go off of your offsets, I will re-verify all that and quintuple check everything. You can do the same as well if you want to be extra sure. If that was the case we would have bianrily exact files. When I wrote this thread, the N7 was the only (and first) android that I owned. Hence it was not sacrificial to me, but an enjoyment that I couldn't just test like that. It is dead now (probably just the battery) and getting ready to set sail on an equitable distribution-end of life garbage cycle, or straight to the data recovery center for cheating wives who want to find any dirt they can to make themselves look better :laugh:
You have done your research on the bootloader in question, and maximized efficiency in a recovery of a failed attempt. Good job!Hmm, I'll have to check out the popular internet archives since perhaps the pictures, etc. would still be intact in their coughs.. :highfive:
I tried hacking the bootloader.img already and fastboot throws a "signature failed!" error, so it seems aboot is the only way to go.
I decided to get crazy with it so I already tried replacing the lock image with the new version in all 3 places in aboot and flashing it and it hard bricked my device. But not so hard that I couldn't recover it myself with some more poking around.
So it seems your original assessment may have been correct, or perhaps I was just a bit cavalier since the new lock image was shorter in data length than the old and required some minor 00 padding. Since I can reliably recover my device (tried it again by fully zeroing aboot), I'm definitely up for some more testing, and agree that a more methodic/scientific approach where the data is the same length (perhaps just changing a single pixel or something to start with) would probably be the best approach. :laugh:
Attached is my aboot.img backup for you to modify and generate your tests. :good:
You have done your research on the bootloader in question, and maximized efficiency in a recovery of a failed attempt. Good job!
One of the good things about RLE (pertaining to this particular scenario) is that you don't have to alter just one pixel to make the image size the same. That is actually really difficult based on the image. I was simply putting out there the random white dot at the bottom right of the lock as a "shove it" move, whereas the ideal way would be to move some pixels that do not go from a white/grey to another white/grey (or black/grey vice versa). The solution was obvious (after the fact):
It is the exact same size and doesn't have to mess with any of the grey areas, and should not be hard to recognize if it takes and boots. I just made a black line white by changing 000 at byte 2884 (in the cut out image, not the complete bootloader) to ÿÿÿ. Here is the data for it.
518 712 1090 600 960
712, 1, 1200
@echo off
setlocal enabledelayedexpansion
color 0b
set "vers=1.2"
title Run Length Imager v%vers%
set "device_dir=sdcard"
set "partitionfind=mmc"
set autozero=sure
set outfiletype=png
set autoopen=sure
set "outfilefolder=output"
set "loglevel=-loglevel debug"
set "hidebanner=-hide_banner"
set "adblog=>>"%~dp0sys\adb_log.txt" 2>&1"
set "ffmlog=>>"%~dp0sys\ffmpeg_log.txt" 2>&1"
IF "%~1"=="-d" (
set ffmlog=
set adblog=
set "loglevel=-loglevel debug"
set hidebanner=
mode con:cols=1000 lines=4000
color 07
shift
)
cd /d "%~dp0"
if not exist "%~dp0%outfilefolder%\" mkdir "%~dp0%outfilefolder%"
if exist "%~dp0sys\adb_log.txt" del /q "%~dp0sys\adb_log.txt"
if exist "%~dp0sys\ffmpeg_log.txt" del /q "%~dp0sys\ffmpeg_log.txt"
if exist "%~dp0sys\rli_log.txt" del /q "%~dp0sys\rli_log.txt"
if exist "%~dp0sys\needfiles" del /q "%~dp0sys\needfiles"
if not exist "%~dp0bin\ffmpeg.exe" echo.FFMPEG Program "%~dp0bin\ffmpeg.exe">>"%~dp0sys\needfiles"
if not exist "%~dp0bin\rlimager1.2.exe" echo.rlimager1.2.exe "%~dp0bin\rlimager1.2.exe">>"%~dp0sys\needfiles"
if exist "%~dp0sys\needfiles" goto :help
if not exist "%~dp0sys\definitions" call :make_definitions_file
if "[%~1]" neq "[]" if exist "%~1" echo.%1>"%~dp0sys\last_file"
if exist "%~dp0sys\settings" (call :load_settings) else (
set "maxcount=0"
set "offset=0"
set /a "bpp=4"
set "pixel_format=bgr0"
set "line_length=50,1,180"
set "rldecode_on=1"
call :save_settings
)
if exist "%~dp0sys\last_file" call :load_last_file
goto :menu
:help
echo.&echo.&echo.&echo.&echo.&echo.&echo.&echo.
echo.The following necessary file^(s^) are not found in their proper location:
echo.&echo.
type "%~dp0sys\needfiles"
echo.&echo.&echo.&echo.&echo.&echo.&echo.&echo.
pause>nul
goto :egress
:make_definitions_file
cls&echo.&echo.&echo.&echo.&echo.&echo.&echo.&echo.
if not exist "%~dp0sys\" mkdir "%~dp0sys"
echo.Building FFmpeg Pixel Format List..
echo.This should only take a minute...&echo.
if exist "%~dp0sys\definitions" del /q "%~dp0sys\definitions"
echo.rgb565 2 >>"%~dp0sys\definitions"
echo.bgr565 2 >>"%~dp0sys\definitions"
for /f "skip=1 tokens=2" %%p in ('bin\ffmpeg -pix_fmts 2^>^&1^|findstr /rxic:"^I.*"') do (
%ffmlog%"%~dp0bin\ffmpeg.exe" -f rawvideo -s 1x1 -pix_fmt rgba -i "%~dp0sys\getres" -f rawvideo -s 1x1 -pix_fmt %%p -y "%~dp0sys\%%p"
for %%? in ("%~dp0sys\%%p") do if not "%%~z?"=="0" set /a bval=%%~z?/3&echo.%%~n? !bval!>>"%~dp0sys\definitions"
del /q "%~dp0sys\%%p"
)
echo.Finished!&call :load_settings
goto :eof
:make_images
call :drawhead
call :drawsettings
if defined list (set "for_type=for /l") else (set "for_type=for")
for %%p in (%pixel_format%) do (
call :setbpp %%p
if "!rldecode_on!"=="1" (
set "out_file=decoded_raw_!bpp!_byte_%in_filename%"
set "out_path=%~dp0%outfilefolder%\%in_filename%_max_%maxcount%_offset_%offset%"
if not exist "!out_path!\" mkdir "!out_path!"
if not exist "!out_path!\!out_file!" (echo.Decoding !bpp! byte rle)&("%~dp0bin\rlimager1.2.exe" -d !bpp! -m %maxcount% -o %offset% < %file% > "!out_path!\!out_file!")||(call :rli_help&goto :menu)
for %%? in ("!out_path!\!out_file!") do set /a "out_filesize=%%~z?"
if not exist "!out_path!\%%p\" mkdir "!out_path!\%%p"
if defined autoopen start "" "!out_path!\%%p\"
%for_type% %%R in (%line_length%) do (
set /a height=!out_filesize!/%%R/!bpp!
echo.Using ffmpeg to generate %%Rx!height! image from %%p pixel format.
if !height! NEQ 0 %ffmlog%"%~dp0bin\ffmpeg.exe" %hidebanner% %loglevel% -f rawvideo -vcodec rawvideo -pix_fmt %%p -s %%Rx!height! -i "!out_path!\!out_file!" -vframes 1 -y "!out_path!\%%p\%%Rx!height!.%outfiletype%"
)
) else (
set "out_path=%~dp0%outfilefolder%\%in_filename%_no_rldecode\%%p"
if not exist "!out_path!\" mkdir "!out_path!"
if defined autoopen start "" "!out_path!\"
%for_type% %%R in (%line_length%) do (
set /a height=!in_filesize!/%%R/!bpp!
if /i "%%p"=="monow" set /a height*=8
if /i "%%p"=="monob" set /a height*=8
echo.Using ffmpeg to generate %%Rx!height! image from %%p pixel format.
if !height! NEQ 0 %ffmlog%"%~dp0bin\ffmpeg.exe" %hidebanner% %loglevel% -f rawvideo -vcodec rawvideo -pix_fmt %%p -s %%Rx!height! -i %file% -vframes 1 -y "!out_path!\%%Rx!height!.%outfiletype%"
)
)
if "!auto_turn_back_on!"=="1" (set "rldecode_on=1"&set auto_turn_back_on=)
)
goto :eof
:rle_image
set "out_path=%outfilefolder%\Run Length Encoded_%in_filename%"
for %%p in (%pixel_format%) do (
call :setbpp %%p
if "%%p"=="rgb0" (set "zoffset=8"&set "zero=8")
if "%%p"=="0rgb" (set "zoffset=5"&set "zero=8")
if "%%p"=="bgr0" (set "zoffset=8"&set "zero=8")
if "%%p"=="0bgr" (set "zoffset=5"&set "zero=8")
set "out_file=encoded_raw_!bpp!_byte_%in_filename%"
if not exist "%~dp0!out_path!\" mkdir "%~dp0!out_path!\"
%ffmlog%"%~dp0bin\ffmpeg.exe" %hidebanner% %loglevel% -i %file% -f rawvideo -vcodec rawvideo -pix_fmt %%p -y "%~dp0!out_path!\raw_%%p"
if defined autozero (echo.Encoding !bpp! byte rle&"%~dp0bin\rlimager1.2.exe" -z 8 -o !zoffset! -i "%~dp0!out_path!\%in_filename%_rl_encoded_with_!bpp!_byte_pattern_and_%%p_pixel_format" -e !bpp! < "%~dp0!out_path!\raw_%%p" > "%~dp0!out_path!\%in_filename%_rl_encoded_with_!bpp!_byte_pattern_and_%%p_pixel_format"||(call :rli_help&goto :menu)
) else (echo.Encoding !bpp! byte rle&"%~dp0bin\rlimager1.2.exe" -e !bpp! < "%~dp0!out_path!\raw_%%p" > "%~dp0!out_path!\%in_filename%_rl_encoded_with_!bpp!_byte_pattern_and_%%p_pixel_format"||(call :rli_help&goto :menu))
set zoffset=&set zero=
)
if defined autoopen start "" "%~dp0!out_path!\"
goto :eof
:rli_help
echo.There was a problem encoding^/decoding the file:&echo.%file%
echo.Bpp is: %bpp%&echo.Pixel format is: %pixel_format%&echo.Offset is: %offset%
echo.Max run is: %maxcount%&echo.Width is: %line_length%&echo.Working file name is: %in_filename%&echo.&pause >nul
goto :eof
:load_last_file
set "encode="
set /p file=<"%~dp0sys\last_file"
for %%? in (%file%) do set /a "in_filesize=%%~z?" &set "in_filename=%%~n?" &set "ext=%%~x?"
if [%ext%]==[] goto :eof
if "%ext%"==".jpg" set "encode=true"
if "%ext%"==".png" set "encode=true"
if "%ext%"==".bmp" set "encode=true"
if "%ext%"==".jpeg" set "encode=true"
goto :eof
:load_settings
<"%~dp0sys\settings" (
set /p pixel_format=
set /p bpp=
set /p offset=
set /p maxcount=
set /p line_length=
set /p rldecode_on=
)
set /a bpp
echo.%line_length%|findstr ".*,.*,"&&set "list=1"||set list=
goto :eof
:save_settings
>"%~dp0sys\settings" (
echo.%pixel_format%
echo.%bpp%
echo.%offset%
echo.%maxcount%
echo.%line_length%
echo.%rldecode_on%
)
goto :eof
:menu
set auto_turn_back_on=&call :load_last_file&call :drawhead&call :drawsettings
echo.&echo.&echo.1 - Make Image(s)
echo.&echo.2 - Change Output Line Length ^(width^)
echo.&echo.3 - Change Pixel Format
echo.&echo.4 - Use ADB To List/Pull A Partition
echo.&if defined rldecode_on (echo.5 - Turn Off Run Length Decoding) else (echo.5 - Turn On Run Length Decoding)
echo.&if defined rldecode_on (echo.6 - Change Offset) else (echo. - - Change Offset ^(run length decoding is off^))
echo.&if defined rldecode_on (echo.7 - Change Max Run Length) else (echo. - - Change Max Run Length ^(run length decoding is off^))
echo.&if defined encode (echo.8 - Encode image) else (echo.8 - Extract Jpgs From File)
echo.&echo.9 - Exit&echo.
choice /n /m "Select A Menu Number:" /C:123456789
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 errorlevel 7 set k=7
if errorlevel 8 set k=8
if errorlevel 9 set k=9
if %k%==1 call :make_images
if %k%==8 if "%encode%"=="true" (call :rle_image) else (call :jextract %file%)
if %k%==4 call :getpartitions
if %k%==3 call :change_pf
if %k%==2 call :change_line_length
if %k%==5 call :rle_toggle
if %k%==6 if defined rldecode_on call :change_offset
if %k%==7 if defined rldecode_on call :change_max_run
if %k%==9 goto :egress
goto :menu
:jextract
call :drawhead&call :drawsettings
set "out_path=%~dp0%outfilefolder%\%in_filename%_extracted_jpgs"
if not exist "%out_path%\" mkdir "%out_path%"
echo.&echo.Working...
"%~dp0bin\rlimager1.2.exe" -o %offset% -j "%out_path%\%in_filename%" <%file%
if defined autoopen start "" "%out_path%\"
echo.&echo.&echo Press any key to continue to the main menu..
pause>nul
goto :eof
:change_max_run
call :drawhead&call :drawsettings
echo.over 4 billion times. With a 3 Bpp rle pattern the highest value 0xFF will repeat the
echo.pixel 255 times maximum. And with a 2 Bpp rle pattern the value 0xFFFF will repeat
echo.a pixel 65535 times.&echo.
echo.When searching this way you need to set the max pixel run count to around ~1000-2000 to avoid
echo.unusable image files that can take forever to generate.&echo.
echo.Just press enter for a default value of 0 which will let the decoding process run its
echo.natural course.&echo.
set /p maxcount=Max pixel run:||set "maxcount=0"
call :save_settings
goto :eof
:change_offset
call :drawhead&call :drawsettings
echo.Enter the byte offset for the file.&echo.
echo.This should always be 0 when dealing with pure rle image files.
echo.The reason it is in here is because if you load an entire file with data/images all
echo.mixed together; the start of the Pixel count read for an image might just not be in
echo.the right spot, and the count will be read as color data instead of count data, resulting
echo.in really long^/short runs and no image. If using a whole partition^/file and a standard
echo.0 as the offset at several resolutions isn't generating the image you are looking for,
echo.taking the offset up, 1 by 1 until you get to 7 for 4 Bpp raw files, or an offset of
echo.3 for 2 ^& 3 Bpp raw files. It is advised to set your max pixel run count to ^~1000-2000
echo.when searching through complete files/partitions like this.&echo.
echo.This is the same thing as deleting "x" bytes from the beginning of the file.&echo.
echo.If you are using an image that starts with the count byte^(s^) at byte 1 in the file, then
echo.you don't have to worry about it.&echo.
echo.Just press enter for the default offset of 0.&echo.
set /p offset=Offset:||set "offset=0"
call :save_settings
goto :eof
:egress
"%~dp0bin\adb.exe" kill-server>nul 2>&1
endlocal&exit
goto :eof
:rle_toggle
if defined rldecode_on (set rldecode_on=) else (set "rldecode_on=1")
call :save_settings
goto :eof
:change_pf
:keepitinthecall
call :drawhead
call :drawsettings
echo.Enter the pixel format to use. The run length decoder will automatically adjust format accordingly.
echo.You may enter multiple pixel formats, but of course if will take longer and produce double the
echo.images if you enter two, or triple if you choose three. If you enter multiple pixel formats
echo.seperate them with a space or a comma. The bytes per pixel number seen at the top of the screen
echo.will only reflect the correct value when one pixel format is chosen, this however will have
echo.no bearing when you go to make images as the bpp is determined before each set of images is made.&echo.
echo.Note that any pixel format over 4 bytes per pixel will probably never be used in Android, for the
echo.purpose of displaying a static image at least.
echo.Threre is no run length decoding of those pixel formats over 4 bytes per pixel as of right now.&echo.
echo.The ones listed below, grouped by their bytes per pixel, are some of the more common pixel formats.
echo.Hit enter to see all input formats available with your FFmpeg build.
echo.&echo.Enter pixel formats in LOWER CASE ONLY.&echo.
echo.Enter "build" if you have updated your ffmpeg, and would like to update the pixel formats also.&echo.
echo.Enter "show" to show available pixel formats with your ffmpeg build.
echo.Common 2 Bpp android pixel formats ^[rgb565le, bgr565le^]
echo.Common 3 Bpp android pixel formats ^[rgb24, bgr24^]
echo.Common 4 Bpp android pixel formats ^[rgb0, 0rgb, 0bgr, bgr0, rgba, argb, abgr, bgra^]&echo.
set "old=%pixel_format%"
set /p pixel_format=Pixel format^(s^):||goto :eof
if /i "%pixel_format%"=="build" (set "pixel_format=%old%"&call :make_definitions_file&goto :keepitinthecall)
if /i "%pixel_format%"=="show" (set "pixel_format=%old%"&call :show_pixel_formats&goto :keepitinthecall)
call :setbpp %pixel_format%
call :save_settings
goto :eof
:setbpp
for /f "tokens=1,2" %%a in ('type "%~dp0sys\definitions"') do if /i "%~1"=="%%a" set /a "bpp=%%b"
if %bpp% GEQ 5 if defined rldecode_on (set "auto_turn_back_on=1"&set rldecode_on=)
if %bpp% EQU 1 if defined rldecode_on (set "auto_turn_back_on=1"&set rldecode_on=)
call :save_settings
goto :eof
:show_pixel_formats
cls&echo.Input pixel formats supported with your FFmpeg build:
for /f "skip=1 tokens=2,4" %%A in ('bin\ffmpeg -pix_fmts 2^>^&1^|FINDSTR /rxic:"^I.*"') DO echo.%%A--- %%B ^<^<^<BITS per pixel
echo.&echo.Press enter to continue...
pause>nul
goto :eof
:drawsettings
echo.Working Name: %in_filename%&echo.File Name: %file%&echo.Size: %in_filesize% bytes
echo.__________________________________&echo.______________________________________&echo.
echo.Pixel Format: %pixel_format%&echo.Line Length: %line_length%
if defined rldecode_on (
echo.Rle Format: %bpp% byte pp&echo.Max Run Length: %maxcount% pixels
echo.Offset: %offset%) else (echo.&echo.Run Length Decoding Is Turned Off.&echo.)
echo.______________________________________&echo.
goto :eof
:change_line_length
call :drawhead&call :drawsettings
echo.Enter the line length ^(width^) that you want to use. You can enter several, SEPERATED BY SPACES;
echo.or you can use a range SEPERATED BY COMMAS, in this format: start resolution, skips, ending resolution.&echo.
echo.Example: If you want to use the widths of 150 25 3000 400 98 16. You would enter in any order:
echo.150 25 3000 400 16 98&echo.
echo.Example: If you want a line length starting at 100 pixels going to 1200 pixels, while skipping to every
echo.10th pixel. You would enter:
echo.100,10,1200&echo.
set /p "line_length=Line length:"
echo.%line_length%|findstr ".*,.*,.*"&&set "list=1"||set list=
call :save_settings
goto :eof
:drawhead
cls&echo.&echo.___________________________________-_-
echo.__________________________________&echo.&echo.Run Length Imager: v%vers% by makers_mark
echo.__________________________________&echo.______________________________________&echo.
goto :eof
:getpartitions
if not exist "%~dp0partitions\" mkdir "%~dp0partitions"
call :drawhead&set /a index=1
"%~dp0bin\adb.exe" -d start-server
if %ERRORLEVEL% GTR 0 call :adb_error&goto :eof
for /f "skip=1 tokens=3,4" %%s in ('bin\adb.exe -d shell cat /proc/partitions^|findstr /rxic:".*%partitionfind%.*"') do (
if not "%%s"=="" (call set /a "_size[!index!]=%%s"&&call set "_partition[!index!]=%%t") else (set /a index=1)
call set /a index+=1
)
if %ERRORLEVEL% GTR 0 call :adb_error&goto :eof
set /a index-=1
echo. Partition Size&echo.
for /l %%c in (1,1,%index%) do (
if %%c LSS 10 (echo. %%c. !_partition[%%c]! !_size[%%c]!) else (
echo.%%c. !_partition[%%c]! !_size[%%c]!)
)
echo.&echo.If you want to pull one of these partitions from your device, enter the number
echo.to the left of it and press enter. Just press enter to go back to the Main Menu&echo.
set /p _pick=:||goto :eof
2>nul set /a _pick=%_pick%/1 || GOTO :eof
IF %_pick% LSS 1 GOTO :eof
if %_pick% GTR %index% goto :eof
cls&echo.&echo.&echo.WARNING: WARNING: WARNING: WARNING: WARNING:&echo.WARNING: WARNING: WARNING: WARNING: WARNING:
echo.WARNING: WARNING: WARNING: WARNING: WARNING:&echo.WARNING: WARNING: WARNING: WARNING: WARNING:&echo.&echo.&echo.&echo.&echo.
echo.Issuing this command:&echo.
call echo.bin^\adb.exe -d shell dd if^=^/dev^/block^/%%_partition[!_pick!]%% of^=^/%device_dir%^/%%_partition[!_pick!]%%
echo.&echo.PLEASE READ THIS TWICE....&echo.
echo.DD is a VERY powerful tool, and if the output directory^/file; listed after ^"of^=^" is not the
echo.name of the partition you chose to pull, DO NOT CONTINUE. If you are not sure what you are doing;
echo.what this command is, or what you are even looking at. DO NOT CONTINUE.&echo.
set "guess=%random%"
echo.Enter this number to continue: %guess%
echo.&set /p answer=:||goto :eof
if not "%guess%"=="%answer%" goto :eof
echo.&echo.Copying data into a file on your device...
call echo."%~dp0bin\adb.exe" -d shell "dd if=/dev/block/%%_partition[!_pick!]%% of=/%device_dir%/%%_partition[!_pick!]%%"|cmd /v:on%adblog%&&echo.&&echo.Copying file from your device to your computer...&&call echo."%~dp0bin\adb.exe" -d pull "/%device_dir%/%%_partition[!_pick!]%%" "%~dp0partitions\%%_partition[!_pick!]%%"|cmd /v:on%adblog%&&echo.&&echo.Deleting the file from your device...&&call echo."%~dp0bin\adb.exe" -d shell rm "/%device_dir%/%%_partition[!_pick!]%%"|cmd /v:on%adblog%
call echo."%~dp0partitions\%%_partition[!_pick!]%%">"%~dp0sys\last_file"
echo.&echo.&echo.Finished. The partition has been loaded and is saved as:&echo.&call echo."%~dp0partitions\%%_partition[!_pick!]%%"&echo.&echo.Press any key to continue.
call :save_settings
pause>nul
goto :eof
:adb_error
echo.&echo.&echo.&echo.&echo.&echo.&echo.&echo.
echo. ADB is not connected, working properly, or you have
echo. more than one device connected.
echo. Try "Safely Removing" your device from your computer.
echo. Then unplug your usb cable, and reinsert it.
echo.&echo.&echo.&echo.&echo.&echo.&echo.&echo.
pause>nul
goto :eof
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
& NOTICE:
& May 5th, 2014
&
& makers_mark @ xda-developers.com
& http://xdaforums.com/showthread.php?t=2764354
&
& Original source:
& https://android.googlesource.com/platform/build/+/b6c1cf6de79035f58b512f4400db458c8401379a/tools/rgb2565/to565.c
& Based off of the original to565.c program to convert raw rgb888 r=8 g=8 b=8 images
& to, 2 byte count, 2 byte color run length encoded rgb565 r=5 g=6 b=5 files.
& Mainly, if not always to my knowledge, used for creating initlogo.rle files for kernel splash
& screens.
&
& Added decoding of 2, 3, and 4 byte rgb(x) patterns
& Added encoding of 3 and 4 byte rgb(x) patterns
& Added byte offsets and maximum pixel runs for decoding files not totally
& encoded in a run length manner
& Version 1.2 added:
& Jpeg extractor, to pull jpegs from any file or drive/device image
& A zero byte writer, to undo what ffmpeg does to rgb0, 0rgb, bgr0, and 0bgr pixel formats
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
unsigned int _CRT_fmode = _O_BINARY;
static char fileName[1024];
void zeroBytes(long long, long, char *);
void jpegExtract(char *, unsigned long long);
void headerToFooter(int);
int getFilename(char *);
void decode_rgb16_rle(unsigned int, unsigned long long int);
void decode_rgb24_rle(unsigned int, unsigned long long int);
void decode_rgbx32_rle(unsigned long int, unsigned long long int);
void encode_rgb16_rle(void);
void encode_rgb24_rle(void);
void encode_rgbx32_rle(void);
void zeroBytes(long long offset, long z, char *inputFile)
{
int readByte;
FILE *zeroStream;
FILE *inStream;
long long int cursorPosition;
char outputFile[1024];
sprintf(outputFile, "%s.zero", inputFile);
if ((inStream = fopen(inputFile, "rb")) == NULL){
fclose(inStream);
return;
}
if ((zeroStream = fopen(outputFile, "wb")) == NULL){
fclose(inStream);
fclose(zeroStream);
return;
}
fprintf(stderr,"\nZeroing every %ld bytes starting at %lld", z, offset);
fprintf(stderr,"\nInput file: %s", inputFile);
while ((readByte = fgetc(inStream)) != EOF){
cursorPosition = ftell(inStream);
if (((cursorPosition - offset) % z) == 0 && cursorPosition >= offset){
fputc(0,zeroStream);
}else{
fputc(readByte,zeroStream);
}
}
fclose(inStream);
fclose(zeroStream);
}
void jpegExtract(char outname[1024], unsigned long long o)
{
int readByte;
FILE *fileStream;
unsigned int header;
if (o != 0){
fseek(stdin, o, SEEK_SET);
}
while ((readByte = fgetc(stdin)) != EOF){
if (readByte == 0xff){
readByte = fgetc(stdin);
if (readByte == 0xd8){
readByte = fgetc(stdin);
if (readByte == 0xff){
readByte = fgetc(stdin);
if (readByte == 0xe0 || readByte == 0xe1){
header = 0x00ffd8ff | (readByte << 24);
if (!getFilename(outname)){
if ((fileStream = fopen(fileName, "wb")) == NULL){
fclose(fileStream);
return;
}
int streamNumber = fileno(fileStream);
fprintf(stderr, "\n%s", fileName);
write(streamNumber, &header, 4);
headerToFooter(streamNumber);
close(streamNumber);
continue;
}else{
break;
}
}
}
}
}
}
fclose(stdin);
}
void headerToFooter(int streamNumber)
{
short notFinished = 1;
int polarity = 1;
int readByte;
while((readByte = fgetc(stdin)) != EOF){
if (readByte == 0xff){
readByte = fgetc(stdin);
if (readByte == EOF){
readByte = 0xff;
write(streamNumber, &readByte, 1);
break;
}else if (readByte == 0xd8){
polarity += 1;
readByte = 0xd8ff;
write(streamNumber, &readByte, 2);
}else if (readByte == 0xd9){
polarity -= 1;
readByte = 0xd9ff;
write(streamNumber, &readByte, 2);
if (polarity == 0){
break;
}
}else{
readByte = 0x00ff | (readByte << 8);
write(streamNumber, &readByte, 2);
}
}else{
write(streamNumber, &readByte, 1);
}
}
}
int getFilename(char outputbase[1024])
{
unsigned int counter;
FILE *stream;
for (counter = 1; counter <= 99999; counter++){
sprintf(fileName, "%s_%05d.jpg", outputbase, counter);
if ((stream = fopen(fileName, "r+")) != NULL){
fclose(stream);
continue;
} else {
fclose(stream);
return(0);
}
}
fclose(stream);
return(1);
}
void decode_rgb16_rle(unsigned int m, unsigned long long int o)
{
unsigned short data[2], repeats;
if (o != 0){
fseek(stdin, o, SEEK_SET);
}
while(read(0,data,4) == 4){
if (data[0] > m){
continue;
}
for (repeats = 0; repeats < data[0]; repeats++){
write(1, &data[1], 2);
}
}
}
void decode_rgb24_rle(unsigned int m, unsigned long long int o)
{
unsigned char repeats, data[4];
unsigned long color;
if (o != 0){
fseek(stdin, o, SEEK_SET);
}
while(read(0, data, 4) == 4){
if (data[0] > m){
continue;
}
color = ((data[1]) | (data[2] << 8) | (data[3]) << 16);
for (repeats = 0;repeats < data[0]; repeats++){
write(1, &color, 3);
}
}
}
void decode_rgbx32_rle(unsigned long int m, unsigned long long int o)
{
unsigned long repeats;
unsigned long data[2];
if (o != 0){
fseek(stdin, o, SEEK_SET);
}
while(read(0, data, 8) == 8){
if (data[0] > m){
continue;
}
for (repeats = 0; repeats < data[0]; repeats++){
write(1, &data[1], 4);
}
}
}
void encode_rgbx32_rle(void)
{
unsigned long color, last, count;
count = 0;
while(read(0, &color, 4) == 4){
if (count){
if ((color == last) && (count != 0xFFFFFFFF)){
count++;
continue;
} else {
write(1, &count, 4);
write(1, &last, 4);
}
}
last = color;
count = 1;
}
if (count){
write(1, &count, 4);
write(1, &last, 4);
}
}
void encode_rgb16_rle(void)
{
unsigned short int last, color, count;
count = 0;
while(read(0, &color, 2) == 2){
if (count){
if ((color == last) && (count != 0xFFFF)){
count++;
continue;
} else {
write(1, &count, 2);
write(1, &last, 2);
}
}
last = color;
count = 1;
}
if (count){
write(1, &count, 2);
write(1, &last, 2);
}
}
void encode_rgb24_rle(void)
{
unsigned char count;
unsigned long int last, color;
count = 0;
while(read(0, &color, 3) == 3){
if (count){
if ((color == last) && (count != 0xFF)){
count++;
continue;
} else {
write(1, &count, 1);
write(1, &last, 3);
}
}
last = color;
count = 1;
}
if (count){
write(1, &count, 1);
write(1, &last, 3);
}
}
int usage(void){
fprintf(stderr, "\n\n\nUsage:\n\nrlimager.exe ([-e] [2-4] | [-d] [2-4] [-m] [max run] [-o] [offset]) < input_file > output_file\n\n");
fprintf(stderr, "Mandatory, one or the other\n\n");
fprintf(stderr, "-d (2-4) Run Length Decode input_file from 2, 3, or 4 byte color pattern\n");
fprintf(stderr, "-e (2-4) Run Length Encode input_file to 2, 3, or 4 byte color pattern\n");
fprintf(stderr, "-j (output root name) Extract Jpegs from file. Output name can include a full path.\n");
fprintf(stderr, "-z (skip) -o (offset) Zero every (skip) bytes, starting with (offset)\n\n");
fprintf(stderr, "Optional for [-d] decoding only:\n\n");
fprintf(stderr, "-m (max run) Maximum pixel run to decode. Default is 0, which defaults to the maximum allowable for each color pattern\n");
fprintf(stderr, "-o (offset) Offset (in bytes) to start decoding. Default is 0\n");
fprintf(stderr, "\n\nExamples:\n\nrlimager1.2 -d 4 -m 8064 < \"C:\\example_file.rle\" > \"C:\\output\\rle_decoded\\example_file.rgb0\"\n");
fprintf(stderr, "rlimager1.2 -j root_name < \"C:\\users\\downloads\\system.img\"\n\n");
fprintf(stderr, "Notice with the jpeg extractor example above you have to use: < \"inputfile\"\n\n");
fprintf(stderr, "rlimager1.2 -z 8 -o 5 -i \"C:\\output\\example_file.rle\" -e 4 < \"C:\\example_file.rgb0\" > \"C:\\output\\example_file.rle\"\n\n");
fprintf(stderr, "The above example rle encodes the input file, then takes the output file and zeros every eighth byte starting at 5\n");
fprintf(stderr, "You can also zero byte any file without doing it all on one line, like:\n\n");
fprintf(stderr, "rlimager1.2 -z 5 -o 8 -i \"C:\\file_to_be_zeroed_every_5th_byte_strarting_with_the_8th.raw\"\n");
return(1);
}
int main(int argc, char **argv)
{
unsigned int decode_opt = 0, encode_opt = 0;
unsigned long long int maxrun = 0;
long long int offset = 0;
long zeroByte = 0;
short jflag = 0;
char *d_string, *e_string, *m_string, *o_string, *j_string, *z_string, *inputFile;
int c;
while ((c = getopt (argc, argv, "i:z:j:m:o:e:d:")) != -1)
switch(c)
{
case 'i':
inputFile = optarg;
break;
case 'z':
z_string = optarg;
zeroByte = atol(z_string);
break;
case 'j':
jflag = 1;
j_string = optarg;
break;
case 'm':
m_string = optarg;
maxrun = atoll(m_string);
break;
case 'o':
o_string = optarg;
offset = atoll(o_string);
break;
case 'e':
e_string = optarg;
encode_opt = atoi(e_string);
break;
case 'd':
d_string = optarg;
decode_opt = atoi(d_string);
break;
}
if ((encode_opt > 1) && (encode_opt < 5)){
if (maxrun != 0 || decode_opt != 0){
usage();
return(1);
}
if (encode_opt == 2){
encode_rgb16_rle();
return(0);
}
if (encode_opt == 3){
encode_rgb24_rle();
}
if (encode_opt == 4){
encode_rgbx32_rle();
}
if (zeroByte){
zeroBytes(offset, zeroByte, inputFile);
}
return(0);
} else if (zeroByte){
zeroBytes(offset, zeroByte, inputFile);
return(0);
} else if ((decode_opt > 1) && (decode_opt < 5)){
if (encode_opt != 0){
usage();
return(1);
}
if (decode_opt == 2){
if (maxrun == 0){
maxrun = 0xFFFF;
}
fprintf(stderr, "Maximum pixel run set at %d\n",maxrun);
decode_rgb16_rle(maxrun, offset);
return(0);
}
if (decode_opt == 3){
if (maxrun == 0){
maxrun = 0xFF;
}
fprintf(stderr, "Maximum pixel run set at %d\n",maxrun);
decode_rgb24_rle(maxrun, offset);
return(0);
}
if (decode_opt == 4){
if (maxrun == 0){
maxrun = 0xFFFFFFFF;
}
fprintf(stderr, "Maximun pixel run set at %lld\n",maxrun);
decode_rgbx32_rle(maxrun, offset);
return(0);
}
return(0);
} else if (jflag){
jpegExtract(j_string, offset);
} else usage();
return(1);
}
Came across this, simply because it's for LCD screens but explains the different encoding methods
http://www.demmel.com/download/ilcd/2d_rle_appnote.pdf
Bashing away at my HTC Desire C
void arbitrary(int bytesofcount, int bytesofcolor)
{
unsigned int i, j, k, totalperpixel = bytesofcount+bytesofcolor;
unsigned long times, count, counttotal;
unsigned char color, instream[totalperpixel];
unsigned char colorbyte[bytesofcolor];
while(read(0,instream,totalperpixel)){
for (i = 0; i<bytesofcount; i++){
count = instream[i];
if (i > 0) {
counttotal = (count << 8) | counttotal;
} else {
counttotal = count;
}
}
for (j=0; j<bytesofcolor;j++){
color = instream[j+i];
colorbyte[j] = color;
}
for (times=0;times< counttotal;times++) {
for (k=0;k<bytesofcolor;k++){
write(1, &colorbyte[k], 1);
}
}
count=0;
}
}
You've spiked my curiosity now, especially as I've not been able to work at my PC in a while
Is now off to see where it's pointed at from....
Bashing away at my HTC Desire C