Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Extracted some functions out of the image_tiff module to the new tiff…

… module.
  • Loading branch information...
commit 0033141744a6533a0684a7f81a35501df9948c63 1 parent dee8083
@davide davide authored
Showing with 32 additions and 409 deletions.
  1. +1 −0  Emakefile
  2. +28 −28 src/image_jpeg.erl
  3. +3 −381 src/image_tiff.erl
View
1  Emakefile
@@ -1,5 +1,6 @@
{"src/erl_img.erl", [debug_info, {d, debug}, {outdir, "ebin"}, {i, "include"}]}.
{"src/exif.erl", [debug_info, {d, debug}, {outdir, "ebin"}, {i, "include"}]}.
+{"src/tiff.erl", [debug_info, {d, debug}, {outdir, "ebin"}, {i, "include"}]}.
{"src/image_tiff.erl", [debug_info, {d, debug}, {outdir, "ebin"}, {i, "include"}]}.
{"src/image_jpeg.erl", [debug_info, {d, debug}, {outdir, "ebin"}, {i, "include"}]}.
{"src/gpsinfo.erl", [debug_info, {d, debug}, {outdir, "ebin"}, {i, "include"}]}.
View
56 src/image_jpeg.erl
@@ -163,35 +163,35 @@ collect_maker_fixme(Fd, T, St) ->
MakerBin = T#tiff_entry.value,
case MakerBin of
<<"OLYMP",0,1,0,_/binary>> ->
- image_tiff:scan_ifd(Fd,
- [$0,$:|T#tiff_entry.ifd],
- T#tiff_entry.offs+8,
- T#tiff_entry.endian,
- fun collect_olymp/3, St);
+ tiff:scan_ifd(Fd,
+ [$0,$:|T#tiff_entry.ifd],
+ T#tiff_entry.offs+8,
+ T#tiff_entry.endian,
+ fun collect_olymp/3, St);
<<"Nikon",0,1,0,_/binary>> ->
- image_tiff:scan_ifd(Fd,
- [$0,$:|T#tiff_entry.ifd],
- T#tiff_entry.offs+8,
- T#tiff_entry.endian,
- fun collect_nikon/3, St);
+ tiff:scan_ifd(Fd,
+ [$0,$:|T#tiff_entry.ifd],
+ T#tiff_entry.offs+8,
+ T#tiff_entry.endian,
+ fun collect_nikon/3, St);
<<"SONY DSC ",0,0,0,_/binary>> ->
%% NOT working - what is SONY doing ?
- image_tiff:scan_ifd(Fd,
- [$0,$:|T#tiff_entry.ifd],
- T#tiff_entry.offs+14,
- T#tiff_entry.endian,
- fun collect_sony/3, St);
+ tiff:scan_ifd(Fd,
+ [$0,$:|T#tiff_entry.ifd],
+ T#tiff_entry.offs+14,
+ T#tiff_entry.endian,
+ fun collect_sony/3, St);
<<"FUJIFILM",Offset:32/little>> ->
- image_tiff:scan_ifd_bin(MakerBin,
- [$0,$:|T#tiff_entry.ifd],
- Offset, little,
- fun collect_fujifilm/3, St);
+ tiff:scan_ifd_bin(MakerBin,
+ [$0,$:|T#tiff_entry.ifd],
+ Offset, little,
+ fun collect_fujifilm/3, St);
_ ->
- image_tiff:scan_ifd(Fd,
- [$0,$:|T#tiff_entry.ifd],
- T#tiff_entry.offs+8,
- T#tiff_entry.endian,
- fun collect_other/3, St)
+ tiff:scan_ifd(Fd,
+ [$0,$:|T#tiff_entry.ifd],
+ T#tiff_entry.offs+8,
+ T#tiff_entry.endian,
+ fun collect_other/3, St)
end.
@@ -203,7 +203,7 @@ collect_exif(Fd, T, St) ->
?ExifInteroperabilityOffset ->
[Offset] = T#tiff_entry.value,
%% could be handle by a collect_interop?
- case image_tiff:scan_ifd(Fd, [$0,$.|T#tiff_entry.ifd],
+ case tiff:scan_ifd(Fd, [$0,$.|T#tiff_entry.ifd],
Offset, T#tiff_entry.endian,
fun collect_exif/3, St) of
{ok, St1} ->
@@ -225,7 +225,7 @@ collect_exif(Fd, T, St) ->
%% Image info collector functions
collect_tiff(Fd, T, St) ->
- Key = image_tiff:decode_tag(T#tiff_entry.tag),
+ Key = tiff:decode_tag(T#tiff_entry.tag),
?dbg("TIFF(~s) ~p ~p ~p\n",
[T#tiff_entry.ifd,Key,T#tiff_entry.type, T#tiff_entry.value]),
case T#tiff_entry.tag of
@@ -257,7 +257,7 @@ collect_tiff(Fd, T, St) ->
end;
?ExifOffset ->
[Offset] = T#tiff_entry.value,
- case image_tiff:scan_ifd(Fd, [$0,$.|T#tiff_entry.ifd],
+ case tiff:scan_ifd(Fd, [$0,$.|T#tiff_entry.ifd],
Offset, T#tiff_entry.endian,
fun collect_exif/3, St) of
{ok, St1} ->
@@ -267,7 +267,7 @@ collect_tiff(Fd, T, St) ->
end;
?GPSInfo ->
[Offset] = T#tiff_entry.value,
- case image_tiff:scan_ifd(Fd, [$0,$.|T#tiff_entry.ifd],
+ case tiff:scan_ifd(Fd, [$0,$.|T#tiff_entry.ifd],
Offset, T#tiff_entry.endian,
fun gpsinfo:collect_gpsinfo/3, []) of
{ok, GPSInfo} ->
View
384 src/image_tiff.erl
@@ -11,13 +11,10 @@
-include("api.hrl").
-include("dbg.hrl").
-
--export([scan_ifd/6, scan_ifd_bin/6]).
--export([decode_tag/1]).
-
-export([scan_fd/3, scan_file/3, scan_binary/3]).
-export([dump_file/1, dump_binary/1]).
+-import(tiff, [scan_ifd/6, scan_ifd_bin/6, undo_differencing/4, unpack_bits/1, decode_tag/1]).
-import(lists, [map/2, reverse/1]).
-define(II, 16#4949). %% little-endian
@@ -164,7 +161,7 @@ write(_Fd,_IMG) ->
%% Image info collector functions
collect_fun(_Fd, T, St) ->
- Key = decode_tag(T#tiff_entry.tag),
+ Key = tiff:decode_tag(T#tiff_entry.tag),
Value = T#tiff_entry.value,
As = [{Key,Value} | St#erl_image.attributes],
case Key of
@@ -199,7 +196,7 @@ collect_fun(_Fd, T, St) ->
dump_fun(_Fd, T, St) ->
- Key = decode_tag(T#tiff_entry.tag),
+ Key = tiff:decode_tag(T#tiff_entry.tag),
io:format("~s ~s ~w\n", [Key,T#tiff_entry.type,T#tiff_entry.value]),
St.
@@ -245,378 +242,3 @@ scan_fd(Fd, Callback, St) ->
Error
end.
-%% Scan entry point for special Exif/MakerNote
-scan_ifd_bin(Bin, IFD, Offset, Endian, Callback, St) ->
- case file:open(Bin, [ram, binary, read]) of
- {ok,Fd} ->
- Res = scan_ifd(Fd, IFD, Offset, Endian, Callback, St),
- file:close(Fd),
- Res;
- Error ->
- Error
- end.
-
-scan_ifd(_Fd, _IFD, 0, _Endian, _Callback, St) ->
- {ok,St};
-scan_ifd(Fd, IFD, Offset, Endian, Callback,St) ->
- file:position(Fd, Offset),
- case read_u16(Fd,Endian) of
- {ok,N} ->
- scan_entries(Fd, IFD, Endian, N, Callback, St);
- Error -> Error
- end.
-
-scan_entries(Fd, [I|IFD], Endian, 0, Callback, St) ->
- case read_u32(Fd,Endian) of
- {ok,Offset} ->
- scan_ifd(Fd,[I+1|IFD],Offset,Endian,Callback,St);
- Error -> Error
- end;
-scan_entries(Fd, IFD, Endian, I, Callback,St) ->
- case read_entry(Fd,Endian) of
- {ok,{Tag,Type,N,Data}} ->
- TiffTag =
- case is_value(Type, N) of
- true ->
- Value = decode_value(Type,Endian,N,Data),
- #tiff_entry { ifd = IFD,
- tag = Tag,
- endian = Endian,
- type = Type,
- value = Value };
- false ->
- Offset = if Endian == little ->
- <<Offs:32/little>> = Data, Offs;
- true ->
- <<Offs:32/big>> = Data, Offs
- end,
- Value = decode_offs_value(Fd,Offset,Type,Endian,N),
- #tiff_entry { ifd = IFD,
- tag = Tag,
- endian = Endian,
- type = Type,
- offs = Offset,
- value = Value }
- end,
- %% Save file position inorder to allwo callback to parse Sub ifd's
- {ok,Save} = file:position(Fd, cur),
- St1 = Callback(Fd, TiffTag, St),
- file:position(Fd, Save),
- scan_entries(Fd, IFD, Endian, I-1, Callback, St1);
- Error -> Error
- end.
-
-read_u16(Fd, Endian) ->
- case file:read(Fd, 2) of
- {ok, <<N:16/little>>} when Endian == little -> {ok, N};
- {ok, <<N:16/big>>} when Endian == big -> {ok, N};
- {ok, _} -> {error, truncated};
- Error -> Error
- end.
-
-read_u32(Fd, Endian) ->
- case file:read(Fd, 4) of
- {ok, <<N:32/little>>} when Endian == little -> {ok, N};
- {ok, <<N:32/big>>} when Endian == big -> {ok, N};
- {ok, _} -> {error, truncated};
- Error -> Error
- end.
-
-read_entry(Fd,Endian) ->
- case file:read(Fd,12) of
- {ok,<<Tag:16/little,T:16/little,N:32/little,V:4/binary>>} when
- Endian == little ->
- {ok,{Tag,decode_type(T),N,V}};
- {ok,<<Tag:16/big,T:16/big,N:32/big,V:4/binary>>} when
- Endian == big ->
- {ok,{Tag,decode_type(T),N,V}};
- {ok,_} -> {error, truncated};
- Error -> Error
- end.
-
-
-%% Decode TIFF types
-decode_type(?BYTE) -> byte;
-decode_type(?ASCII) -> ascii;
-decode_type(?SHORT) -> short;
-decode_type(?LONG) -> long;
-decode_type(?RATIONAL) -> rational;
-decode_type(?SBYTE) -> sbyte;
-decode_type(?UNDEFINED) -> undefined;
-decode_type(?SSHORT) -> sshort;
-decode_type(?SLONG) -> slong;
-decode_type(?SRATIONAL) -> srational;
-decode_type(?FLOAT) -> float;
-decode_type(?DOUBLE) -> double;
-decode_type(_) -> unknown.
-
-decode_tag(Tag) ->
- case Tag of
- ?NewSubfileType -> 'NewSubfileType';
- ?SubfileType -> 'SubfileType';
- ?ImageWidth -> 'ImageWidth';
- ?ImageLength -> 'ImageLength';
- ?BitsPerSample -> 'BitsPerSample';
- ?Compression -> 'Compression';
- ?PhotoMetricInterpretation -> 'PhotoMetricInterpretation';
- ?Threshholding -> 'Threshholding';
- ?CellWidth -> 'CellWidth';
- ?CellLength -> 'CellLength';
- ?FillOrder -> 'FillOrder';
- ?DocumentName -> 'DocumentName';
- ?ImageDescription -> 'ImageDescription';
- ?Make -> 'Make';
- ?Model -> 'Model';
- ?StripOffset -> 'StripOffset';
- ?Orientation -> 'Orientation';
- ?SamplesPerPixel -> 'SamplesPerPixel';
- ?RowsPerStrip -> 'RowsPerStrip';
- ?StripByteCounts -> 'StripByteCounts';
- ?MinSampleValue -> 'MinSampleValue';
- ?MaxSampleValue -> 'MaxSampleValue';
- ?XResolution -> 'XResolution';
- ?YResolution -> 'YResolution';
- ?PlanarConfiguration -> 'PlanarConfiguration';
- ?PageName -> 'PageName';
- ?XPosition -> 'XPosition';
- ?YPosition -> 'YPosition';
- ?FreeOffsets -> 'FreeOffsets';
- ?FreeByteCounts -> 'FreeByteCounts';
- ?GrayResponseUnit -> 'GrayResponseUnit';
- ?GrayResponseCurve -> 'GrayResponseCurve';
- ?T4Options -> 'T4Options';
- ?T6Options -> 'T6Options';
- ?ResolutionUnit -> 'ResolutionUnit';
- ?PageNumber -> 'PageNumber';
- ?TransferFunction -> 'TransferFunction';
- ?Software -> 'Software';
- ?DateTime -> 'DateTime';
- ?Artist -> 'Artist';
- ?HostComputer -> 'HostComputer';
- ?Predictor -> 'Predictor';
- ?WhitePoint -> 'WhitePoint';
- ?PrimaryChromaticities -> 'PrimaryChromaticities';
- ?ColorMap -> 'ColorMap';
- ?HalftoneHints -> 'HalftoneHints';
- ?TileWidth -> 'TileWidth';
- ?TileLength -> 'TileLength';
- ?TileOffset -> 'TileOffset';
- ?TileByteCounts -> 'TileByteCounts';
- ?InkSet -> 'InkSet';
- ?InkNames -> 'InkNames';
- ?NumberOfInks -> 'NumberOfInks';
- ?DotRange -> 'DotRange';
- ?TargetPrinter -> 'TargetPrinter';
- ?ExtraSamples -> 'ExtraSamples';
- ?SampleFormat -> 'SampleFormat';
- ?SMinSampleValue -> 'SMinSampleValue';
- ?SMaxSampleValue -> 'SMaxSampleValue';
- ?TransferRange -> 'TransferRange';
- ?JPEGProc -> 'JPEGProc';
- ?JPEGInterchangeFormat -> 'JPEGInterchangeFormat';
- ?JPEGInterchangeFormatLength -> 'JPEGInterchangeFormatLength';
- ?JPEGRestartInterval -> 'JPEGRestartInterval';
- ?JPEGLosslessPredictors -> 'JPEGLosslessPredictors';
- ?JPEGPointTransforms -> 'JPEGPointTransforms';
- ?JPEGQTables -> 'JPEGQTables';
- ?JPEGDCTables -> 'JPEGDCTables';
- ?JPEGACTables -> 'JPEGACTables';
- ?YCbCrCoefficients -> 'YCbCrCoefficients';
- ?YCbCrSampling -> 'YCbCrSampling';
- ?YCbCrPositioning -> 'YCbCrPositioning';
- ?ReferenceBlackWhite -> 'ReferenceBlackWhite';
- ?Copyright -> 'Copyright';
- ?ExifOffset -> 'ExifOffset';
- ?GPSInfo -> 'GPSInfo';
- _ -> Tag
- end.
-
-
-is_value(byte,N) when N =< 4 -> true;
-is_value(sbyte,N) when N =< 4 -> true;
-is_value(undefined,N) when N =< 4 -> true;
-is_value(ascii,N) when N =< 4 -> true;
-is_value(short,N) when N =< 2 -> true;
-is_value(sshort,N) when N =< 2 -> true;
-is_value(long,1) -> true;
-is_value(slong,1) -> true;
-is_value(float,1) -> true;
-is_value(_,_) -> false.
-
-%% calculate the size of the type
-sizeof(byte) -> 1;
-sizeof(ascii) -> 1;
-sizeof(short) -> 2;
-sizeof(long) -> 4;
-sizeof(rational) -> 8;
-sizeof(sbyte) -> 1;
-sizeof(undefined) -> 1;
-sizeof(sshort) -> 2;
-sizeof(slong) -> 4;
-sizeof(srational) -> 8;
-sizeof(float) -> 4;
-sizeof(double) -> 8;
-sizeof(_) -> 0.
-
-%% decode an offseted value
-decode_offs_value(Fd,Offset,Type,Endian,N) ->
- Sz = sizeof(Type)*N,
- case file:pread(Fd, Offset, Sz) of
- {ok,Bin} when size(Bin) == Sz ->
- decode_value(Type,Endian,N,Bin);
- {ok,_} ->
- {error, truncated};
- Error ->
- Error
- end.
-
-decode_value(_,_,0,_) -> [];
-
-%% little
-decode_value(short,little,I,<<V:16/little,VT/binary>>) ->
- [V|decode_value(short,little,I-1,VT)];
-
-decode_value(long,little,I,<<V:32/little,VT/binary>>) ->
- [V|decode_value(long, little,I-1,VT)];
-
-decode_value(rational,little,I, <<N:32/little,D:32/little,VT/binary>>) ->
- [{N,D}|decode_value(rational,little,I-1,VT)];
-
-decode_value(sshort,little,I,<<V:16/signed-little,VT/binary>>) ->
- [V|decode_value(sshort,little,I-1,VT)];
-
-decode_value(slong,little,I,<<V:32/signed-little,VT/binary>>) ->
- [V|decode_value(slong, little,I-1,VT)];
-
-decode_value(srational,little,I,
- <<N:32/signed-little,D:32/signed-little,VT/binary>>) ->
- [{N,D}|decode_value(srational,little,I-1,VT)];
-
-decode_value(float,little,I,<<V:32/little-float,VT/binary>>) ->
- [V|decode_value(float, little,I-1,VT)];
-
-decode_value(double,little,I,<<V:64/little-float,VT/binary>>) ->
- [V|decode_value(double,little,I-1,VT)];
-
-%% big
-decode_value(short,big,I,<<V:16/big,VT/binary>>) ->
- [V|decode_value(short,big,I-1,VT)];
-
-decode_value(long,big,I,<<V:32/big,VT/binary>>) ->
- [V|decode_value(long,big,I-1,VT)];
-
-decode_value(rational,big,I,<<N:32/big,D:32/big,VT/binary>>) ->
- [{N,D}|decode_value(rational,big,I-1,VT)];
-
-decode_value(sshort,big,I,<<V:16/signed-big,VT/binary>>) ->
- [V|decode_value(sshort,big,I-1,VT)];
-
-decode_value(slong,big,I,<<V:32/signed-big,VT/binary>>) ->
- [V|decode_value(slong,big,I-1,VT)];
-
-decode_value(srational,big,I,<<N:32/signed-big,D:32/signed-big,VT/binary>>) ->
- [{N,D}|decode_value(srational,big,I-1,VT)];
-
-decode_value(float,big,I,<<V:32/big-float,VT/binary>>) ->
- [V|decode_value(float,big,I-1,VT)];
-
-decode_value(double,big,I,<<V:64/big-float,VT/binary>>) ->
- [V|decode_value(double,big,I-1,VT)];
-
-%% Any endian single fields
-decode_value(sbyte,_Endian,N,Bin) ->
- <<V:N/binary,_/binary>> = Bin,
- map(fun(I) when I >= 16#80 -> I - 16#100;
- (I) -> I
- end, binary_to_list(V));
-
-
-decode_value(byte,_Endian,N,Bin) ->
- <<V:N/binary,_/binary>> = Bin,
- binary_to_list(V);
-decode_value(ascii,_Endian,N,Bin) ->
- <<V:N/binary,_/binary>> = Bin,
- decode_strings(binary_to_list(V));
-decode_value(undefined,_Endian,N,Bin) ->
- <<V:N/binary,_/binary>> = Bin,
- V;
-decode_value(unknown,_Endian,_N,Bin) ->
- Bin.
-
-
-%% decode a sequence of strings
-decode_strings(Cs) ->
- decode_strings(Cs,[],[]).
-
-decode_strings([0|Cs], String, Acc) ->
- decode_strings(Cs, [], [reverse(String)|Acc]);
-decode_strings([C|Cs], String, Acc) ->
- decode_strings(Cs, [C|String], Acc);
-decode_strings([], [], Acc) ->
- reverse(Acc);
-decode_strings([], String, Acc) ->
- reverse([reverse(String)|Acc]).
-
-
-
-undo_differencing(Data,2,r8g8b8a8,Width) ->
- undo_differencing4(Data, Width);
-undo_differencing(Data,2,r8g8b8,Width) ->
- undo_differencing3(Data, Width);
-undo_differencing(Data,_,_,_) ->
- Data.
-
-undo_differencing4(Data, Width) ->
- if is_binary(Data) ->
- undo_differencing4(0, Width, binary_to_list(Data),0,0,0,0, []);
- is_list(Data) ->
- undo_differencing4(0, Width, Data, 0,0,0,0, [])
- end.
-
-
-undo_differencing4(W, W, Rest, _,_,_,_,Ack) ->
- undo_differencing4(0,W, Rest, 0,0,0,0,Ack);
-undo_differencing4(C, W, [R,G,B,A|Rest], AR,AG,AB,AA, Ack) ->
- %% io:format("undo ~p ~n", [[{R,G,B,A}, {AR,AG,AB,AA}]]),
- RR = (R + AR) rem 256,
- RG = (G + AG) rem 256,
- RB = (B + AB) rem 256,
- RA = (A + AA) rem 256,
- undo_differencing4(C+1, W, Rest, RR,RG,RB,RA, [RA,RB,RG,RR|Ack]);
-undo_differencing4(_, _, [], _,_,_,_, Ack) ->
- list_to_binary(reverse(Ack)).
-
-
-undo_differencing3(Data, Width) ->
- if is_binary(Data) ->
- undo_differencing3(0, Width, binary_to_list(Data),0,0,0, []);
- is_list(Data) ->
- undo_differencing3(0, Width, Data, 0, 0, 0, [])
- end.
-
-undo_differencing3(W, W, Rest, _,_,_, Ack) ->
- undo_differencing3(0,W, Rest, 0,0,0, Ack);
-undo_differencing3(C, W, [R,G,B|Rest], AR,AG,AB, Ack) ->
- RR = (R + AR) rem 256,
- RG = (G + AG) rem 256,
- RB = (B + AB) rem 256,
- undo_differencing3(C+1, W, Rest, RR,RG,RB, [RB,RG,RR|Ack]);
-undo_differencing3(_, _, [], _,_,_, Ack) ->
- list_to_binary(reverse(Ack)).
-
-
-unpack_bits(Bin) ->
- unpack_bits(Bin, []).
-
-unpack_bits(<<>>, Acc) ->
- list_to_binary(lists:reverse(Acc));
-unpack_bits(<<128:8/signed,Tail/binary>>, Acc) ->
- unpack_bits(Tail, Acc);
-unpack_bits(<<Code:8/signed,Tail/binary>>, Acc) when Code >= 0 ->
- Count = Code + 1,
- <<Bin1:Count/binary, Tail1/binary>> = Tail,
- unpack_bits(Tail1, [Bin1|Acc]);
-unpack_bits(<<Code:8/signed,Tail/binary>>, Acc) ->
- Count = -Code + 1,
- <<Re:8, Tail1/binary>> = Tail,
- unpack_bits(Tail1, [list_to_binary(lists:duplicate(Count, Re))|Acc]).
Please sign in to comment.
Something went wrong with that request. Please try again.