Created
January 17, 2011 02:56
-
-
Save mokele/782431 to your computer and use it in GitHub Desktop.
This file contains hidden or 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(eimgs). | |
-compile(export_all). | |
-define(M,16#FF). | |
-define(SOI,16#D8). | |
-define(EOI,16#D9). | |
-record(jpg, {buf = <<>>}). | |
go() -> | |
{ok, IO} = file:open("dat/me.jpg", [read,binary]), | |
chunk(IO, {#jpg{}, 2, fun marker/2}). | |
chunk(_IO, ok) -> | |
ok; | |
chunk(IO, {I=#jpg{buf=Buf}, Read, Fun}) -> | |
case read(IO, Buf, Read) of | |
{ok, Buf2, Data} -> | |
chunk(IO, Fun(I#jpg{buf=Buf2}, Data)); | |
{error, Reason} -> | |
io:format("Error: ~p~n", [Reason]); | |
eof -> | |
ok | |
end. | |
%% read Read number of bytes from either the binary second | |
%% argument buffer or from the iodevice, or both if there's | |
%% some but not enough in the binary buffer. | |
read(IO, <<>>, Read) -> | |
%% shortcut for no buffer, go straight to file | |
read_response(file:read(IO,Read)); | |
read(IO, Buf, Read) -> | |
{Buf2,BufRead,Count} = bin_read(Buf,Read), | |
read(IO, Buf2, Read, BufRead, Count). | |
read(_IO, Buf, Read, Acc, Read) -> | |
{ok,Buf,Acc}; | |
read(IO, Buf, Read, Acc, Count) -> | |
case file:read(IO,Read-Count) of | |
{ok, Data} -> | |
{ok,Buf,<<Acc/binary,Data/binary>>}; | |
{error, Reason} -> | |
{error, Reason}; | |
eof -> | |
case Acc of | |
<<>> -> eof; | |
_ -> {ok,Buf,Acc} | |
end | |
end. | |
read_response({ok, Data}) -> {ok, <<>>, Data}; | |
read_response(Other) -> Other. | |
%% bin_read | |
bin_read(Buf,Read) -> | |
bin_read(Buf,Read,<<>>,0). | |
bin_read(<<>>,_Read,Acc,Count) -> | |
{<<>>,Acc,Count}; | |
bin_read(Rest,Read,Acc,Read) -> | |
{Rest,Acc,Read}; | |
bin_read(<<Byte:8,Rest/binary>>,Read,Acc,Count) -> | |
bin_read(Rest,Read,<<Acc/binary,Byte:8>>,Count+1). | |
%% 11,648 bytes | |
%% start of image SOI | |
marker(I, <<?M,?SOI>>) -> | |
io:format("Start of image...~n"), | |
{I, 2, fun marker/2}; | |
%% end of image EOI | |
marker(I, <<?M,?EOI>>) -> | |
io:format("End of image!~n"), | |
{I, 2, fun marker/2}; | |
marker(I, <<?M,16#DA>>) -> | |
io:format("Stat of scan...~n"), | |
{I, 3, fun scan_length/2}; | |
marker(I, <<?M,Marker:8>>) -> | |
io:format("Marker: ~p~n", [marker(Marker)]), | |
{I, 2, fun marker_segment_length/2}. | |
marker_segment_length(I, <<Length:2/integer-unsigned-unit:8>>) -> | |
{I, Length-2, fun marker_segment/2}. | |
marker_segment(I, _Data) -> | |
%io:format("Data: ~p~n", [Data]), | |
{I, 2, fun marker/2}. | |
scan_length(I, <<Length:2/integer-unsigned-unit:8,Ns:1/integer-unsigned-unit:8>>) -> | |
io:format("Ns: ~p~n", [Ns]), | |
{I, Length, fun scan_header/2}. | |
scan_header(I, Data) -> | |
io:format("Scan Header: ~p~n", [Data]), | |
{I, 3, fun scan/2}. | |
scan(I, <<Ss:8,Se:8,Ah:4,Al:4>>) -> | |
io:format("Scan: ~p ~p ~p ~p~n", [Ss,Se,Ah,Al]), | |
io:format("Entropy "), | |
{I, 1, fun entropy/2}. | |
entropy(I, <<?M>>) -> | |
{I, 1, fun entropy_end_check/2}; | |
entropy(I, _Data) -> | |
{I, 1, fun entropy/2}. | |
entropy_end_check(I, <<0:8>>) -> | |
%% not end of entropy, need to include original ?M in data already read | |
io:format("Zero Pad "), | |
{I, 1, fun entropy/2}; | |
entropy_end_check(I=#jpg{buf=Buf}, Other) -> | |
io:format("~nEnd of entropy~n"), | |
{I#jpg{buf = <<Buf/binary,?M,Other/binary>>}, 2, fun marker/2}. | |
marker(16#C0) -> "SOF 0"; | |
marker(16#C1) -> "SOF 1"; | |
marker(16#C2) -> "SOF 2"; | |
marker(16#C3) -> "SOF 3"; | |
marker(16#C5) -> "SOF 5"; | |
marker(16#C6) -> "SOF 6"; | |
marker(16#C7) -> "SOF 7"; | |
marker(16#C8) -> "JPG"; | |
marker(16#C9) -> "SOF 9"; | |
marker(16#CA) -> "SOF 10"; | |
marker(16#CB) -> "SOF 11"; | |
marker(16#CD) -> "SOF 13"; | |
marker(16#CE) -> "SOF 14"; | |
marker(16#CF) -> "SOF 15"; | |
marker(16#C4) -> "DHT"; | |
marker(16#CC) -> "DAC"; | |
marker(M) when M >= 16#D0, M =< 16#D7 -> "DAC"; | |
marker(?SOI) -> "SOI*"; | |
marker(?EOI) -> "EOI*"; | |
marker(16#DA) -> "SOS"; | |
marker(16#DB) -> "DQT"; | |
marker(16#DC) -> "DNL"; | |
marker(16#DD) -> "DRI"; | |
marker(16#DE) -> "DHP"; | |
marker(16#DF) -> "EXP"; | |
marker(M) when M >= 16#E0, M =< 16#EF -> "APPn"; | |
marker(M) when M >= 16#F0, M =< 16#FD -> "JPGn"; | |
marker(16#FE) -> "COM"; | |
marker(16#01) -> "TEM*"; | |
marker(M) when M >= 16#02, M =< 16#BF -> "RES". | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment