///* // * libeg/load_icns.c // * Loading function for .icns Apple icon images // * // * Copyright (c) 2006 Christoph Pfisterer // * All rights reserved. // * // * Redistribution and use in source and binary forms, with or without // * modification, are permitted provided that the following conditions are // * met: // * // * * Redistributions of source code must retain the above copyright // * notice, this list of conditions and the following disclaimer. // * // * * Redistributions in binary form must reproduce the above copyright // * notice, this list of conditions and the following disclaimer in the // * documentation and/or other materials provided with the // * distribution. // * // * * Neither the name of Christoph Pfisterer nor the names of the // * contributors may be used to endorse or promote products derived // * from this software without specific prior written permission. // * // * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // */ ////#if !defined(LODEPNG) //#include "libegint.h" // //#ifndef DEBUG_ALL //#define DEBUG_IMG 0 //#else //#define DEBUG_IMG DEBUG_ALL //#endif // //#if DEBUG_IMG == 0 //#define DBG(...) //#else //#define DBG(...) DebugLog(DEBUG_IMG, __VA_ARGS__) //#endif // // //// //// Decompress .icns RLE data //// // //VOID egDecompressIcnsRLE(IN OUT UINT8 **CompData, IN OUT UINTN *CompLen, IN UINT8 *PixelData, IN UINTN PixelCount) //{ // UINT8 *cp; // UINT8 *cp_end; // UINT8 *pp; // UINTN pp_left; // UINTN len, i; // UINT8 value; // // // setup variables // cp = *CompData; // cp_end = cp + *CompLen; // pp = PixelData; // pp_left = PixelCount; // // // decode // while (cp + 1 < cp_end && pp_left > 0) { // len = *cp++; // if (len & 0x80) { // compressed data: repeat next byte // len -= 125; // if (len > pp_left) // break; // value = *cp++; // for (i = 0; i < len; i++) { // *pp = value; // pp += 4; // } // } else { // uncompressed data: copy bytes // len++; // if (len > pp_left || cp + len > cp_end) // break; // for (i = 0; i < len; i++) { // *pp = *cp++; // pp += 4; // } // } // pp_left -= len; // } // // if (pp_left > 0) { // DBG(" egDecompressIcnsRLE: still need %d bytes of pixel data\n", pp_left); // } // // // record what's left of the compressed data stream // *CompData = cp; // *CompLen = (UINTN)(cp_end - cp); //} // //// //// Load Apple .icns icons //// // //EG_IMAGE * egDecodeICNS(IN UINT8 *FileData, IN UINTN FileDataLength, IN UINTN IconSize, IN BOOLEAN WantAlpha) //{ // EG_IMAGE *NewImage; // UINT8 *Ptr, *BufferEnd, *DataPtr, *MaskPtr; // UINT32 BlockLen, DataLen, MaskLen; // UINTN FetchPixelSize, PixelCount, i; // UINT8 *CompData; // UINTN CompLen; // UINT8 *SrcPtr; // EG_PIXEL *DestPtr; // // if (FileDataLength < 8 || FileData == NULL || // FileData[0] != 'i' || FileData[1] != 'c' || FileData[2] != 'n' || FileData[3] != 's') { // // not an icns file... // DBG("not icns\n"); // return NULL; // } // // FetchPixelSize = IconSize; // for (;;) { // DataPtr = NULL; // DataLen = 0; // MaskPtr = NULL; // MaskLen = 0; // // Ptr = FileData + 8; // BufferEnd = FileData + FileDataLength; // // iterate over tagged blocks in the file // while (Ptr + 8 <= BufferEnd) { // BlockLen = ((UINT32)Ptr[4] << 24) + ((UINT32)Ptr[5] << 16) + ((UINT32)Ptr[6] << 8) + (UINT32)Ptr[7]; // if (Ptr + BlockLen > BufferEnd) // block continues beyond end of file // break; // // // extract the appropriate blocks for each pixel size // if (FetchPixelSize == 128) { // if (Ptr[0] == 'i' && Ptr[1] == 't' && Ptr[2] == '3' && Ptr[3] == '2') { // if (Ptr[8] == 0 && Ptr[9] == 0 && Ptr[10] == 0 && Ptr[11] == 0) { // DataPtr = Ptr + 12; // DataLen = BlockLen - 12; // } // } else if (Ptr[0] == 't' && Ptr[1] == '8' && Ptr[2] == 'm' && Ptr[3] == 'k') { // MaskPtr = Ptr + 8; // MaskLen = BlockLen - 8; // } // // } else if (FetchPixelSize == 48) { // if (Ptr[0] == 'i' && Ptr[1] == 'h' && Ptr[2] == '3' && Ptr[3] == '2') { // DataPtr = Ptr + 8; // DataLen = BlockLen - 8; // } else if (Ptr[0] == 'h' && Ptr[1] == '8' && Ptr[2] == 'm' && Ptr[3] == 'k') { // MaskPtr = Ptr + 8; // MaskLen = BlockLen - 8; // } // // } else if (FetchPixelSize == 32) { // if (Ptr[0] == 'i' && Ptr[1] == 'l' && Ptr[2] == '3' && Ptr[3] == '2') { // DataPtr = Ptr + 8; // DataLen = BlockLen - 8; // } else if (Ptr[0] == 'l' && Ptr[1] == '8' && Ptr[2] == 'm' && Ptr[3] == 'k') { // MaskPtr = Ptr + 8; // MaskLen = BlockLen - 8; // } // // } else if (FetchPixelSize == 16) { // if (Ptr[0] == 'i' && Ptr[1] == 's' && Ptr[2] == '3' && Ptr[3] == '2') { // DataPtr = Ptr + 8; // DataLen = BlockLen - 8; // } else if (Ptr[0] == 's' && Ptr[1] == '8' && Ptr[2] == 'm' && Ptr[3] == 'k') { // MaskPtr = Ptr + 8; // MaskLen = BlockLen - 8; // } // // } // // Ptr += BlockLen; // } // //TODO - take different larger size if not found // // FUTURE: try to load a different size and scale it later // if (DataPtr == NULL && FetchPixelSize == 128) { // FetchPixelSize = 32; // continue; // } // // break; // } // // if (DataPtr == NULL) { // DBG("not found such IconSize\n"); // return NULL; // no image found // } // // // allocate image structure and buffer // NewImage = egCreateImage(FetchPixelSize, FetchPixelSize, WantAlpha); // if (NewImage == NULL) // return NULL; // PixelCount = FetchPixelSize * FetchPixelSize; // // if (DataLen < PixelCount * 3) { // // // pixel data is compressed, RGB planar // CompData = DataPtr; // CompLen = DataLen; // egDecompressIcnsRLE(&CompData, &CompLen, &NewImage->PixelData->r, PixelCount); // egDecompressIcnsRLE(&CompData, &CompLen, &NewImage->PixelData->g, PixelCount); // egDecompressIcnsRLE(&CompData, &CompLen, &NewImage->PixelData->b, PixelCount); // // possible assertion: CompLen == 0 // if (CompLen > 0) { // DBG(" egLoadICNSIcon: %d bytes of compressed data left\n", CompLen); // } // // } else { // // // pixel data is uncompressed, RGB interleaved // SrcPtr = DataPtr; // DestPtr = NewImage->PixelData; // for (i = 0; i < PixelCount; i++, DestPtr++) { // DestPtr->r = *SrcPtr++; // DestPtr->g = *SrcPtr++; // DestPtr->b = *SrcPtr++; // } // // } // // // Jief : not sure where they should define TODO ! // extern VOID egInsertPlane(IN UINT8 *SrcDataPtr, IN UINT8 *DestPlanePtr, IN UINTN PixelCount); // extern VOID egSetPlane(IN UINT8 *DestPlanePtr, IN UINT8 Value, IN UINT64 PixelCount); // // // add/set alpha plane // if (MaskPtr != NULL && MaskLen >= PixelCount && WantAlpha) // egInsertPlane(MaskPtr, &NewImage->PixelData->a, PixelCount); // else // egSetPlane(&NewImage->PixelData->a, WantAlpha ? 255 : 0, PixelCount); // // // FUTURE: scale to originally requested size if we had to load another size // // return NewImage; //} ////#endif ///* EOF */