[Nexus 6P Original Android Development] makers_mark:
Nexus6Pcodec.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <windows.h>
#include "zlib.h"
#include "lodepng.h"
#include "Nexus6Pcodec.h"

uint8_t *FindSplashFile(FILE *input, uint64_t *start, uint64_t *end){

uint32_t numberOfImages = 0, lastOffset = 0, lastSize = 0;
int readByte;
uint8_t pos = 0;
uint8_t *data = NULL;

fseek(input, 0, SEEK_SET);

while ((readByte = fgetc(input)) != EOF){

if (readByte == splashHeader[pos]){

if (pos == 31){

*start = (ftell(input) - 32);

fseek(input, *start + 36, SEEK_SET);

if(fread(&numberOfImages, 1, 4, input) != 4){

fprintf(stderr, "ERROR: Reading Input File (no. of images).\n");
fclose(input);
exit(EXIT_FAILURE);

}

fseek(input, *start + 40 + ((numberOfImages - 1) * 52) + 44, SEEK_SET );

if(fread(&lastOffset, 1 , 4, input) != 4){

fprintf(stderr, "ERROR: Reading Input File (last offset).\n");
fclose(input);
exit(EXIT_FAILURE);

}

if(fread(&lastSize, 1, 4, input) != 4){

fprintf(stderr, "ERROR: Reading Input File (last size).\n");
fclose(input);
exit(EXIT_FAILURE);

}

*end = *start + (uint64_t)lastOffset + (uint64_t)lastSize;
fseek(input, *start, SEEK_SET);
data = (uint8_t*)malloc(*end - *start);

if(data == NULL){

fprintf(stderr, "ERROR: Allocating Memory (data)\n");
fclose(input);
exit(EXIT_FAILURE);

}

if(fread(data, 1, *end - *start, input) != *end - *start){

fprintf(stderr, "ERROR: Reading Input File (data).\n");
fclose(input);
exit(EXIT_FAILURE);

}

return data;

} else {

pos++;
continue;

}
}

pos = 0;
}

return 0;

}

uint32_t GetSize(FILE *fp){

uint32_t i = 0, cur = ftell(fp);

fseek(fp, 0, SEEK_END);
i = ftell(fp);
fseek(fp, cur, SEEK_SET);

return i;

}

void DrawHead(void){

HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
uint8_t i = 0;
SetConsoleTextAttribute(hConsole, TOPCOLOR);

printf("%c", 218);
for(i = 0; i < 79; i++){
printf("%c", 196);
}
printf("-_-%c%c\n", 196, 191);

printf("%c ", 179);
SetConsoleTextAttribute(hConsole, BLUE);
printf("N");
SetConsoleTextAttribute(hConsole, RED);
printf("E");
SetConsoleTextAttribute(hConsole, YELLOW);
printf("X");
SetConsoleTextAttribute(hConsole, BLUE);
printf("U");
SetConsoleTextAttribute(hConsole, GREEN);
printf("S");
SetConsoleTextAttribute(hConsole, RED);
printf(" 6");
SetConsoleTextAttribute(hConsole, YELLOW);
printf("P");
SetConsoleTextAttribute(hConsole, TOPTEXTCOLOR);
printf(" Image Injector v%s %c\n", version, 179);
printf("%c Written By:", 179);
SetConsoleTextAttribute(hConsole, GREEN);
printf("makers_mark");
SetConsoleTextAttribute(hConsole, TOPTEXTCOLOR);
printf("@xda ");

SetConsoleTextAttribute(hConsole, TOPCOLOR);
printf("%c\n", 179);
printf("%c", 192);
for(i = 0; i < 83; i++){
printf("%c", 196);
}
printf("%c\n", 217);

SetConsoleTextAttribute(hConsole, COLOR);

return;
}

