====== Android Boot Logo and Bootanimation ======
One of the favorite **vanity customizations** for an Android device, is to personalize the **boot logo** and the **boot animation**.
Here you find some notes about the Gretel A7, a phone based on the **MediaTek MT6580** chip, running **Android 6.0 Marshmallow**. Operation should be rather similar on other devices sharing a similar MTK chip and similar O.S. version.
We used a **GNU/Linux PC** as the host to perform all the actions: download and upload of partition content, manipulation of image files, running of some scripts, etc.
===== log.bin =====
The boot logo is contained into a dedicated partition called **logo**, you can find the binary image called **logo.bin** packed into the stock ROM archive or you can download it from the phone using the **SP Flash Tool** program.
The partition image contains **several different pictures** (39 in our case!), some are at full screen size (720x1280 pixels), others are snippets used (before the actual boot stage) to represent e.g. the charging battery, the percentage, etc. The **logo.bin** has a rather simple structure:
^ Content ^ Size (bytes) ^ Notes ^
^ MTK Header | 512 | At **offset 0x08** there should be the string **LOGO** or **logo**. |
^ Pictures Count | 4 | A [[wp>Little-endian|little-endian]] 32bit integer. This is the number of pictures packed into the data block. |
^ Total Block Size | 4 | A little-endian 32bit integer. This is the total size of the data, excluding only the 512 bytes of the MTK header. |
^ Offsets Map | 4 x Count | For each picture there is a little-endian 32bit integer, indicating the offset of the picture into the data, after the 512 bytes header. The first offset is 4 + 4 + (4 * pictures count). |
^ Pictures Data Block | Variable | Each picture is in **raw RGB** format, it is appended as a **z-compressed** file. |
Here there are two full screen examples:
{{img-03.png?100}}
{{img-38.png?100}}
Here it is a 163x29 pixels snippet used for the "battery charging" animation:
{{img-24.png?80}}
==== Unpack and repack the log.bin ====
Unfortunately the [[https://github.com/rom1nux/mtkimg|mtkimg]] did not work with my logo.bin. The [[https://github.com/rom1nux/mtkimg/issues/6|issue]] is about unsopported signature and RGB format. So I write a Python script, download it here: **{{mtk-android-logo.txt|mtk-android-logo}}**.
./mtk-android-logo unpack
Run the script into the same directory containing the **logo.bin** file; a **logo.d** directory will be created with compressed (.z) and uncompressed (.bin) files.
./mtk-android-logo repack
For repacking, the script needs the original **logo.bin** and a **logo.d** directory containing the pictures. If the z-compressed picture exists, it will be used, otherwise the .bin one is used after z-compressing it. The resulting image is saved as **logo.repack.bin**.
Pictures are expected to be **raw RGB**, stored with **z-compression**. The pixel size (width x height) of each picture must be guessed.
Suppose that th e screen size is 720x1280 and the biggest, uncompressed picture is 3686400 bytes:
3686400 / (720 * 1280) = 4
so we can desume that the picture is 4 bytes/pixel, i.e. a 32bit RGB. By **trial and error** we found that it is an BGRA (Blue, Green, Red and Alpha), we can convert it into PNG with **ffmpeg**, specifying the **bgra** pixel format:
ffmpeg -vcodec rawvideo -f rawvideo \
-pix_fmt bgra -s 720x1280 -i "img-01.bin" \
-f image2 -vcodec png "img-01.png"
Once edited, we can convert it back to raw BGRA with:
ffmpeg -vcodec png -i "img-01.png" \
-vcodec rawvideo -f rawvideo -pix_fmt bgra "img-01.bin"
It is known that also 16bit raw formats are used (eg. bgr565le), you can guess it, if the size of the picture is 2 bytes per pixel. You can list all the pixel formats supprted by ffmpeg by running:
ffmpeg -pix_fmts
===== bootanimation.zip =====
The logo contained into the **logo.bin** partition is displayed in the early stage of the boot process. Once the system partition is available, an animation is played for some seconds. That animation is contained into a zip file. In our case it turned out that the file is stored in **/system/media/bootanimation.zip**. To replace it, being into the **/system/** directory, **root privileges** are required.
There should be an executable responsible to actually run the animation, it should be **/system/bin/bootanimation**. It may search the bootanimation.zip in several directories, where the first one found, will be used. Searched directories can be:
* **/custom/media/bootanimation.zip**
* **/oem/media/bootanimation.zip**
* **/data/local/bootanimation.zip**
* **/system/media/bootanimation.zip**
If bootanimation.zip file is **not found**, the **framework-res.apk** package is searched into directories **/system/customer/framework/** or **/system/framework/**, that file contains two images that are used as a fall-back animation:
* assets/images/android-logo-mask.png
* assets/images/android-logo-shine.png
==== Contents of bootanimation.zip ====
Generally the animation is composed of **two parts**: the first is played just **once**, the second part is played in **loop** until the system is ready. This is controlled by the contents of the **desc.txt** file contained into the zip, here it is an example:
720 1280 15
p 1 0 part0
p 0 0 part1
The first line tell us that the animation is **720x1280 pixels**, at **15 frames per second**.
The second line tell us that there is a part of **type p** to be executed **1** time. The following number (**0** in the example above) someone says that it is a pause to wait after the animation, in my case it is instead ununsed at all. The actual frames are contained into the **part0** subdirectory.
The last line defines another part **type p** to be executed in an endless (**0**) loop until the system is ready, with a zero **0** pause. The frames are into the **part1** subdirectory.
A **type p** means that the animation can be interrupted when the boot process is completed. If you want instead a part to be played as the final part of the animation (e.g. if you want a fade-out effect), you have to use a **tpye c**, which means //play at least once//.
720 1280 15
p 1 0 part0
c 0 0 part1
c 0 0 part2
In the above example, once the boot process is completed, the **part1** is interrupted, and the **part2** is executed. Animation part **type c** was introduced with **Android Jelly Bean** (i.e. Android 4.1 to 4.3.1).
Frames are actually **PNG images**, of the proper size (720x1280 in our case).
So the directories structure should be something like this:
.
├── desc.txt
├── part0
│ ├── img_000.png
│ ├── ...
│ └── img_196.png
└── part1
├── img_197.png
├── ...
└── img_207.png
To pack eveything into a zip file you can use the command:
zip -r -Z store bootanimation.zip desc.txt part0 part1
Beware of the **%%-Z store%%** option: the zip archive must be created using the **store compression method**, not the //deflate// one.
===== Web References =====
* **[[https://github.com/rom1nux/mtkimg|mtkimg]]** Unpack/Repack boot.img, recovery.img and logo.bin for Mediatek
* **[[https://forum.xda-developers.com/showthread.php?t=1560836|BOOT ANIMATION explained]]**
* **[[http://muzso.hu/2012/07/15/understanding-boot-animations-in-android|Understanding boot animations in Android]]**