Что не так с этим файлом .ico, в котором есть изображение в формате .png?

#png #ico

#png #ico

Вопрос:

Я основал файл на https://en.wikipedia.org/wiki/ICO_ (file_format) и https://www.w3.org/TR/PNG /. Я переведу файл .ico из того, как он выглядит в моем шестнадцатеричном редакторе, в какой-то псевдо-двоичный файл (порядок байтов указан как записанный):

 ICONDIR{
    uint16_t idReserved : 00 00 
    uint16_t idType : 00 01 
    uint16_t idCount : 00 01 
    ICONDIRENTRY{
        uint8_t bWidth : 01 
        uint8_t bHeight : 01 
        uint8_t bColorCount : 00 
        uint8_t bReserved : 00 
        uint16_t wPlanes : 00 00 
        uint16_t wBitCount : 00 20 
        uint32_t dwBytesInRes : 00 00 00 49 
        uint32_t dwImageOffset : 00 00 00 16 
    }
}
PNG{
    uint8_t PNGSignature[8] : 89 50 4E 47 0D 0A 1A 0A 
    IHDR{
        uint32_t Length :  00 00 00 0D 
        uint8_t ChunkType[4] : 49 48 44 52 //IHDR
        uint32_t Width : 00 00 00 01 
        uint32_t Height : 00 00 00 01 
        uint8_t BitDepth : 08 //8 bits
        uint8_t ColourType : 06 //RGBA
        uint8_t CompressionMethod : 00 
        uint8_t FilterMethod : 00
        uint8_t InterlaceMethod : 00 
        uint32_t CRC32 : 1F 15 C4 89 //CRC32 of bits [ChunkType,...,InterlaceMethod]
    }
    IDAT{
        uint32_t Length : 00 00 00 10 
        uint8_t ChunkType[4] : 49 44 41 54 //IDAT
        ZLIB{
            (CMF.CINFO = 0000,CMF.CM = 1000) : 08 
            (FLG.FLEVEL = 10 /*Slowest Algorithm*/
            ,FLG.FDICT = 0 /* No dictionary */
            ,FLG.FCHECK = 11001 /* 0000100010011001 = 2201 = 71 x 31 */) : 99 
            DEFLATE{
                (BFINAL = 1 /* Last block */
                ,BTYPE = 00 /* No compression */
                ,<No compression ignored bytes = 00000>) : 80 
                uint16_t LEN : 00 05 
                uint16_t NLEN : FF FA 
                LITERAL_DATA_SCANLINE{
                    uint8_t FilterTypeByte : 00 // No filtering
                    PIXEL{
                        uint8_t R : FF 
                        uint8_t G : 00 
                        uint8_t B : 00 
                        uint8_t A : FF 
                    }
                }
            }
            uint32_t ADLER32 : 00 AB 00 A2 
        }
        uint32_t CRC32 : 02 EA 6B 91 //CRC32 of bits [ChunkType,ZLIB]
    }
    IEND{
        uint32_t Length : 00 00 00 00 
        uint8_t ChunkType[4] : 49 45 4E 44 
        uint32_t CRC32 : AE 42 60 82 //CRC32 of [ChunkType]
    }
}
 

Изображение в формате PNG (увеличено до размера 100×100):

Поскольку PNG может отображаться, я предполагаю, что есть некоторая документация, которую я не нашел / неправильно истолковал. Пожалуйста, укажите на ошибку, если вы ее видите!

Ответ №1:

Я пропустил часть с малым концом… Правильная версия части ICO:

 ICONDIR{
    uint16_t idReserved : 00 00 
    uint16_t idType : 01 00 
    uint16_t idCount : 01 00 
    ICONDIRENTRY{
        uint8_t bWidth : 01 
        uint8_t bHeight : 01 
        uint8_t bColorCount : 00 
        uint8_t bReserved : 00 
        uint16_t wPlanes : 00 00 
        uint16_t wBitCount : 20 00  
        uint32_t dwBytesInRes : 49 00 00 00  
        uint32_t dwImageOffset : 16 00 00 00  
    }
}
 

Комментарии:

1. Это ответ. Не хватало небольшого порядка байтов.

2. (Я сериализовал структуру ico в формате big endian, что повредило изображение.)