int decode(FILE *originalBin, const uint8_t *path, HANDLE hConsole){

uint32_t i, numberOfImages = 0;
uint64_t cur;
int color;
uint32_t k = 0;
uint8_t pngName[512] = {0};
FILE *txt = NULL;
uint8_t command[512] = {0};
uint8_t exeFile[512] = {0};

fseek(originalBin, 36, SEEK_SET);

if((fread(&numberOfImages, 1, 4, originalBin)) != 4){

fprintf(stderr, "ERROR: Reading The Number Of Images.\n");
fclose(originalBin);
return 0;

}

pHeader headers[numberOfImages];

sprintf((char*)command, "%s\\Rebuild Images Folder.bat", path);

if ((txt = fopen((const char*)command, "w")) == NULL){

fclose(txt);
fclose(originalBin);
fprintf(stderr, "\n%s could not be opened.\n", command);
return 0;

}

printf(" Image Name W x H Offset Size Decoded Size \n");
UNDERSCORE;
color = INVERSE(COLOR);
uint8_t four = 0;

for( i = 0; i < numberOfImages; i++, four++, k = 0 ){

if (four == PATTERN){
color = INVERSE(color);
four = 0;
}

SetConsoleTextAttribute(hConsole, color);

if((fread(&headers[i].name, 1, 32, originalBin) != 32) ||
(fread(&headers[i].width, 1, 4, originalBin) != 4 ) ||
(fread(&headers[i].height, 1, 4, originalBin) != 4 ) ||
(fread(&headers[i].bpp, 1, 4, originalBin) != 4 ) ||
(fread(&headers[i].offset, 1, 4, originalBin) != 4 ) ||
(fread(&headers[i].size, 1, 4, originalBin) != 4 )){

fprintf(stderr, "ERROR: Reading Header Data.\n");
fclose(originalBin);
return 0;

}

if(headers[i].bpp != 24){

fprintf(stderr, "\n32 bpp isn't supported yet. When they acutally use it, I will include it.\n");
fclose(originalBin);
return 0;

}

headers[i].decodedSize = headers[i].width * headers[i].height * 3;

cur = ftell(originalBin);
fseek(originalBin, headers[i].offset + 10, SEEK_SET);
uint8_t j = 0;
while((headers[i].gzName[j++] = fgetc(originalBin)) != '\0'){};
fseek(originalBin, headers[i].offset, SEEK_SET);

sprintf((char*)pngName, "%s\\%s\\%s.png", path, IMAGES_DIR, headers[i].name);

printf("Decoding %s..", headers[i].name);

uint8_t buffer[headers[i].size];
uint8_t *rawBGRimage;
rawBGRimage = (uint8_t*)malloc((uint32_t)headers[i].decodedSize);

if(rawBGRimage == NULL){

fprintf(stderr, "ERROR: Allocating Memory (raw bgr image)\n");
fclose(originalBin);
return 0;

}

if(fread(&buffer, 1, sizeof(buffer), originalBin) != headers[i].size){

fprintf(stderr, "ERROR: Reading Encoded File.\n");
fclose(originalBin);
return 0;

}

dec(buffer, rawBGRimage, (uint32_t)headers[i].size, (uint32_t)headers[i].decodedSize);
uint8_t old = 0;

while( k < headers[i].decodedSize ){

old = rawBGRimage[k];
rawBGRimage[k] = rawBGRimage[k + 2];
rawBGRimage[k + 2] = old;
k += 3;

}

headers[i].crc32 = crc32(0L, Z_NULL, 0);
headers[i].crc32 = crc32(headers[i].crc32, rawBGRimage, headers[i].decodedSize);

printf("Writing PNG..");

lodepng_encode24_file((char*)pngName, rawBGRimage, (unsigned)headers[i].width, (unsigned)headers[i].height);

printf("\r %2d.%-32s %4d x %-4d %10d %10d %12d \n", i + 1, headers[i].name, headers[i].width, headers[i].height, headers[i].offset, headers[i].size, headers[i].decodedSize);

free(rawBGRimage);

fseek(originalBin, cur, SEEK_SET);

fprintf(txt, ":: %s %d %d %d %d %d %d %d %d %ld %s %s\n", headers[i].name, headers[i].width, headers[i].height, headers[i].offset, headers[i].size, headers[i].crc32, headers[i].bpp, headers[i].decodedSize, gzNewHeaderp.os, gzNewHeaderp.time, headers[i].gzName, pngName);
}

fclose(originalBin);

GetModuleFileName(NULL, (LPSTR)exeFile, 512);

fprintf(txt, "\n@mode con cols=86 lines=%d&echo off\ntitle Nexus6P Image Injector v%s\n\"%s\" -n %d -b \"\%%~dpnx0\" && 2>nul del \"%%~dp0\\%s\"\npause>nul\n", numberOfImages + 20, version, exeFile, numberOfImages, MODIFIEDBIN);
fclose(txt);
SetConsoleTextAttribute(hConsole, COLOR);

UNDERSCORE;
SetConsoleTextAttribute(hConsole, __INFO_);
printf("%s", path);
FinishLineSpaces((uint8_t)strlen((const char*)path));
BLANKLINE;
printf("This folder above contains an 'Images' folder.(The parent folder should of opened on \n");
printf("your screen). Inside of the 'Images' folder is all of the PNG's that were extracted \n");
printf("from your original file. Change/replace any images you want, but do not change the \n");
printf("name, or the location of the PNG's. Run the 'Rebuild Images Folder.bat' file when you\n");
printf("are finished editing the images and ready to make a new Splash.bin. \n");
BLANKLINE;
printf("You can rebuild the folder as many times as you want. \n");
printf("The output file, %s, is just rewritten/overwritten each time with", MODIFIEDBIN);

FinishLineSpaces(strlen((const char*)MODIFIEDBIN) + 63);
printf("what is currently in the 'Images' folder. \n");
SetConsoleTextAttribute(hConsole, COLOR);

return 1;
}

