| 161 | // |
| 162 | |
| 163 | EG_IMAGE * egDecodeICNS(IN UINT8 *FileData, IN UINTN FileDataLength, IN UINTN IconSize, IN BOOLEAN WantAlpha) |
| 164 | { |
| 165 | EG_IMAGE *NewImage; |
| 166 | UINT8 *Ptr, *BufferEnd, *DataPtr, *MaskPtr; |
| 167 | UINT32 BlockLen, DataLen, MaskLen; |
| 168 | UINTN FetchPixelSize, PixelCount, i; |
| 169 | UINT8 *CompData; |
| 170 | UINTN CompLen; |
| 171 | UINT8 *SrcPtr; |
| 172 | EFI_UGA_PIXEL *DestPtr; |
| 173 | |
| 174 | if (FileDataLength < 8 || FileData == NULL || |
| 175 | FileData[0] != 'i' || FileData[1] != 'c' || FileData[2] != 'n' || FileData[3] != 's') { |
| 176 | // not an icns file... |
| 177 | DBG("not icns\n"); |
| 178 | return NULL; |
| 179 | } |
| 180 | |
| 181 | FetchPixelSize = IconSize; |
| 182 | for (;;) { |
| 183 | DataPtr = NULL; |
| 184 | DataLen = 0; |
| 185 | MaskPtr = NULL; |
| 186 | MaskLen = 0; |
| 187 | |
| 188 | Ptr = FileData + 8; |
| 189 | BufferEnd = FileData + FileDataLength; |
| 190 | // iterate over tagged blocks in the file |
| 191 | while (Ptr + 8 <= BufferEnd) { |
| 192 | BlockLen = ((UINT32)Ptr[4] << 24) + ((UINT32)Ptr[5] << 16) + ((UINT32)Ptr[6] << 8) + (UINT32)Ptr[7]; |
| 193 | if (Ptr + BlockLen > BufferEnd) // block continues beyond end of file |
| 194 | break; |
| 195 | |
| 196 | // extract the appropriate blocks for each pixel size |
| 197 | if (FetchPixelSize == 128) { |
| 198 | if (Ptr[0] == 'i' && Ptr[1] == 't' && Ptr[2] == '3' && Ptr[3] == '2') { |
| 199 | if (Ptr[8] == 0 && Ptr[9] == 0 && Ptr[10] == 0 && Ptr[11] == 0) { |
| 200 | DataPtr = Ptr + 12; |
| 201 | DataLen = BlockLen - 12; |
| 202 | } |
| 203 | } else if (Ptr[0] == 't' && Ptr[1] == '8' && Ptr[2] == 'm' && Ptr[3] == 'k') { |
| 204 | MaskPtr = Ptr + 8; |
| 205 | MaskLen = BlockLen - 8; |
| 206 | } |
| 207 | |
| 208 | } else if (FetchPixelSize == 48) { |
| 209 | if (Ptr[0] == 'i' && Ptr[1] == 'h' && Ptr[2] == '3' && Ptr[3] == '2') { |
| 210 | DataPtr = Ptr + 8; |
| 211 | DataLen = BlockLen - 8; |
| 212 | } else if (Ptr[0] == 'h' && Ptr[1] == '8' && Ptr[2] == 'm' && Ptr[3] == 'k') { |
| 213 | MaskPtr = Ptr + 8; |
| 214 | MaskLen = BlockLen - 8; |
| 215 | } |
| 216 | |
| 217 | } else if (FetchPixelSize == 32) { |
| 218 | if (Ptr[0] == 'i' && Ptr[1] == 'l' && Ptr[2] == '3' && Ptr[3] == '2') { |
| 219 | DataPtr = Ptr + 8; |
| 220 | DataLen = BlockLen - 8; |
no test coverage detected