Last active
October 5, 2015 15:24
-
-
Save m-2k/d6fb6237e1a3e3670623 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-module(bpg_info). | |
-author('Andrey Martemyanov'). | |
-compile(export_all). | |
-record(bpg_info, { | |
pixel_format, | |
alpha, | |
bit_depth, | |
color_space, | |
extension_present, | |
limited_range, | |
animation, | |
picture_width, | |
picture_height | |
}). | |
bpg_info({filename,FileName}) -> | |
case file:open(FileName, [read,raw,binary]) of | |
{ok, IoDevice} -> | |
case file:read(IoDevice, 14) of | |
{ok,Data} -> file:close(IoDevice), bpg_info({data,Data}); | |
eof -> file:close(IoDevice), {error,small_file}; | |
{error, Reason} -> file:close(IoDevice), {error,Reason} | |
end; | |
_ -> {error,wrong_file_name} | |
end; | |
bpg_info({data,<<Header:14/binary,_/binary>>}) -> | |
FileMagic = 16#425047fb, % "BPGû" | |
case Header of | |
<<FileMagic:32,PixelFormat:3,Alpha1Flag:1,BitDepthMinus8:4,ColorSpace:4, | |
ExtensionPresentFlag:1,Alpha2Flag:1,LimitedRangeFlag:1,AnimationFlag:1, | |
PictureDimensions:8/binary>> -> | |
{ok,PictureWidth,PictureHeight}=bpg_dimensions(PictureDimensions), | |
{ok,#bpg_info{ | |
pixel_format=case PixelFormat of | |
0 -> grayscale; | |
1 -> '4:2:0-jpeg'; | |
2 -> '4:2:2-jpeg'; | |
3 -> '4:4:4'; | |
4 -> '4:2:0-mpeg2'; | |
5 -> '4:2:2-mpeg2' end, | |
alpha=case {Alpha1Flag,Alpha2Flag} of | |
{0,0} -> no_alpha; | |
{1,0} -> alpha_color_not_premultiplied; | |
{1,1} -> alpha_color_premultiplied; | |
{0,1} -> alpha_CMYK end, | |
bit_depth=BitDepthMinus8+8, | |
color_space=case ColorSpace of | |
0 -> {'YCbCr','BT 601', 5}; | |
1 -> {'RGB', undefined,unedfined}; | |
2 -> {'YCgCo', undefined, 8}; | |
3 -> {'YCbCr', 'BT 709', 1}; | |
4 -> {'YCbCr', 'BT 2020', 9}; | |
5 -> { reserved, 'BT 2020', undefined}; | |
_ -> { reserved, undefined, undefined} end, | |
extension_present=case ExtensionPresentFlag of 0 -> false; 1 -> true end, | |
limited_range=case LimitedRangeFlag of 0 -> false; 1 -> true end, | |
animation=case AnimationFlag of 0 -> false; 1 -> true end, | |
picture_width=PictureWidth, | |
picture_height=PictureHeight}}; | |
_ -> {error,wrong_bpg_header} | |
end. | |
bpg_dimensions(Bytes) -> | |
ReadUE7 = fun ReadUE7(<<1:1,Byte7:7,Tail/binary>>,Number) -> | |
ReadUE7(Tail,<<Number/bitstring,Byte7:7>>); | |
ReadUE7(<<0:1,Byte7:7,Tail/binary>>,Number) -> | |
Size=bit_size(Number)+7, | |
<<UE7:Size>> = <<Number/bitstring,Byte7:7>>, | |
{ok,UE7,Tail} | |
end, | |
ReadUE7Array = fun ReadUE7Array(<<>>,_,Acc) -> {error,wrong_data}; | |
ReadUE7Array(_,0,Acc) -> Acc; | |
ReadUE7Array(ByteList,Count,Acc) -> | |
{ok,Num,Tail}=ReadUE7(ByteList,<<>>), | |
ReadUE7Array(Tail,Count-1,[Num|Acc]) | |
end, | |
case ReadUE7Array(Bytes,2,[]) of | |
[H,W] -> {ok,W,H}; | |
Error -> Error end. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment