[LG V20 Guides, News, & Discussion] emdroidle:
Okay, bit more analysis since I've actually kind of been wanting to be able to modify raw_resources (having my name/image on phone start would be kind of neat).

The initial header appears to have 5 fields:

struct rrheader {
char magic[16]="BOOT_IMAGE_RLE\x00\x00";
uint32_t entrycount;
uint32_t unknown;
char devicename[16];
uint32_t dataend;
};

The magic string is simply an identifier. Clearly suggestive of run-length encoding. The entrycount is the number of images stored in raw_resources. The unknown is a value which I don't know the meaning of, could instead be a pair of 16-bit numbers, but I suspect a single 32-bit little-endian is more likely. The devicename is something like "elsa_global_com". dataend identifies the complete length of all the data in raw_resources.

At offset 0x1000 (think LBA 1) the image headers start. The format is:

struct imageheader {
char name[40];
uint32_t dataoffset;
uint32_t expect;
uint32_t width;
uint32_t height;
char unknown[8];
}

Name is effectively a filename, such as "lglogo_image" or "verifiedboot_red_01". I'm pretty sure this string is what the code is searching for when trying to display an image. dataoffset is a byte offset from the begining of raw_resources. expect is a count of RLE entries worth of data, as such LGE/Qualcomm's software would multiply this by 4 and read that many bytes.

width and height are pretty obvious. The size of the image. I suspect the unknown is a pair of 4-byte integers, but I'm unsure of this. Presently I've got no idea of what it does. I'd love to have someone try modifying this value and see what it does.

5 images take roughly 250KB of space each: lglogo_image, verifiedboot_orange_01, verifiedboot_orange_02, verifiedboot_red_01, and verifiedboot_red_02. If you wanted to save space in raw_resources, you might merge verifiedboot_orange_01 with verifiedboot_orange_02, and similar for verifiedboot_red_0[12]. A number of the other images are also pairs which differ only by the unknown field, these pairs could be merged by setting their dataoffset values to the same value, thus freeing up more space.

My analysis in the previous post was on the money. The format is really dumb RLE. This is simple to encode, but doesn't offer very good compression ratios. These entries are 4-bytes long (expect counts these entries, not individual bytes). The first byte is a number value indicating a number of repeats, a 1 will result in 1 pixel of the color indicated by the next 3 bytes, a 2 will result in 2 pixels of the color, etc. The value 0 might well be untested, but it might cause 0 pixels of that color, 256 pixels of that color, 65536 pixels of that color, or perhaps a software crash.

The raw_resources sample I found had the color data in the order blue-green-red.

I'm attaching a simple Python 3 script which will decode a raw_resources image. Each portion will be dumped into a file matching the name in the image header. The format is "PPM" which is horribly inefficient, but easy to generate and modify by hand. Figure lglogo_image.ppm is 14MB for a 760x1544 image. The unknown in the image header will be emitted near the top of the PPM file (PPM is a text format, you can look at the raw data in a text editor). The data from the overall header including the raw unknown value will be emitted in a ".notes" text file matching the filename of the raw_resources image file.

Have fun with the knowledge.