From 31bb486c913795c8b67d1c4dbaae2bdec4943fc9 Mon Sep 17 00:00:00 2001 From: raywu Date: Thu, 13 Sep 2018 16:11:56 +0800 Subject: SLP1.0 / SLP2.0 / Default Password / Logo / Fix Boot Order --- EDK/MiniSetup/TseAdvanced/png.c | 1353 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 1353 insertions(+) create mode 100644 EDK/MiniSetup/TseAdvanced/png.c (limited to 'EDK/MiniSetup/TseAdvanced/png.c') diff --git a/EDK/MiniSetup/TseAdvanced/png.c b/EDK/MiniSetup/TseAdvanced/png.c new file mode 100644 index 0000000..b2abf2e --- /dev/null +++ b/EDK/MiniSetup/TseAdvanced/png.c @@ -0,0 +1,1353 @@ +//*****************************************************************// +//*****************************************************************// +//*****************************************************************// +//** **// +//** (C)Copyright 2011, American Megatrends, Inc. **// +//** **// +//** All Rights Reserved. **// +//** **// +//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **// +//** **// +//** Phone (770)-246-8600 **// +//** **// +//*****************************************************************// +//*****************************************************************// +//*****************************************************************// +// $Archive: /Alaska/SOURCE/Modules/AMITSE2_0/AMITSE/TseAdvanced/png.c $ +// +// $Author: Arunsb $ +// +// $Revision: 3 $ +// +// $Date: 10/18/12 5:53a $ +// +//*****************************************************************// +//*****************************************************************// +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/AMITSE2_0/AMITSE/TseAdvanced/png.c $ +// +// 3 10/18/12 5:53a Arunsb +// Updated for 2.16.1235 QA submission +// +// 2 10/10/12 12:35p Arunsb +// Synched the source for v2.16.1232, backup with Aptio +// +// 2 6/20/11 1:20p Rajashakerg +// [TAG] EIP60910 +// [Description] Updated with respect to the review comments. +// +// 1 6/13/11 12:21p Rajashakerg +// EIP:60910 -PNG image support in TSE. +// +// +//*****************************************************************// +//*****************************************************************// + +// +//---------------------------------------------------------------------------- +// +// Name: png.c +// +// Description: This file contains code for png image handling +// +//---------------------------------------------------------------------------- +// + +#include "minisetup.h" +#include "png.h" +#include EFI_PROTOCOL_DEFINITION(GraphicsOutput) +//--------------------------------------------------------------------------- +// Macros +//--------------------------------------------------------------------------- +#define MakeDword(a,b,c,d) ((a)*0x1000000+(b)*0x10000+(c)*0x100+(d)) +#define IHDR MakeDword('I','H','D','R') +#define IDAT MakeDword('I','D','A','T') +#define PLTE MakeDword('P','L','T','E') +#define IEND MakeDword('I','E','N','D') +#define pHYs MakeDword('p','H','y','s') +#define tRNS MakeDword('t','R','N','S') +#define gAMA MakeDword('g','A','M','A') +#define PNG_SIGNATURE_LENGTH 8 +#define CHUNK_LENGTH 4 +#define CHUNK_TYPE 4 +#define CRC_LENGTH 4 + +static unsigned char *ImageBuffer = (unsigned char *)NULL; + + +// +//---------------------------------------------------------------------------- +// +// Name: PngGetUnsignedInt() +// +// Description: To get decimal values +// +// Input: const unsigned char dat[] +// +// Output: unsigned int +// +//---------------------------------------------------------------------------- +// +unsigned int PngGetUnsignedInt(const unsigned char dat[4]) +{ + return (unsigned)dat[3] + (unsigned)dat[2] * 0x100 + (unsigned)dat[1] * 0x10000 + (unsigned)dat[0] * 0x1000000; +} + +// +//---------------------------------------------------------------------------- +// +// Name: FindImageSize() +// +// Description: To find the PNG image size +// +// Input: none +// +// Output: unsigned int +// +//---------------------------------------------------------------------------- +// +unsigned int FindImageSize() +{ + unsigned char *dwBuf = (unsigned char *)NULL; + UINT32 i = 0; + unsigned int ImageSize = 0; + unsigned int length = 0; + unsigned int chunkType = 0; + + ImageBuffer = ImageBuffer + PNG_SIGNATURE_LENGTH; + dwBuf = (unsigned char *)EfiLibAllocateZeroPool(CHUNK_LENGTH); + if (dwBuf == NULL) { + goto ERREND; + } + ImageSize = PNG_SIGNATURE_LENGTH; + while (chunkType != IEND) //IEND is end of PNG image file + { + for (i = 0; i < CHUNK_LENGTH; i++) { + dwBuf[i] = ImageBuffer[i]; + } + ImageSize = ImageSize + CHUNK_LENGTH; //Adding 4 byte for Chunk Length to move the pointer to Chunk type field + ImageBuffer = ImageBuffer + CHUNK_LENGTH; + + length = PngGetUnsignedInt(dwBuf); + + for (i = 0; i < CHUNK_TYPE; i++) { + dwBuf[i] = ImageBuffer[i]; + } + ImageSize = ImageSize + CHUNK_TYPE; //Adding 4 byte for Chunk type to move the pointer to Chunk data field + ImageBuffer = ImageBuffer + CHUNK_TYPE; + + chunkType = PngGetUnsignedInt(dwBuf); + ImageSize = ImageSize + length + CRC_LENGTH; //Adding Chunk data length and CRC length to move the pointer to next Chunk + ImageBuffer = ImageBuffer + length + CRC_LENGTH; + } + if (dwBuf) { + MemFreePointer(&dwBuf); + } + + return ImageSize; +ERREND: + return 0; +} + +// +//---------------------------------------------------------------------------- +// +// Name: Header_Decode() +// +// Description: To Store the header values in the PngHeader variables +// +// Input: unsigned char dat[] +// +// Output: none +// +//---------------------------------------------------------------------------- +// +void Header_Decode(unsigned char dat[]) +{ + gPng_Info.hdr.width = PngGetUnsignedInt(dat); + gPng_Info.hdr.height = PngGetUnsignedInt(dat+4); + gPng_Info.hdr.bitDepth = dat[8]; // Storing IHDR values in PngHeader structure + gPng_Info.hdr.colorType = dat[9]; + gPng_Info.hdr.compressionMethod = dat[10]; + gPng_Info.hdr.filterMethod = dat[11]; + gPng_Info.hdr.interlaceMethod = dat[12]; +} + +// +//---------------------------------------------------------------------------- +// +// Name: Palette_Decode() +// +// Description: To store the PLTE data values in PngPalette variables +// +// Input: unsigned length,unsigned char dat[] +// +// Output: int +// +//---------------------------------------------------------------------------- +// +EFI_STATUS Palette_Decode(unsigned length, unsigned char dat[]) +{ + if (length%3 != 0) //PLTE Length should be divisable by three + { + return EFI_UNSUPPORTED; + } + + if (gPng_Info.plt.entry != NULL) + { + MemFreePointer(&gPng_Info.plt.entry); + gPng_Info.plt.nEntry = 0; + } + + if (length > 0) + { + gPng_Info.plt.entry = (unsigned char *)EfiLibAllocateZeroPool(length); + if (gPng_Info.plt.entry != NULL) + { + unsigned int i; + gPng_Info.plt.nEntry = length/3; + for (i = 0; i < length; i++) + { + gPng_Info.plt.entry[i] = dat[i]; + } + } + } + + return EFI_SUCCESS; +} + +// +//---------------------------------------------------------------------------- +// +// Name: Transparency_Decode() +// +// Description: To store the tRNS data values in PngPalette variables +// +// Input: unsigned int length,unsigned char dat[],unsigned int colorType +// +// Output: int +// +//---------------------------------------------------------------------------- +// +EFI_STATUS Transparency_Decode(unsigned int length, unsigned char dat[], unsigned int colorType) +{ + unsigned int i; + switch (colorType) //See PNG specification for the color Types + { + case 0: + if (length >= 2) + { + gPng_Info.trns.col[0] = (unsigned int)dat[0] * 256 + (unsigned int)dat[1]; + return EFI_SUCCESS; + } + break; + case 2: + if (length >= 6) + { + gPng_Info.trns.col[0] = (unsigned int)dat[0] * 256 + (unsigned int)dat[1]; + gPng_Info.trns.col[1] = (unsigned int)dat[2] * 256 + (unsigned int)dat[3]; + gPng_Info.trns.col[2] = (unsigned int)dat[4] * 256 + (unsigned int)dat[5]; + return EFI_SUCCESS; + } + break; + case 3: + for (i=0; i < 3 && i < length; i++) + { + gPng_Info.trns.col[i] = dat[i]; + } + return EFI_SUCCESS; + } + return EFI_ABORTED; +} + +// +//---------------------------------------------------------------------------- +// +// Name: Initialize() +// +// Description: to initialize the PngImageDecoder member variables +// +// Input: none +// +// Output: none +// +//---------------------------------------------------------------------------- +// +void Initialize(void) +{ + gPng_Info.gamma = gamma_default; + gPng_Info.trns.col[0] = 0x7fffffff; + gPng_Info.trns.col[1] = 0x7fffffff; + gPng_Info.trns.col[2] = 0x7fffffff; +} + +// +//---------------------------------------------------------------------------- +// +// Name: ReadChunk() +// +// Description: To Read all the chunk data +// +// Input: unsigned &length,unsigned char *&buf,unsigned &chunkType,unsigned &crc +// +// Output: int +// +//---------------------------------------------------------------------------- +// +EFI_STATUS ReadChunk(unsigned *length, unsigned char **buf, unsigned *chunkType, unsigned *crc) +{ + unsigned char *dwBuf = (unsigned char *)NULL; + UINT32 i = 0; + EFI_STATUS Status = EFI_SUCCESS; + + dwBuf = (unsigned char *)EfiLibAllocateZeroPool(4); + if (dwBuf == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto EndRead; + } + for (i = 0; i < 4; i++) { + dwBuf[i] = ImageBuffer[i]; + } + ImageBuffer = ImageBuffer + CHUNK_LENGTH; //Adding 4 byte for Chunk Length to move the pointer to Chunk type field + + *length = PngGetUnsignedInt(dwBuf); + + for (i = 0; i < 4; i++) { + dwBuf[i] = ImageBuffer[i]; + } + ImageBuffer = ImageBuffer + CHUNK_TYPE; //Adding 4 byte for Chunk type to move the pointer to Chunk data field + + *chunkType = PngGetUnsignedInt(dwBuf); + + if(*length > 0) + { + *buf = (unsigned char *)EfiLibAllocateZeroPool(*length); + if (*buf == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto EndRead; + } + for (i = 0; i < *length; i++) { + (*buf)[i] = ImageBuffer[i]; + } + } + else + { + *buf = (unsigned char *)NULL; + } + ImageBuffer = ImageBuffer + *length; //Adding Chunk data length to move the pointer to CRC field + + for (i = 0; i < 4; i++) { + dwBuf[i] = ImageBuffer[i]; + } + ImageBuffer = ImageBuffer + CRC_LENGTH; //Adding 4 byte for CRC length to move the pointer to next Chunk + + *crc = PngGetUnsignedInt(dwBuf); + +EndRead: + + if (dwBuf) { //Fix for Fortify issue - Memory Leak + MemFreePointer(&dwBuf); + } + + return Status; +} + +// +//---------------------------------------------------------------------------- +// +// Name: Decode() +// +// Description: Read all the PNG chunks and do convert the png format to RGB format. +// +// Input: unsigned char *PNGImage,UINT32 PNGImageSize +// +// Output: int +// +//---------------------------------------------------------------------------- +// +EFI_STATUS Decode(unsigned char *PNGImage, UINT32 PNGImageSize) +{ + unsigned char *datBuf = (unsigned char *)NULL; + unsigned datBufUsed; + unsigned char *buf; + unsigned length,chunkType,crc; + + if (PNGImage) + { + ImageBuffer = PNGImage; + PNGImageSize = FindImageSize(); //Find the png image size if the PNGImageSize is zero + + datBufUsed = 0; + datBuf = (unsigned char *)EfiLibAllocateZeroPool(PNGImageSize); + if (datBuf == NULL) { + goto ERREND; + } + + ImageBuffer = PNGImage + PNG_SIGNATURE_LENGTH; //Adding 8 bytes to move the pointer to Chunk length + while (ReadChunk(&length,&buf,&chunkType,&crc) == EFI_SUCCESS && chunkType != IEND) //Read the Chunk data upto IEND(End of the PNG image) + { + if(buf == NULL){ + break; //If the buffer is invalid, break from the loop + } + switch (chunkType) + { + case IHDR: + if (length >= 13) + { + Header_Decode(buf); //Stores the IHDR values in the PngHeader structure + } + MemFreePointer(&buf); + break; + case PLTE: + if (Palette_Decode(length,buf)) //Stores the PLTE values in the PngPalette structure + { + MemFreePointer(&buf); + goto ERREND; + } + MemFreePointer(&buf); + break; + case tRNS: + if (Transparency_Decode(length,buf,gPng_Info.hdr.colorType)) //Stores the tRNS values in the PngTransparency structure + { + MemFreePointer(&buf); + goto ERREND; + } + MemFreePointer(&buf); + break; + case gAMA: + if(length >= 4) + { + gPng_Info.gamma = PngGetUnsignedInt(buf); //Stores the gAMA chunk values + MemFreePointer(&buf); + } + break; + case IDAT: + if (buf != NULL) + { + unsigned i; + for (i = 0; i < length; i++) + { + datBuf[datBufUsed+i] = buf[i]; //Stores the IDAT chunk value in datbuf[] + } + datBufUsed += length; //datBufUsed used to store consecutive IDAT chunk sequentialy + MemFreePointer(&buf); + } + break; + default: + MemFreePointer(&buf); //Modified to remove the fortify warning + break; + } + } + + if (PrepareOutput() == EFI_SUCCESS) // Check the combination of Color type and bit debth + { + //PngUncompressor uncompressor; + //uncompressor.output = this; + if (Uncompress(datBufUsed,datBuf)) { //Convert the PNG image data into the RGB format in PngImageDecoder.rgba variable + goto ERREND; + } + } else { + goto ERREND; + } + + MemFreePointer(&datBuf); + return EFI_SUCCESS; + } + +ERREND: + if (datBuf) { + MemFreePointer(&datBuf); + } + return EFI_ABORTED; +} + +// +//---------------------------------------------------------------------------- +// +// Name: Paeth() +// +// Description: +// +// Input: unsigned int ua,unsigned int ub,unsigned int uc +// +// Output: unsigned char +// +//---------------------------------------------------------------------------- +// +unsigned char Paeth(unsigned int ua,unsigned int ub,unsigned int uc) +{ + int a,b,c,p,pa,pb,pc; + + a = (int)ua; + b = (int)ub; + c = (int)uc; + + p = a + b - c; + pa = (p>a ? p-a : a-p); //Paeth filtering as per the PNG Specification + pb = (p>b ? p-b : b-p); + pc = (p>c ? p-c : c-p); + + if (pa <= pb && pa <= pc) + { + return (unsigned char)a; //Fix for Fortify issue - Type Mismatch : Signed to Unsigned + } + else if(pb <= pc) + { + return (unsigned char)b; //Fix for Fortify issue - Type Mismatch : Signed to Unsigned + } + else + { + return (unsigned char)c; //Fix for Fortify issue - Type Mismatch : Signed to Unsigned + } +} + +// +//---------------------------------------------------------------------------- +// +// Name: Filter8() +// +// Description: +// +// Input: unsigned char curLine[],unsigned char prvLine[],int x,int y,int unitLng,int filter +// +// Output: none +// +//---------------------------------------------------------------------------- +// +void Filter8(unsigned char curLine[],unsigned char prvLine[],int x,int y,int unitLng,int filter) +{ + int i; + switch (filter) //filtering algorithm + { + case 1: + if (x > 0) + { + for (i = 0; i < unitLng; i++) + { + curLine[ x * unitLng + i] = curLine[ x * unitLng + i] + curLine[ x * unitLng + i - unitLng]; + } + } + break; + case 2: + if (y > 0) + { + for (i = 0; i < unitLng; i++) + { + curLine[x * unitLng + i] = curLine[x * unitLng + i] + prvLine[ x * unitLng + i]; + } + } + break; + case 3: + for (i = 0; i < unitLng; i++) + { + unsigned int a; + a = (x > 0 ? curLine[x * unitLng + i - unitLng] : 0); + a += (y > 0 ? prvLine[x * unitLng + i] : 0); + curLine[x * unitLng + i] += (unsigned char)a / 2; + } + break; + case 4: + for (i = 0; i < unitLng; i++) + { + unsigned int a,b,c; + a = (x > 0 ? curLine[x * unitLng + i - unitLng] : 0); + b = (y > 0 ? prvLine[x * unitLng + i] : 0); + c = ((x > 0 && y > 0) ? prvLine[x * unitLng - unitLng + i] : 0); + curLine[x * unitLng + i] = curLine[x * unitLng + i] + Paeth(a,b,c); + } + break; + } +} + +// +//---------------------------------------------------------------------------- +// +// Name: ShiftTwoLineBuf() +// +// Description: +// +// Input: none +// +// Output: none +// +//---------------------------------------------------------------------------- +// +void ShiftTwoLineBuf(void) +{ + if (gPng_Info.twoLineBuf8 != NULL) + { + unsigned char *swap; + swap = gPng_Info.curLine8; + gPng_Info.curLine8 = gPng_Info.prvLine8; + gPng_Info.prvLine8 = swap; + } +} + +// +//---------------------------------------------------------------------------- +// +// Name: PrepareOutput() +// +// Description: To validate the colorType and bitDepth combination and prepare the output data +// +// Input: none +// +// Output: int +// +//---------------------------------------------------------------------------- +// +EFI_STATUS PrepareOutput(void) +{ + int supported; + unsigned int twoLineBufLngPerLine = 0; + + supported = 0; + switch ( gPng_Info.hdr.colorType) + { + case 0: // Greyscale + switch (gPng_Info.hdr.bitDepth) + { + case 8: + case 1: + supported = 1; + break; + case 2: + case 4: + case 16: + break; + } + break; + case 2: // Truecolor + switch (gPng_Info.hdr.bitDepth) + { + case 8: + case 16: + supported = 1; + break; + } + break; + case 3: // Indexed-color + switch (gPng_Info.hdr.bitDepth) + { + case 4: + case 8: + supported = 1; + break; + case 1: + case 2: + break; + } + break; + case 4: // Greyscale with alpha + switch (gPng_Info.hdr.bitDepth) + { + case 8: + supported = 1; + break; + case 16: + break; + } + break; + case 6: // Truecolor with alpha + switch (gPng_Info.hdr.bitDepth) + { + case 8: + supported = 1; + break; + case 16: + break; + } + break; + } + + if (supported == 0) + { + return EFI_UNSUPPORTED; + } + + gPng_Info.wid = gPng_Info.hdr.width; + gPng_Info.hei =gPng_Info.hdr.height; + if(gPng_Info.autoDeleteRgbaBuffer == 1 && gPng_Info.rgba != NULL) + { + MemFreePointer(&gPng_Info.rgba); + gPng_Info.rgba = (unsigned char *)NULL; + } + gPng_Info.rgba = (unsigned char *)EfiLibAllocateZeroPool(gPng_Info.wid * gPng_Info.hei * 4); + gPng_Info.x = -1; + gPng_Info.y = 0; + gPng_Info.filter = 0; + gPng_Info.inLineCount = 0; + gPng_Info.inPixelCount = 0; + gPng_Info.firstByte = 1; + gPng_Info.index = 0; + gPng_Info.interlacePass = 1; + + if (gPng_Info.twoLineBuf8 != NULL) + { + MemFreePointer(&gPng_Info.twoLineBuf8); + } + + + switch (gPng_Info.hdr.colorType) + { + case 0: // Greyscale + switch(gPng_Info.hdr.bitDepth) + { + case 1: + twoLineBufLngPerLine = (gPng_Info.hdr.width + 7) /8; + break; + case 2: + twoLineBufLngPerLine = (gPng_Info.hdr.width + 3) / 4; + break; + case 4: + twoLineBufLngPerLine = (gPng_Info.hdr.width + 1) / 2; + break; + case 8: + twoLineBufLngPerLine = gPng_Info.hdr.width; + break; + case 16: + twoLineBufLngPerLine = gPng_Info.hdr.width * 2; + break; + } + break; + case 2: // Truecolor + switch (gPng_Info.hdr.bitDepth) + { + case 8: + twoLineBufLngPerLine = gPng_Info.hdr.width * 3; + break; + case 16: + twoLineBufLngPerLine = gPng_Info.hdr.width * 6; + break; + } + break; + case 3: // Indexed-color + switch (gPng_Info.hdr.bitDepth) + { + case 1: + twoLineBufLngPerLine = (gPng_Info.hdr.width + 7) / 8; + break; + case 2: + twoLineBufLngPerLine = (gPng_Info.hdr.width + 3) / 4; + break; + case 4: + twoLineBufLngPerLine = (gPng_Info.hdr.width + 1) / 2; + break; + case 8: + twoLineBufLngPerLine = gPng_Info.hdr.width; + break; + } + break; + case 4: // Greyscale with alpha + switch (gPng_Info.hdr.bitDepth) + { + case 8: + twoLineBufLngPerLine = gPng_Info.hdr.width * 2; + break; + case 16: + twoLineBufLngPerLine = gPng_Info.hdr.width * 4; + break; + } + break; + case 6: // Truecolor with alpha + switch (gPng_Info.hdr.bitDepth) + { + case 8: + twoLineBufLngPerLine = gPng_Info.hdr.width * 4; + break; + case 16: + twoLineBufLngPerLine = gPng_Info.hdr.width * 8; + break; + } + break; + } + + gPng_Info.twoLineBuf8 = (unsigned char *) EfiLibAllocateZeroPool(twoLineBufLngPerLine*2); + gPng_Info.curLine8 = gPng_Info.twoLineBuf8; + gPng_Info.prvLine8 = gPng_Info.twoLineBuf8 + twoLineBufLngPerLine; + + return EFI_SUCCESS; +} + +// +//---------------------------------------------------------------------------- +// +// Name: Output() +// +// Description: To create the output values in the RGB format. +// +// Input: unsigned char dat +// +// Output: int +// +//---------------------------------------------------------------------------- +// +EFI_STATUS Output(unsigned char dat) +{ + unsigned int i; + unsigned int colIdx; + unsigned int interlaceWid,interlaceHei,interlaceX,interlaceY; + + if (gPng_Info.y >= gPng_Info.hei || (gPng_Info.rgba == NULL)) + { + return EFI_UNSUPPORTED; + } + + if (gPng_Info.x == -1) // First byte is filter type for the line. + { + gPng_Info.filter = dat; // See PNG Specification for filtering + gPng_Info.inLineCount = 0; + gPng_Info.inPixelCount = 0; + gPng_Info.x++; + return EFI_SUCCESS; + } + else + { + switch (gPng_Info.hdr.interlaceMethod) + { + case 0: // Non-Interlace + switch (gPng_Info.hdr.colorType) // See PNG Specification for colortype and values + { + case 0: // Grayscale + switch (gPng_Info.hdr.bitDepth) + { + case 1: + gPng_Info.curLine8[gPng_Info.x/8] = dat; + Filter8(gPng_Info.curLine8, gPng_Info.prvLine8, gPng_Info.x/8, gPng_Info.y, 1, gPng_Info.filter); + + for (i = 0; i < 8 && gPng_Info.x < gPng_Info.wid; i++) + { + colIdx = (gPng_Info.curLine8[gPng_Info.x/8] >> (7 - i))&1; + colIdx = (colIdx << 1) + colIdx; + colIdx = (colIdx << 2) + colIdx; + colIdx = (colIdx << 4) + colIdx; + + gPng_Info.rgba[gPng_Info.index] = (char)colIdx; + gPng_Info.rgba[gPng_Info.index+1] = (char)colIdx; + gPng_Info.rgba[gPng_Info.index+2] = (char)colIdx; + gPng_Info.rgba[gPng_Info.index+3] = 0; + gPng_Info.x++; + gPng_Info.index += 4; + } + break; + + case 8: + gPng_Info.curLine8[gPng_Info.x] = dat; + Filter8(gPng_Info.curLine8, gPng_Info.prvLine8, gPng_Info.x, gPng_Info.y, 1, gPng_Info.filter); + + gPng_Info.rgba[gPng_Info.index] = gPng_Info.curLine8[gPng_Info.x]; + gPng_Info.rgba[gPng_Info.index+1] = gPng_Info.curLine8[gPng_Info.x]; + gPng_Info.rgba[gPng_Info.index+2] = gPng_Info.curLine8[gPng_Info.x]; + if (gPng_Info.curLine8[gPng_Info.x] == gPng_Info.trns.col[0] || gPng_Info.curLine8[gPng_Info.x] == gPng_Info.trns.col[1] || gPng_Info.curLine8[gPng_Info.x] == gPng_Info.trns.col[2]) + { + gPng_Info.rgba[gPng_Info.index+3] = 0; + } + else + { + gPng_Info.rgba[gPng_Info.index+3] = 255; + } + + gPng_Info.x++; + gPng_Info.index += 4; + break; + } + break; + + case 2: //True color + switch (gPng_Info.hdr.bitDepth) + { + case 8: + gPng_Info.curLine8[gPng_Info.inLineCount+gPng_Info.inPixelCount] = dat; + gPng_Info.inPixelCount++; + if (gPng_Info.inPixelCount == 3) + { + Filter8(gPng_Info.curLine8, gPng_Info.prvLine8, gPng_Info.x,gPng_Info.y, 3, gPng_Info.filter); + gPng_Info.rgba[gPng_Info.index] = gPng_Info.curLine8[gPng_Info.inLineCount]; + gPng_Info.rgba[gPng_Info.index+1] = gPng_Info.curLine8[gPng_Info.inLineCount+1]; + gPng_Info.rgba[gPng_Info.index+2] = gPng_Info.curLine8[gPng_Info.inLineCount+2]; + + if (gPng_Info.curLine8[gPng_Info.inLineCount] == gPng_Info.trns.col[0] && + gPng_Info.curLine8[gPng_Info.inLineCount+1] == gPng_Info.trns.col[1] && + gPng_Info.curLine8[gPng_Info.inLineCount+2] == gPng_Info.trns.col[2]) + { + gPng_Info.rgba[gPng_Info.index+3] = 0; + } + else + { + gPng_Info.rgba[gPng_Info.index+3] = 255; + } + + gPng_Info.x++; + gPng_Info.index += 4; + gPng_Info.inLineCount += 3; + gPng_Info.inPixelCount = 0; + } + break; + case 16: + gPng_Info.curLine8[gPng_Info.inLineCount+gPng_Info.inPixelCount] = dat; + gPng_Info.inPixelCount++; + if (gPng_Info.inPixelCount == 6) + { + Filter8(gPng_Info.curLine8, gPng_Info.prvLine8, gPng_Info.x, gPng_Info.y, 6, gPng_Info.filter); + gPng_Info.rgba[gPng_Info.index] =gPng_Info. curLine8[gPng_Info.inLineCount]; + gPng_Info.rgba[gPng_Info.index+1] = gPng_Info.curLine8[gPng_Info.inLineCount+2]; + gPng_Info.rgba[gPng_Info.index+2] = gPng_Info.curLine8[gPng_Info.inLineCount+4]; + + gPng_Info.r = gPng_Info.curLine8[gPng_Info.inLineCount] * 256 + gPng_Info.curLine8[gPng_Info.inLineCount+1]; + gPng_Info.g = gPng_Info.curLine8[gPng_Info.inLineCount+2] * 256 + gPng_Info.curLine8[gPng_Info.inLineCount+3]; + gPng_Info.b = gPng_Info.curLine8[gPng_Info.inLineCount+4] * 256 + gPng_Info.curLine8[gPng_Info.inLineCount+5]; + if (gPng_Info.r == gPng_Info.trns.col[0] && gPng_Info.g == gPng_Info.trns.col[1] && gPng_Info.b == gPng_Info.trns.col[2]) + { + gPng_Info.rgba[gPng_Info.index+3] = 0; + } + else + { + gPng_Info.rgba[gPng_Info.index+3] = 255; + } + gPng_Info.x++; + gPng_Info.index += 4; + gPng_Info.inLineCount += 6; + gPng_Info.inPixelCount = 0; + } + break; + } + break; + + case 3: // Indexed color + switch (gPng_Info.hdr.bitDepth) + { + case 4: + gPng_Info.curLine8[gPng_Info.x/2] = dat; + Filter8(gPng_Info.curLine8, gPng_Info.prvLine8, gPng_Info.x/2, gPng_Info.y, 1, gPng_Info.filter); + + for (i = 0; i<2 && gPng_Info.x < gPng_Info.wid; i++) + { + colIdx = (gPng_Info.curLine8[gPng_Info.x/2] >> ((1 - i) * 4))&0x0f; + + if (colIdx < gPng_Info.plt.nEntry) + { + gPng_Info.rgba[gPng_Info.index] = gPng_Info.plt.entry[colIdx*3]; + gPng_Info.rgba[gPng_Info.index+1] = gPng_Info.plt.entry[colIdx*3+1]; + gPng_Info.rgba[gPng_Info.index+2] = gPng_Info.plt.entry[colIdx*3+2]; + if (colIdx == gPng_Info.trns.col[0] || colIdx == gPng_Info.trns.col[1] || colIdx == gPng_Info.trns.col[2]) + { + gPng_Info.rgba[gPng_Info.index+3] = 0; + } + else + { + gPng_Info.rgba[gPng_Info.index+3] = 255; + } + } + gPng_Info.x++; + gPng_Info.index += 4; + } + break; + + case 8: + gPng_Info.curLine8[gPng_Info.x] = dat; + Filter8(gPng_Info.curLine8, gPng_Info.prvLine8, gPng_Info.x, gPng_Info.y, 1, gPng_Info.filter); + colIdx = gPng_Info.curLine8[gPng_Info.x]; + + if (colIdx < gPng_Info.plt.nEntry) + { + gPng_Info.rgba[gPng_Info.index] = gPng_Info.plt.entry[colIdx*3]; + gPng_Info.rgba[gPng_Info.index+1] = gPng_Info.plt.entry[colIdx*3+1]; + gPng_Info.rgba[gPng_Info.index+2] = gPng_Info.plt.entry[colIdx*3+2]; + if (colIdx == gPng_Info.trns.col[0] || colIdx == gPng_Info.trns.col[1] || colIdx == gPng_Info.trns.col[2]) + { + gPng_Info.rgba[gPng_Info.index+3] = 0; + } + else + { + gPng_Info.rgba[gPng_Info.index+3] = 255; + } + } + gPng_Info.x++; + gPng_Info.index += 4; + break; + } + break; + + case 4: // Greyscale with alpha + switch(gPng_Info.hdr.bitDepth) + { + case 8: + gPng_Info.curLine8[gPng_Info.inLineCount + gPng_Info.inPixelCount] = dat; + gPng_Info.inPixelCount++; + if (gPng_Info.inPixelCount == 2) + { + Filter8(gPng_Info.curLine8, gPng_Info.prvLine8, gPng_Info.x, gPng_Info.y, 2, gPng_Info.filter); + gPng_Info.rgba[gPng_Info.index] = gPng_Info.curLine8[gPng_Info.inLineCount]; + gPng_Info.rgba[gPng_Info.index+1] = gPng_Info.curLine8[gPng_Info.inLineCount]; + gPng_Info.rgba[gPng_Info.index+2] = gPng_Info.curLine8[gPng_Info.inLineCount]; + gPng_Info.rgba[gPng_Info.index+3] = gPng_Info.curLine8[gPng_Info.inLineCount+1]; + gPng_Info.index += 4; + gPng_Info.x++; + gPng_Info.inLineCount += 2; + gPng_Info.inPixelCount = 0; + } + break; + } + break; + + case 6: // Truecolor with alpha + switch(gPng_Info.hdr.bitDepth) + { + case 8: + gPng_Info.curLine8[gPng_Info.inLineCount+gPng_Info.inPixelCount] = dat; + gPng_Info.inPixelCount++; + if (gPng_Info.inPixelCount == 4) + { + Filter8(gPng_Info.curLine8, gPng_Info.prvLine8,gPng_Info.x, gPng_Info.y, 4, gPng_Info.filter); + gPng_Info.rgba[gPng_Info.index] = gPng_Info.curLine8[gPng_Info.inLineCount]; + gPng_Info.rgba[gPng_Info.index+1] = gPng_Info.curLine8[gPng_Info.inLineCount+1]; + gPng_Info.rgba[gPng_Info.index+2] = gPng_Info.curLine8[gPng_Info.inLineCount+2]; + gPng_Info.rgba[gPng_Info.index+3] = gPng_Info.curLine8[gPng_Info.inLineCount+3]; + gPng_Info.index += 4; + gPng_Info.x++; + gPng_Info.inLineCount += 4; + gPng_Info.inPixelCount = 0; + } + break; + } + break; + } // switch(hdr.colorType) + + if (gPng_Info.x >= gPng_Info.wid) + { + gPng_Info.y++; + gPng_Info.x = -1; + ShiftTwoLineBuf(); + } + + return EFI_SUCCESS; + + case 1: // Interlace + // 1 6 4 6 2 6 4 6 + // 7 7 7 7 7 7 7 7 + // 5 6 5 6 5 6 5 6 + // 7 7 7 7 7 7 7 7 + // 3 6 4 6 3 6 4 6 + // 7 7 7 7 7 7 7 7 + // 5 6 5 6 5 6 5 6 + // 7 7 7 7 7 7 7 7 + switch (gPng_Info.interlacePass) + { + case 1: + interlaceWid = (gPng_Info.wid + 7) / 8; + interlaceHei = (gPng_Info.hei + 7) / 8; + interlaceX = gPng_Info.x * 8; + interlaceY = gPng_Info.y * 8; + break; + case 2: + interlaceWid = (gPng_Info.wid + 3) / 8; + interlaceHei = (gPng_Info.hei + 7) / 8; + interlaceX = 4 + gPng_Info.x * 8; + interlaceY = gPng_Info.y * 8; + break; + case 3: + interlaceWid = (gPng_Info.wid + 3) / 4; + interlaceHei = (gPng_Info.hei + 3) / 8; + interlaceX = gPng_Info.x * 4; + interlaceY = 4 + gPng_Info.y * 8; + break; + case 4: + interlaceWid = (gPng_Info.wid + 1) / 4; + interlaceHei = (gPng_Info.hei + 3) / 4; + interlaceX = 2 + gPng_Info.x * 4; + interlaceY = gPng_Info.y * 4; + break; + case 5: + interlaceWid = (gPng_Info.wid + 1) / 2; + interlaceHei = (gPng_Info.hei + 1) / 4; + interlaceX = gPng_Info.x * 2; + interlaceY = 2 + gPng_Info.y * 4; + break; + case 6: + interlaceWid = (gPng_Info.wid) / 2; + interlaceHei = (gPng_Info.hei + 1) / 2; + interlaceX = 1 + gPng_Info.x * 2; + interlaceY = gPng_Info.y * 2; + break; + case 7: + interlaceWid = gPng_Info.wid; + interlaceHei = gPng_Info.hei / 2; + interlaceX = gPng_Info.x; + interlaceY = 1 + gPng_Info.y * 2; + break; + default: + return EFI_UNSUPPORTED; + } // switch(interlacePass) + + switch (gPng_Info.hdr.colorType) // See PNG Specification for Colour types and values + { + case 0: // Grayscale + switch (gPng_Info.hdr.bitDepth) + { + case 8: + gPng_Info.curLine8[gPng_Info.inLineCount] = dat; + Filter8(gPng_Info.curLine8, gPng_Info.prvLine8, gPng_Info.x, gPng_Info.y, 1, gPng_Info.filter); + + gPng_Info.index = interlaceX * 4 + interlaceY * gPng_Info.wid * 4; + gPng_Info.rgba[gPng_Info.index] = gPng_Info.curLine8[gPng_Info.inLineCount]; + gPng_Info.rgba[gPng_Info.index+1] = gPng_Info.curLine8[gPng_Info.inLineCount]; + gPng_Info.rgba[gPng_Info.index+2] = gPng_Info.curLine8[gPng_Info.inLineCount]; + + if (gPng_Info.curLine8[gPng_Info.inLineCount] == gPng_Info.trns.col[0] || + gPng_Info.curLine8[gPng_Info.inLineCount] == gPng_Info.trns.col[1] || + gPng_Info.curLine8[gPng_Info.inLineCount] == gPng_Info.trns.col[2]) + { + gPng_Info.rgba[gPng_Info.index+3] = 0; + } + else + { + gPng_Info.rgba[gPng_Info.index+3] = 255; + } + + gPng_Info.x++; + gPng_Info.inLineCount++; + break; + } + break; + + case 2: // True color + switch (gPng_Info.hdr.bitDepth) + { + case 8: + gPng_Info.curLine8[gPng_Info.inLineCount+gPng_Info.inPixelCount] = dat; + gPng_Info.inPixelCount++; + if (gPng_Info.inPixelCount == 3) + { + Filter8(gPng_Info.curLine8, gPng_Info.prvLine8, gPng_Info.x, gPng_Info.y, 3, gPng_Info.filter); + + gPng_Info.index = interlaceX * 4 + interlaceY * gPng_Info.wid * 4; + gPng_Info.rgba[gPng_Info.index] = gPng_Info.curLine8[gPng_Info.inLineCount]; + gPng_Info.rgba[gPng_Info.index+1] = gPng_Info.curLine8[gPng_Info.inLineCount+1]; + gPng_Info.rgba[gPng_Info.index+2] = gPng_Info.curLine8[gPng_Info.inLineCount+2]; + + if ( gPng_Info.curLine8[ gPng_Info.inLineCount] == gPng_Info.trns.col[0] && + gPng_Info.curLine8[ gPng_Info.inLineCount+1] == gPng_Info.trns.col[1] && + gPng_Info.curLine8[ gPng_Info.inLineCount+2] == gPng_Info.trns.col[2]) + { + gPng_Info.rgba[ gPng_Info.index+3] = 0; + } + else + { + gPng_Info.rgba[ gPng_Info.index+3] = 255; + } + + gPng_Info.x++; + gPng_Info.inLineCount += 3; + gPng_Info.inPixelCount = 0; + } + break; + + case 16: + gPng_Info.curLine8[gPng_Info.inLineCount+gPng_Info.inPixelCount] = dat; + gPng_Info.inPixelCount++; + if (gPng_Info.inPixelCount == 6) + { + Filter8(gPng_Info.curLine8, gPng_Info.prvLine8, gPng_Info.x, gPng_Info.y, 6, gPng_Info.filter); + gPng_Info.index = interlaceX * 4 + interlaceY * gPng_Info.wid * 4; + gPng_Info.rgba[gPng_Info.index] = gPng_Info.curLine8[gPng_Info.inLineCount]; + gPng_Info.rgba[gPng_Info.index+1] = gPng_Info.curLine8[gPng_Info.inLineCount+2]; + gPng_Info.rgba[gPng_Info.index+2] = gPng_Info.curLine8[gPng_Info.inLineCount+4]; + + gPng_Info.r = gPng_Info.curLine8[gPng_Info.inLineCount] * 256 + gPng_Info.curLine8[gPng_Info.inLineCount+1]; + gPng_Info.g = gPng_Info.curLine8[gPng_Info.inLineCount+2] * 256 + gPng_Info.curLine8[gPng_Info.inLineCount+3]; + gPng_Info.b = gPng_Info.curLine8[gPng_Info.inLineCount+4] * 256 + gPng_Info.curLine8[gPng_Info.inLineCount+5]; + + if(gPng_Info.r==gPng_Info.trns.col[0] && gPng_Info.g==gPng_Info.trns.col[1] && gPng_Info.b==gPng_Info.trns.col[2]) + { + gPng_Info.rgba[gPng_Info.index+3] = 0; + } + else + { + gPng_Info.rgba[gPng_Info.index+3] = 255; + } + + gPng_Info.x++; + gPng_Info.inLineCount += 6; + gPng_Info.inPixelCount = 0; + } + break; + } + break; + + case 3: // Indexed color + switch (gPng_Info.hdr.bitDepth) + { + case 8: + gPng_Info.curLine8[gPng_Info.inLineCount] = dat; + Filter8(gPng_Info.curLine8, gPng_Info.prvLine8, gPng_Info.x, gPng_Info.y, 1, gPng_Info.filter); + + gPng_Info.index = interlaceX * 4 + interlaceY *gPng_Info.wid * 4; + colIdx = gPng_Info.curLine8[gPng_Info.inLineCount]; + if (colIdx < gPng_Info.plt.nEntry) + { + gPng_Info.rgba[gPng_Info.index] = gPng_Info.plt.entry[colIdx*3]; + gPng_Info.rgba[gPng_Info.index+1] = gPng_Info.plt.entry[colIdx*3+1]; + gPng_Info.rgba[gPng_Info.index+2] = gPng_Info.plt.entry[colIdx*3+2]; + if (colIdx == gPng_Info.trns.col[0] || colIdx == gPng_Info.trns.col[1] || colIdx == gPng_Info.trns.col[2]) + { + gPng_Info.rgba[gPng_Info.index+3] = 0; + } + else + { + gPng_Info.rgba[gPng_Info.index+3] = 255; + } + } + + gPng_Info.x++; + gPng_Info.inLineCount++; + break; + } + break; + + case 4: // Greyscale with alpha + switch (gPng_Info.hdr.bitDepth) + { + case 8: + gPng_Info.curLine8[gPng_Info.inLineCount+gPng_Info.inPixelCount] = dat; + gPng_Info.inPixelCount++; + if (gPng_Info.inPixelCount == 2) + { + Filter8(gPng_Info.curLine8, gPng_Info.prvLine8, gPng_Info.x, gPng_Info.y, 2, gPng_Info.filter); + + gPng_Info.index = interlaceX * 4 + interlaceY * gPng_Info.wid * 4; + gPng_Info.rgba[gPng_Info.index] = gPng_Info.curLine8[gPng_Info.inLineCount]; + gPng_Info.rgba[gPng_Info.index+1] = gPng_Info.curLine8[gPng_Info.inLineCount]; + gPng_Info.rgba[gPng_Info.index+2] = gPng_Info.curLine8[gPng_Info.inLineCount]; + gPng_Info.rgba[gPng_Info.index+3] = gPng_Info.curLine8[gPng_Info.inLineCount+1]; + + gPng_Info.x++; + gPng_Info.inLineCount += 2; + gPng_Info.inPixelCount = 0; + } + break; + } + break; + + case 6: // Truecolor with alpha + switch (gPng_Info.hdr.bitDepth) + { + case 8: + gPng_Info.curLine8[gPng_Info.inLineCount+gPng_Info.inPixelCount] = dat; + gPng_Info.inPixelCount++; + if (gPng_Info.inPixelCount == 4) + { + Filter8(gPng_Info.curLine8, gPng_Info.prvLine8, gPng_Info.x, gPng_Info.y, 4, gPng_Info.filter); + + gPng_Info.index = interlaceX * 4 + interlaceY * gPng_Info.wid * 4; + gPng_Info.rgba[gPng_Info.index] = gPng_Info.curLine8[gPng_Info.inLineCount]; + gPng_Info.rgba[gPng_Info.index+1] = gPng_Info.curLine8[gPng_Info.inLineCount+1]; + gPng_Info.rgba[gPng_Info.index+2] = gPng_Info.curLine8[gPng_Info.inLineCount+2]; + gPng_Info.rgba[gPng_Info.index+3] = gPng_Info.curLine8[gPng_Info.inLineCount+3]; + + gPng_Info.x++; + gPng_Info.inLineCount += 4; + gPng_Info.inPixelCount = 0; + } + break; + } + break; + } // switch(hdr.colorType) + + if (gPng_Info.x >= (int)interlaceWid) + { + gPng_Info.y++; + gPng_Info.x = -1; + ShiftTwoLineBuf(); + if (gPng_Info.y >= (int)interlaceHei) + { + gPng_Info.y = 0; + gPng_Info.interlacePass++; + } + } + + return EFI_SUCCESS; + default: + return EFI_UNSUPPORTED; + } + } +} + +// +//---------------------------------------------------------------------------- +// +// Name: ConvertPNGToBlt() +// +// Description: Decode the PNG and store the output in RGB format +// +// Input: IN VOID *PNGImage, IN UINT32 PNGImageSize, IN OUT VOID **Blt, +// IN OUT UINTN *BltSize, OUT UINT32 *PixelHeight, OUT UINT32 *PixelWidth +// +// Output: EFI_STATUS +// +//---------------------------------------------------------------------------- +// +EFI_STATUS ConvertPNGToUgaBlt( IN VOID *PNGImage, IN UINT32 PNGImageSize, IN OUT VOID **Blt, IN OUT UINTN *BltSize, OUT UINT32 *PixelHeight, OUT UINT32 *PixelWidth ) +{ + //PngImageDecoder pngDecoder; + //pngDecoder.Initialize(); + EFI_STATUS Status = EFI_SUCCESS; + unsigned int x,y; + EFI_UGA_PIXEL *buf = (EFI_UGA_PIXEL *)NULL; + unsigned char *tempRGBA; + PNGImageSize = 0; + Initialize(); + if (Decode((unsigned char*)PNGImage, PNGImageSize) == EFI_SUCCESS) //Decodes the PNG image to convert PNG image data to RGB format + { + + + *PixelHeight = gPng_Info.hei; + *PixelWidth = gPng_Info.wid; + *BltSize = (*PixelHeight) * (*PixelWidth) * 4; + + *Blt = EfiLibAllocateZeroPool(*BltSize); + if (*Blt == NULL) + { + Status = EFI_OUT_OF_RESOURCES; + return Status; + } + + buf = (EFI_UGA_PIXEL *)*Blt; + + for(y = 0; y < *PixelHeight; y++) { + for(x = 0; x < *PixelWidth; x++) { + + if(x < (unsigned int)gPng_Info.wid) + { + tempRGBA = gPng_Info.rgba + (y * gPng_Info.wid + x) * 4; + } + else + { + tempRGBA = gPng_Info.rgba + (y * gPng_Info.wid + gPng_Info.wid - 1) * 4; + } + + buf->Blue = tempRGBA[2]; + buf->Green = tempRGBA[1]; //Stores the converted image data(RGB format) + buf->Red = tempRGBA[0]; + buf++; + } + } + } else { + Status = EFI_ABORTED; + } + return Status; +} + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** -- cgit v1.2.3