эксперименты с .ico

 

Мне понадобились файлы, относящиеся к .hlp. Понадобилось несколько пассов, которые дали бы готовый файл со значками 16x16 и 32x32. Кое-как выдернул и решил попробовать собрать .ico программным способом. На решение задачи ушло джва дня, а причиной было то, что я не разобрался с форматом значков

Заголовок

word           idreserved;   // reserved (must be 0)
word           idtype;       // resource type (1 for icons)
word           idcount;      // how many images?

Следующим должны быть данные для каждого значка - для одного значка одна структура, для двух - две:

byte        bwidth;          // width, in pixels, of the image
byte        bheight;         // height, in pixels, of the image
byte        bcolorcount;     // number of colors in image (0 if >=8bpp)
byte        breserved;       // reserved ( must be 0)
word        wplanes;         // color planes
word        wbitcount;       // bits per pixel
dword       dwbytesinres;    // how many bytes in this resource?
dword       dwimageoffset;   // where in the file is this image?

На сладкое - данные о цвете, с которым я пока не разобрался. Часть информации тут 
Сначала я написал парсер информации:

Structure ICONDIRENTRY
   bWidth.a       ; Width, in pixels, of the image
   bHeight.a      ; Height, in pixels, of the image
   bColorCount.a  ; Number of colors in image (0 if >=8bpp)
   bReserved.a    ; Reserved ( must be 0)
   wPlanes.w      ; Color Planes
   wBitCount.w    ; Bits per pixel
   dwBytesInRes.l ; How many bytes in this resource?
   dwImageOffset.l; Where in the file is this image?
EndStructure

Structure ICONDIR
   idReserved.w ; Reserved (must be 0)
   idType.w     ; Resource Type (1 for icons)
   idCount.w    ; How many images?
   Array idEntries.ICONDIRENTRY(1) ;An entry for each image (idCount of 'em)
 EndStructure
 
; Debug SizeOf(ICONDIRENTRY);16
f$="combine.ico"

If ReadFile(0,f$)
  idreserved.u=ReadUnicodeCharacter(0);reserved (must be 0)
  idtype.u=ReadUnicodeCharacter(0);resource type (1 for icons)
  idcount.u=ReadUnicodeCharacter(0);how many images?
  If idcount
    idc.ICONDIRENTRY
    For i=1 To idcount
      Debug "------"+Str(i)+"------"
      ReadData(0,@idc,SizeOf(ICONDIRENTRY))
      Debug "width="+Str(idc\bWidth)
      Debug "height="+Str(idc\bHeight)
      Debug "number of colors="+Str(idc\bColorCount)
      Debug "reserved="+Str(idc\bReserved)
      Debug "color planes="+Str(idc\wPlanes)
      Debug "Bits per pixel="+Str(idc\wBitCount)
      Debug "Bytes for resource="+Str(idc\dwBytesInRes)
      Debug "Offset="+Str(idc\dwImageOffset)
    Next i
  Else
    Debug "zero count entries"
  EndIf
  CloseFile(0)
Else
  Debug "error read:"+f$
EndIf

С готовым файлом из двух значков стало понятнее, и после нескольких проб я написал объединитель двух файлов. Осталось добавить код, который извлечет нужные данные:

Structure ICONDIRENTRY
   bWidth.a       ; Width, in pixels, of the image
   bHeight.a      ; Height, in pixels, of the image
   bColorCount.a  ; Number of colors in image (0 if >=8bpp)
   bReserved.a    ; Reserved ( must be 0)
   wPlanes.w      ; Color Planes
   wBitCount.w    ; Bits per pixel
   dwBytesInRes.l ; How many bytes in this resource?
   dwImageOffset.l; Where in the file is this image?
EndStructure

icd1.ICONDIRENTRY
icd2.ICONDIRENTRY

ReadFile(1,"small.ico"):FileSeek(1,6):ReadData(1,@icd1,SizeOf(ICONDIRENTRY))
ReadFile(2,"large.ico"):FileSeek(2,6):ReadData(2,@icd2,SizeOf(ICONDIRENTRY))
CreateFile(0,"hujcy.ico")
;header
   WriteWord(0,0);idReserved.w ; Reserved (must be 0)
   WriteWord(0,1);idType.w     ; Resource Type (1 for icons)
   WriteWord(0,2);idCount.w    ; How many images?
   icd1\dwImageOffset=icd1\dwImageOffset+16
   WriteData(0,@icd1,SizeOf(ICONDIRENTRY))
   icd2\dwImageOffset=icd1\dwImageOffset+icd1\dwBytesInRes;+16
   ;Debug icd2\dwImageOffset
   WriteData(0,@icd2,SizeOf(ICONDIRENTRY))
   For n=1 To 2
     While Not Eof(n)
       WriteAsciiCharacter(0,ReadAsciiCharacter(n))
     Wend
     CloseFile(n)
  Next n
CloseFile(0)

С более серьезными проектами не стал связываться. файлы тут.

Комментарии