Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
-module(parse_ico).
-export([parse_ico/1]).
parse_ico(FileName) ->
{ok, File} = file:read_file(FileName),
<<Reserved:16/unsigned-integer-little,
Type:16/unsigned-integer-little,
ImageCount:16/unsigned-integer-little,
Images/binary>> = File,
{{header,
{reserved, Reserved},
{type, Type},
{image_count, ImageCount}},
{images, parse_images(Images, ImageCount, [])}}.
parse_images(_, 0, Result) ->
Result;
parse_images(ImagesBin, ImageCount, Result) ->
<<Width,
Height,
PaletteCount,
Reserved,
ColorPlanes:16/unsigned-integer-little,
BitsPerPixel:16/unsigned-integer-little,
Size:32/unsigned-integer-little,
Offset:32/unsigned-integer-little,
Content/binary>> = ImagesBin,
{ok, Palette, PixelsBin} = parse_palette(Content, PaletteCount, []),
{ok, Pixels, NextImgBin} = parse_pixels(PixelsBin, BitsPerPixel, Width, Height),
Image = {
{width, Width},
{height, Height},
{palette_count, PaletteCount},
{reserved, Reserved},
{color_planes, ColorPlanes},
{bits_per_pixel, BitsPerPixel},
{size, Size},
{offset, Offset},
{content, {
{palette, Palette},
{pixels, Pixels}}}},
parse_images(NextImgBin, ImageCount -1, [Image | Result]).
parse_palette(Binary, 0, Result) ->
{ok, lists:reverse(Result), Binary};
parse_palette(<<R, G, B, A, Rest/binary>>, Count, Result) ->
parse_palette(Rest, Count - 1, [{R, G, B, A} | Result]).
parse_pixels(PixelsBin, BitsPerPixel, Width, Height) ->
CurImageSize = trunc(BitsPerPixel * Width * Height / 8),
CurRowSize = trunc(BitsPerPixel * Width / 8),
<<MyPixels:CurImageSize/binary, NextImgBin/binary>> = PixelsBin,
Pixels = [lists:flatten([[Px2, Px1]
|| <<Px1:BitsPerPixel, Px2:BitsPerPixel>> <= Row])
|| <<Row:CurRowSize/binary>> <= MyPixels],
{ok, Pixels, NextImgBin}.
jParser: анализ двоичных файлов работает просто