pHeader *ReadID(FILE *bat, uint8_t numberOfImages){

pHeader *new;
new = malloc(numberOfImages * 618);

if(new == NULL){

return(NULL);

}

memset(new, 0, numberOfImages * 618);
uint8_t i = 0;

while(fscanf(bat, "%*s %s %ld %ld %ld %ld %ld %ld %ld %ld %ld %s %[^\n]",
new[i].name, (long int*)&new[i].width, (long int*)&new[i].height, (long int*)&new[i].offset,
(long int*)&new[i].size, (long int*)&new[i].crc32, (long int*)&new[i].bpp, (long int*)&new[i].decodedSize,
(long int*)&new[i].os, (long int*)&new[i].time, new[i].gzName, new[i].pathToPNG) == 12){i++;}

return new;
}

uint32_t GetWidth(FILE *pngFile){

uint32_t width;

fseek(pngFile, 16, SEEK_SET);

if(fread(&width, 1, 4, pngFile) != 4){

fprintf(stderr, "\nERROR: Reading PNG Width\n");
return 0;

}

return(SWAP32(width));

}

uint32_t GetHeight(FILE *pngFile){

uint32_t height;

fseek(pngFile, 20, SEEK_SET);

if(fread(&height, 1, 4, pngFile) != 4){

fprintf(stderr, "\nERROR: Reading PNG Height\n");
return 0;

}

return(SWAP32(height));
}

