0
votes

I want to read ICO file and save every icon into separate BMP. My code does the trick for the first icon in ICO files. But then I don't know where to set the file cursor (where to fseek to).

Here's are the steps I do, in pseudocode:

  1. Read ICONDIR = read first 6 bytes:
    • UInt16 as 'reserved' (always 0)
    • Uint16 as 'type' (1 for ICO, 0 for CUR)
    • Uint16 as 'count' (number of icons)
  2. Read ICONDIRENTRY = next 16 bytes
    • Uint8 as 'width'
    • Uint8 as 'height'
    • Uint8 as 'colors'
    • Uint16 as 'color planes'
    • Uint16 as 'bits per pixel'
    • Uint32 as 'size of image'
    • Uint32 as 'offset'
  3. Set the file position to the 'offset'. Read BITMAPINFOHEADER = next 40 bytes
    • Uint32 as 'header size'
    • Uint32 as 'width2'
    • Uint32 as 'height2'
    • Uint16 as 'color planes2'
    • Uint16 as 'bits per pixel2'
    • Uint32 as 'compression'
    • Uint32 as 'image length'
    • Uint32 as 'dpi X'
    • Uint32 as 'dpi Y'
    • Uint32 as 'colors used'
    • Uint32 as 'important colors'
  4. Read the pixels of the image, from offset = 40 + 'offset' I read 'width' * 'height' * 'bits per pixel' / 8 bytes. And I got first icon from ICO files. So far so good.

But where do I fseek to now? I tried reading from the place I finished but with no luck. I know the next icon is 48x48 bytes in size, so I think i should read next ICONDIRENTRY which should give me 'width' and 'height' = 48. But I don't know where to start reading from.

I am writing the program in PHP but PHP guys for questions like this usually say 'use library X' or 'use ImageMagick' and I just need to know the algorithm. Such programs are usually written in C++ so I tagged this C++.

Where is the next ICONDIRENTRY in the ICO file (what offset)?

1
Go back to the ICONDIR and read the next ICONDIRENTRY. Seek to the defined offset and read the image. Rinse and repeat. Or better, just read the whole ICONDIR at once into some sort of array, then seek to the different offsets.user1864610
@HoboSapiens That's it! Thank you so much! Can you post it as an answer so I can accept?Tom

1 Answers

1
votes

You're nearly there...

The ICO format starts with the ICONDIR, a short header and one or more ICONDIRENTRY blocks that define the parameters for each icon in the file. To read the whole file start by reading the ICONDIR and parsing the ICONDIRENTRY blocks into an array.

Then loop through your array using the offset in each entry to seek to the next image.

The file format is described on MSDN, and there's also an article on Wikipedia