• Introducing XDA Computing: Discussion zones for Hardware, Software, and more!    Check it out!

[TOOL][MOD][WIN] Change Your Splash Screen And Various Graphics v.97B

Search This thread

giannis_mathiou

Senior Member
Aug 14, 2011
347
176
Athens
I'm trying to create a logo like this. For the time I have only managed to to rebuild Images using strict mode. When I tried to use Non strict mode I ended up with no boot logo at all. So, could you guide me on the process I should follow to create full screen boot logo and build it through non strict mode?
Thank you very much In advance.

Edit: Bellow is the .bin file for anyone who may like and want my progress so far. The .bin is inside the .7z .
It's NOT flashable through recovery by any means. It is really simple, just replaced Google text with Nexus and removed lock icon at the bottom.

Edit2: It is build upon latest bootloader from stock image "bootloader-shamu-moto-apq8084-72.04". I don't know if that maters but I think worth saying.
 

Attachments

  • NexusByLineage.7z
    419.6 KB · Views: 37
  • logo_boot.Png
    logo_boot.Png
    22.1 KB · Views: 229
Last edited:

carl1961

Senior Member
Dec 5, 2010
7,521
6,201
Tickfaw
anyone know why the OP MotoLogo Injector v.97b.zip file missing?

Edit: I found this 1.1 version also by @makers_mark Worked Perfect!

Nexus 6 running lineage-18.1-20210412-microG-shamu

 

Attachments

  • logo_boot.png
    logo_boot.png
    32.3 KB · Views: 3
  • shamu_logo_DeGoogleNexusByLineage.zip
    896.6 KB · Views: 1
Last edited:

Top Liked Posts

  • There are no posts matching your filters.
  • 38
    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.
    MLInjector_zpsfd2308b5.png~original



    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!
    14
    For what it's worth, Google 2015:

    2 TWRP flashable zips. One with droid_operation.Png, ic_unlocked_bootloader.Png andlogo_boot.Png changed and one with ic_unlocked_bootloader.Png and logo_boot.Png changed
    13
    Can you make a splash image with new Google logo fot the latest android 6.0 bootloader, without any colors, black screen and new Google logo, it would mean so much

    Oh well... maybe your idea wasn't so bad after all. Attached
    8
    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]
    8
    Here is a video of how to change the boot logo:

    Add it to the OP if you want.