int BuildImages(uint8_t *build, uint8_t numberOfImages, uint8_t brute, HANDLE hConsole){

uint32_t i = 0;
int color;
uint8_t resolutionChanges = 0;

FILE *bat = NULL;

if ((bat = fopen((const char*)build, "r")) == NULL){
fprintf(stderr, "ERROR: Opening Batch File\n");
return 0;
}

pHeader *old = ReadID(bat, numberOfImages);
fclose(bat);

if(old == NULL){

fprintf(stderr, "ERROR: Allocating Memeory (headers).\n");
return 0;

}

uint8_t oldPixel = 0, four = 0;
uint32_t k = 0;

FILE *modifiedBin = NULL;
FILE *originalBin = NULL;

uint8_t *headerTemplate;
uint32_t headerSize;

if ((modifiedBin = fopen((const char*)MODIFIEDBIN, "wb")) == NULL){

fprintf(stderr, "ERROR: Failed To Open File\n%s\n", MODIFIEDBIN);
return 0;

}

if ((originalBin = fopen((const char*)ORIGINALBIN, "rb")) == NULL){

fprintf(stderr, "ERROR: Failed To Open File\n%s\n", ORIGINALBIN);
fclose(modifiedBin);
return 0;

}

uint32_t modifiedSize = 0, originalSize = GetSize(originalBin);

headerSize = old[0].offset;
headerTemplate = (uint8_t*)malloc(headerSize);

if(headerTemplate == NULL){

fclose(originalBin);
fclose(modifiedBin);
unlink(MODIFIEDBIN);
fprintf(stderr, "\nERROR: Allocating Memory (header temp).\n");
return 0;

}

memset(headerTemplate, 0, headerSize);

if((fread(headerTemplate, 1, headerSize, originalBin)) != headerSize){

fclose(originalBin);
fclose(modifiedBin);
unlink(MODIFIEDBIN);
fprintf(stderr, "\nERROR: Reading File (original bin).\n");
return 0;

}

if((fwrite(headerTemplate, 1, headerSize, modifiedBin)) != headerSize){

fclose(originalBin);
fclose(modifiedBin);
unlink(MODIFIEDBIN);
fprintf(stderr, "\nERROR: Writing File (header temp).\n");
return 0;

}

printf(" Image Name W x H Offset Size Decoded Size \n");
UNDERSCORE;

color = INVERSE(COLOR);

for( i = 0 ; i < numberOfImages; k = 0, i++, four++){

printf("Decoding PNG..");
uint32_t width = 0, height = 0, crcrc = 0, offset = 0;

uint8_t *decodedPNG;
FILE *pngFile = NULL;

if ((pngFile = fopen((const char*)old[i].pathToPNG, "rb")) == NULL){

fprintf(stderr, "ERROR: Opening Png File\n%s\n", old[i].pathToPNG);
fclose(modifiedBin);
fclose(originalBin);
unlink(MODIFIEDBIN);

return 0;
}

width = GetWidth(pngFile);
height = GetHeight(pngFile);

if((width < 1) || (height <1)){

fclose(modifiedBin);
fclose(originalBin);
unlink(MODIFIEDBIN);
fclose(pngFile);

return 0;
}

const uint32_t rawBytes = width * height * 3;

if (four == PATTERN){

color = INVERSE(color);
four = 0;

}

SetConsoleTextAttribute(hConsole, color);

decodedPNG = (uint8_t*)malloc(rawBytes);

if(decodedPNG == NULL){

fclose(originalBin);
fclose(modifiedBin);
unlink(MODIFIEDBIN);
fprintf(stderr, "\nERROR: Allocating Memory (decoded png).\n");
return 0;

}

lodepng_decode24_file(&decodedPNG, (uint32_t*)&width, (uint32_t*)&height , (const char*)old[i].pathToPNG);
fclose(pngFile);

crcrc = crc32(0L, Z_NULL, 0);
crcrc = crc32(crcrc, decodedPNG, rawBytes);
printf("Swapping Color Order..");

while( k < rawBytes ){

oldPixel = decodedPNG[k];
decodedPNG[k] = decodedPNG[k + 2];
decodedPNG[k + 2] = oldPixel;
k += 3;

}

offset = ftell(modifiedBin);
memcpy(&headerTemplate[40 + (i * 52) + 44], &offset, 4);

if((crcrc == old[i].crc32) && (!brute)){

free(decodedPNG);
printf("Image Unchanged, Copying Data..");
fseek(originalBin, old[i].offset, SEEK_SET);
uint8_t *buff = (uint8_t*)malloc(old[i].size);

if(buff == NULL){

fclose(originalBin);
fclose(modifiedBin);
unlink(MODIFIEDBIN);
fprintf(stderr, "\nERROR: Allocating Memory (copy original buffer).\n");
return 0;

}

if((fread(buff, 1, old[i].size, originalBin)) != old[i].size){

fclose(originalBin);
fclose(modifiedBin);
unlink(MODIFIEDBIN);
fprintf(stderr, "\nERROR: Reading File (copy original buffer).\n");
return 0;

}

if((fwrite(buff, 1, old[i].size, modifiedBin)) != old[i].size){

fclose(originalBin);
fclose(modifiedBin);
unlink(MODIFIEDBIN);
fprintf(stderr, "\nERROR: Writing File (copy original buffer).\n");
return 0;

}

free(buff);
printf("\r %2d.%-32s %4d x %-4d %10d %10d %12d \n", i + 1, old[i].name, width, height, offset, old[i].size, old[i].decodedSize);

} else {

uint32_t compressedSize = 0;
printf("Encoding Image..");
uint8_t *buff = (uint8_t*)malloc((rawBytes * 1.1) + 12);

if(buff == NULL){

fclose(originalBin);
fclose(modifiedBin);
unlink(MODIFIEDBIN);
fprintf(stderr, "\nERROR: Allocating Memory (encode buffer).\n");
return 0;

}

gzNewHeaderp.name = old[i].gzName;
gzNewHeaderp.os = old[i].os;
gzNewHeaderp.time = old[i].time;
buff = enc(decodedPNG, rawBytes , buff, (rawBytes * 1.1) + 12, 9, &compressedSize);

if((fwrite(buff, 1, compressedSize, modifiedBin)) != compressedSize){

fclose(originalBin);
fclose(modifiedBin);
unlink(MODIFIEDBIN);
fprintf(stderr, "\nERROR: Writing File (encode buffer).\n");
return 0;

}

memcpy(&headerTemplate[40 + ( i * 52) + 48], &compressedSize, 4);

free(buff);
free(decodedPNG);

SetConsoleTextAttribute(hConsole, INVERSE(__INFO_));

if((width != old[i].width) || (height != old[i].height)){

SetConsoleTextAttribute(hConsole, WARNING);
resolutionChanges++;
memcpy(&headerTemplate[40 + ( i * 52) + 32], &width , 4);
memcpy(&headerTemplate[40 + ( i * 52) + 36], &height, 4);

}

printf("\r %2d.%-32s %4d x %-4d %10d %10d %12d \n", i + 1, old[i].name, width, height, offset, compressedSize, rawBytes);

}
}

uint8_t l = 0;

for(l = 0; l < 85; l++){

printf("%c", 196);

}

printf("\n");

SetConsoleTextAttribute(hConsole, COLOR);

if (resolutionChanges){
BLANKLINE;
SetConsoleTextAttribute(hConsole, WARNING);

if (resolutionChanges == 1){

printf("The Resolution Changed With The Image In Red! It has been newly encoded. \n");

} else {

printf("The Resolution Changed With The %d Images In Red!They have been newly encoded. ", resolutionChanges);

if(resolutionChanges < 10){

printf(" \n");

} else {

printf("\n");

}

}

printf("IT MAY NOT BE SAFE TO FLASH THIS FILE!! \n");
printf("PLEASE KNOW WHAT YOU ARE DOING!! \n");

SetConsoleTextAttribute(hConsole, COLOR);
BLANKLINE;

} else {

printf("SUCCESS!! \n");
printf("You Can Flash The File 'Modified-SPLASH.bin' in fastboot. \n");

}

fseek(modifiedBin, 0, SEEK_SET);

if((fwrite(headerTemplate, 1, headerSize, modifiedBin)) != headerSize){

fclose(modifiedBin);
unlink(MODIFIEDBIN);
fclose(originalBin);

}

free(headerTemplate);
modifiedSize = GetSize(modifiedBin);
SetConsoleTextAttribute(hConsole, __INFO_);
printf(" %c", 218);
for(l = 0; l < 38; l++){
printf("%c", 196);
}
printf("%c \n", 191);

printf(" %cOriginal Size: %8d bytes, %4.2f MB%c \n", 179, originalSize, (float)originalSize/(float)1024/(float)1024, 179);
printf(" %cModified Size: %8d bytes, %4.2f MB%c \n", 179, modifiedSize, (float)modifiedSize/(float)1024/(float)1024, 179);
printf(" %c", 192);
for(i = 0; i < 38; i++){
printf("%c", 196);
}
printf("%c \n", 217);

BLANKLINE;
printf(" Press and key to exit...... \n");
fclose(modifiedBin);
fclose(originalBin);
return 1;
}

void FinishLineSpaces(uint8_t alreadyTaken){

uint8_t a = 1;

for (a = 1; a < SCREENWIDTH - alreadyTaken; a++){
printf(" ");
}
printf("\n");

}

int8_t CheckBinOffsets(FILE *modifiedFile){

uint32_t numberOfImages = 0;
uint32_t i = 0;
uint16_t data = 0;
const uint16_t magic = 0x8b1f;
uint32_t offset = 0, match = 0;

fseek(modifiedFile, 36, SEEK_SET);

if((fread(&numberOfImages, 1, 4, modifiedFile)) != 4){

fprintf(stderr, "\nERROR: Reading File (check bin offsets).\n");
return -1;

}

for(i = 0; i < numberOfImages ; i++){

fseek(modifiedFile, 40 + (i * 52) + 44, SEEK_SET);

if((fread(&offset, 1, 4, modifiedFile)) != 4){

fprintf(stderr, "\nERROR: Reading File (offset).\n");
return -1;

}

fseek(modifiedFile, offset, SEEK_SET);

if((fread(&data , 1, 2, modifiedFile)) != 2){

fprintf(stderr, "\nERROR: Reading File (two byte header).\n");
return -1;

}

if(data == magic){match++;}
}

return match - numberOfImages;
}

int32_t main(int32_t argc, char **argv){

int32_t c;
uint8_t numberOfImages = 0, brute = 0;
uint8_t splash[32] = {0};
uint8_t *path = NULL, *inputFile = NULL, *build = NULL;
FILE *input = NULL;
uint8_t command[512];

HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);

CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
CONSOLE_CURSOR_INFO cursor;
cursor.dwSize = 1;
cursor.bVisible = FALSE;
SetConsoleCursorInfo(hConsole, &cursor);
WORD originalColor;
GetConsoleScreenBufferInfo(hConsole, &consoleInfo);
originalColor = consoleInfo.wAttributes;
SetConsoleTextAttribute(hConsole, COLOR);

DrawHead();

while ((c = getopt (argc, (char**)argv, "i:I:p:P:b:B:n:N")) != -1){

switch(c)
{
case 'i':
case 'I':
inputFile = (uint8_t*)optarg;
break;

case 'p':
case 'P':
path = (uint8_t*)optarg;
break;

case 'b':
build = (uint8_t*)optarg;
break;

case 'B':
build = (uint8_t*)optarg;
brute = 1;
break;

case 'n':
case 'N':
numberOfImages = atoi(optarg);
break;

}
}

if(build){

int ret = BuildImages(build, numberOfImages, brute, hConsole);

if(ret){

FILE *modifiedBin = NULL;

if ((modifiedBin = fopen((const char*)MODIFIEDBIN, "rb")) == NULL){

fclose(modifiedBin);
fprintf(stderr, "%s could not be opened.\n", MODIFIEDBIN);
SetConsoleTextAttribute(hConsole, originalColor);

exit(EXIT_FAILURE);

}

if ((CheckBinOffsets(modifiedBin)) != 0){

fclose(modifiedBin);
fprintf(stderr, "Error in writing offsets.\n");
unlink(MODIFIEDBIN);
ret = 0;

}
}

SetConsoleTextAttribute(hConsole, originalColor);
return ret;

}

if((input = fopen((const char*)inputFile, "rb")) == NULL){

fprintf(stderr, "%s cound not be opened to read.", inputFile);
SetConsoleTextAttribute(hConsole, originalColor);

exit(EXIT_FAILURE);
}

if((fread(&splash, 1, 32, input)) != 32){

fprintf(stderr, "\nERROR: Reading File (splash).\n");
SetConsoleTextAttribute(hConsole, originalColor);

exit(EXIT_FAILURE);
}

uint8_t *data = NULL;
uint64_t start = 0, end = 0;

FILE *workingFile = NULL;

sprintf((char*)command,"%s\\%s", path , ORIGINALBIN );

if((workingFile = fopen((const char*)command, "wb")) == NULL){

fclose(workingFile);
fprintf(stderr, "\n%s\\%s could not be opened.\n", path, ORIGINALBIN);
SetConsoleTextAttribute(hConsole, originalColor);

exit(EXIT_FAILURE);

}

if (strncmp((const char*)splash, (const char*)splashHeader, 32) != 0 ){

if ((data = FindSplashFile(input, &start, &end)) != NULL){

fclose(input);

if((fwrite(data, 1 , end - start, workingFile)) != end - start){

fclose(workingFile);
fprintf(stderr, "ERROR: Writing File (cut splash).\n");
SetConsoleTextAttribute(hConsole, originalColor);

exit(EXIT_FAILURE);

}

fclose(workingFile);

if ((workingFile = fopen((const char*)command, "rb")) == NULL){

fclose(workingFile);
fprintf(stderr, "%s could not be opened.\n", command);
SetConsoleTextAttribute(hConsole, originalColor);

exit(EXIT_FAILURE);

}

} else {

printf("No SPLASH2!! header found in file.\n%s\nPress any key to exit.\n", inputFile);

fclose(workingFile);
fclose(input);

SetConsoleTextAttribute(hConsole, originalColor);
exit(EXIT_FAILURE);
}

} else {

uint32_t sizeFile = GetSize(input);

data = (uint8_t*)malloc(sizeFile);

if(data == NULL){

fclose(workingFile);
fclose(input);
fprintf(stderr, "ERROR: Allocating Memory (original splash file copy).\n");
return 0;

}

fseek(input, 0, SEEK_SET);

if((workingFile = fopen((const char*)command, "wb")) == NULL){

fclose(workingFile);
fprintf(stderr, "%s could not be opened.\n", command);
SetConsoleTextAttribute(hConsole, originalColor);

exit(EXIT_FAILURE);

}

if((fread(data, 1, sizeFile, input)) != sizeFile){

fclose(workingFile);
fprintf(stderr,"ERROR: Read Fail (data)\n");
SetConsoleTextAttribute(hConsole, originalColor);

exit(EXIT_FAILURE);

}

if((fwrite(data, 1, sizeFile, workingFile)) != sizeFile){

fclose(workingFile);
fprintf(stderr,"ERROR: Write Fail (data)\n");
SetConsoleTextAttribute(hConsole, originalColor);

exit(EXIT_FAILURE);

}

free(data);
fclose(input);
fclose(workingFile);

if ((workingFile = fopen((const char*)command, "rb")) == NULL){

fclose(workingFile);
fprintf(stderr, "%s could not be opened.\n", command);
SetConsoleTextAttribute(hConsole, originalColor);

exit(EXIT_FAILURE);

}

}
if ((CheckBinOffsets(workingFile)) != 0){

fclose(workingFile);
fprintf(stderr, "Initial offset check revealed invalid magic numbers.\n");
SetConsoleTextAttribute(hConsole, originalColor);

exit(EXIT_FAILURE);
}

if (decode(workingFile, path, hConsole)){
sprintf((char*)command, "start \"\" \"%s\\\"", path);
system((const char*)command);

}
printf("Press and key to exit...... \n");

SetConsoleTextAttribute(hConsole, originalColor);

return EXIT_SUCCESS;

}

Nexus6Pcodec.h

#define PATTERN 5
#define SCREENWIDTH 86
#define BACKGROUNDCOLOR 0x00
#define MERGEBACKGROUND(x) ((BACKGROUNDCOLOR & 0xf0) | (x & 0x0f))
#define COLOR MERGEBACKGROUND(0xbb)
#define TOPCOLOR MERGEBACKGROUND(0xbb)
#define TOPTEXTCOLOR MERGEBACKGROUND(0Xbb)
#define BLUE MERGEBACKGROUND(0x09)
#define RED MERGEBACKGROUND(0x0c)
#define YELLOW MERGEBACKGROUND(0x0e)
#define GREEN MERGEBACKGROUND(0x0a)
#define WARNING 0xcf
#define __INFO_ MERGEBACKGROUND(0xaa)
#define __HIGHLIGHT_ MERGEBACKGROUND(0xee)

#define SIZEOFLONGINT 4
#define MODIFIEDBIN "Modified-SPLASH.bin"
#define ORIGINALBIN "Original-SPLASH.bin"
#define IMAGES_DIR "Images"
#define BLOCKSIZE 512
#define SWAP32(x) (( x >> 24 )&0xff) | ((x << 8)&0xff0000) | ((x >> 8)&0xff00) | ((x << 24)&0xff000000)
#define INVERSE(x) ( (x & 0x0F)<<4 | (x & 0xF0)>>4 )
#define BLANKLINE printf(" \n")
#define UNDERSCORE printf("_____________________________________________________________________________________\n")

typedef struct {
uint8_t name[33];
uint32_t width;
uint32_t height;
uint32_t bpp;
uint32_t offset;
uint32_t size;
uint8_t gzName[37];
uint32_t time;
uint32_t os;
uint32_t decodedSize;
uint32_t crc32;
uint8_t pathToPNG[512];
} pHeader;

uint8_t *FindSplashFile(FILE*, uint64_t*, uint64_t*);
uint32_t GetSize(FILE*);
void DrawHead(void);
uint8_t *dec(uint8_t*, uint8_t*, uint32_t, uint32_t);
uint8_t *enc(uint8_t*, uint32_t, uint8_t*, uint32_t, int, uint32_t*);
int decode(FILE*, const uint8_t*, HANDLE);
pHeader *ReadID(FILE*, uint8_t);
uint32_t GetWidth(FILE*);
uint32_t GetHeight(FILE*);
int BuildImages(uint8_t*, uint8_t, uint8_t, HANDLE);
void FinishLineSpaces(uint8_t);
int8_t CheckBinOffsets(FILE*);
int32_t main(int32_t, char**);

gz_header gzNewHeaderp;
uint8_t version[] = "1.1";

const uint8_t splashHeader[] = "SPLASH2!!\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";

uint8_t *dec(uint8_t *source, uint8_t *dest, uint32_t srclen, uint32_t dstlen){

int rtn;

z_stream zStream = {0};
zStream.zalloc = Z_NULL;
zStream.zfree = Z_NULL;
zStream.opaque = Z_NULL;
zStream.total_in = zStream.avail_in = srclen;
zStream.total_out = zStream.avail_out = dstlen;
zStream.next_in = (uint8_t*)source;
zStream.next_out = (uint8_t*)dest;

rtn = inflateInit2(&zStream, 16 + MAX_WBITS);

if (rtn != Z_OK){
fprintf(stderr, "Error: Initialising Decoder\n");
(void)inflateEnd(&zStream);
return NULL;
}

rtn = inflateGetHeader(&zStream, &gzNewHeaderp);

if (rtn != Z_OK){
fprintf(stderr, "Error: Reading Header\n");
(void)inflateEnd(&zStream);
return NULL;
}

rtn = inflate(&zStream, Z_FINISH);

if (rtn != Z_STREAM_END){
fprintf(stderr, "Error: Decoding\n");
(void)inflateEnd(&zStream);
return NULL;
}

(void)inflateEnd(&zStream);

return dest;
}

uint8_t *enc(uint8_t *source, uint32_t srclen , uint8_t *dest, uint32_t dstlen, int level, uint32_t *compressedSize){

int rtn;

z_stream zStream = {0};
zStream.total_in = zStream.avail_in = srclen;
zStream.total_out = zStream.avail_out = dstlen;
zStream.next_in = (uint8_t*)source;
zStream.next_out = dest;
zStream.zalloc = Z_NULL;
zStream.zfree = Z_NULL;
zStream.opaque = Z_NULL;

rtn = deflateInit2(&zStream, level, Z_DEFLATED, 16 + MAX_WBITS, 8, Z_DEFAULT_STRATEGY);

if (rtn != Z_OK){
fprintf(stderr, "Error: Initialising Encoder\n");
(void)deflateEnd(&zStream);
return NULL;
}

rtn = deflateSetHeader(&zStream, &gzNewHeaderp);

if (rtn != Z_OK){
fprintf(stderr, "Error: Writing Header\n");
(void)deflateEnd(&zStream);
return NULL;
}

rtn = deflate(&zStream, Z_FINISH);

if (rtn != Z_STREAM_END){
fprintf(stderr, "Error: Encoding\n");
(void)deflateEnd(&zStream);
return NULL;
}

*compressedSize = zStream.total_out;
(void)deflateEnd(&zStream);

return dest;
}