Ksharp, Please try it again with the following code. There was definitely something wrong with the code, particularly how it identified a second set of tags:
%let path=c:\art\;
options datestyle=ymd;
proc format;
value ttwo 18761='pibr2.'
19789='s370fpib2.';
value tfour 18761='pibr4.'
19789='s370fpib4.';
run;
filename indata pipe "dir &path.*.jpg /b";
data want (keep=picture dt_taken coordinates title
width height);
length fil2read title $80;
retain _exif_pattern_num;
format dt_taken datetime19.;
format lat lon $1.;
length coordinates $35;
infile indata truncover;
if _n_ = 1 then _exif_pattern_num=
PRXPARSE("/\x45\x78\x69\x66/");
informat f2r $50.;
input f2r;
fil2read="&path."||f2r;
done=0;
infile dummy filevar=fil2read RECFM=n lrecl=12000
end=done;
picture=fil2read;
do while(not done);
input VAR1 $char12000.;
POSITIONX = PRXMATCH(_EXIF_PATTERN_NUM,var1)+6;
endian2=put(input(substr(var1,positionx,2),pibr2.),ttwo.);
endian4=put(input(substr(var1,positionx,2),pibr2.),tfour.);
numberx=inputn(substr(var1,positionx+inputn(substr(
var1,positionx+4,4),endian4),2),endian2);
offset=positionx+inputn(substr(var1,positionx+4,4),
endian4)+2;
gps_offset=0;
subject_offset=0;
date_offset=0;
last_offset=0;
do i=0 to numberx-1;
xtag=inputn(substr(var1,offset+i*12,2),endian2);
if xtag eq 34665 then do;
numberx2=positionx+inputn(substr(
var1,offset+i*12+8,4),endian4);
last_offset=positionx+inputn(substr(
var1,offset+i*12+8,4),endian4)+2;
end;
else if xtag eq 34853 then do;
gps_bytes=inputn(substr(var1,offset+i*12+2,2),
endian2);
if gps_bytes eq 2 then gps_offset=positionx+
inputn(substr(var1,offset+i*12+10,2),endian2);
else gps_offset=positionx+
inputn(substr(var1,offset+i*12+8,4),endian4);
end;
else if xtag eq 40091 then do;
title_offset=positionx+inputn(substr(
var1,offset+i*12+8,4),endian4);
title_length=inputn(substr(
var1,offset+i*12+4,4),endian4);
end;
end;
if last_offset then do;
do i=0 to numberx2-1;
xtag=inputn(substr(var1,last_offset+i*12,2),endian2);
if xtag eq 36867 then date_offset=
inputn(substr(
var1,last_offset+i*12+8,4),endian4);
else if xtag eq 40962 then width=
inputn(substr(
var1,last_offset+i*12+8,4),endian4);
else if xtag eq 40963 then height=
inputn(substr(
var1,last_offset+i*12+8,4),endian4);
end;
end;
if title_offset then title=compress(input(substr(
var1,title_offset,title_length),$50.),
"/ ?+#$%&","knp");
else title="No Title";
if gps_offset then do;
numberx=inputn(substr(var1,gps_offset,2),endian2);
offset=gps_offset+2;
do i=0 to numberx-1;
xtag=inputn(substr(var1,offset+i*12,2),endian2);
if xtag eq 1 then lat=input(substr(
var1,offset+i*12+8,1),$1.);
else if xtag eq 2 then do;
lat_offset=positionx+inputn(substr(var1,
offset+i*12+8,2),endian4);
latdeg=inputn(substr(var1,lat_offset+ 0,4),endian4)/
inputn(substr(var1,lat_offset+ 4,4),endian4);
latmin=inputn(substr(var1,lat_offset+ 8,4),endian4)/
inputn(substr(var1,lat_offset+12,4),endian4);
latsec=inputn(substr(var1,lat_offset+16,4),endian4)/
inputn(substr(var1,lat_offset+20,4),endian4);
end;
else if xtag eq 3 then lon=input(substr(
var1,offset+i*12+8,1),$1.);
else if xtag eq 4 then do;
lon_offset=positionx+inputn(substr(var1,
offset+i*12+8,2),endian4);
londeg=inputn(substr(var1,lon_offset+ 0,4),endian4)/
inputn(substr(var1,lon_offset+ 4,4),endian4);
lonmin=inputn(substr(var1,lon_offset+ 8,4),endian4)/
inputn(substr(var1,lon_offset+12,4),endian4);
lonsec=inputn(substr(var1,lon_offset+16,4),endian4)/
inputn(substr(var1,lon_offset+20,4),endian4);
end;
end;
coordinates=strip(put(latdeg,best12.))||" "||
strip(put(latmin,best12.))||"' "||
strip(put(latsec,best12.))||'" '||
strip(lat)||","||
strip(put(londeg,best12.))||" "||
strip(put(lonmin,best12.))||"' "||
strip(put(lonsec,best12.))||'" '||
strip(lon);
end;
else coordinates="No GPS";
if date_offset then dt_taken=
input(substr(var1,positionx+date_offset,19),anydtdtm19.);
else dt_taken=0;
output;
done=1;
end;
run;
Ksharp, One additional note: DON'T use window's explorer to modify the jpg file. It has a tendency to REALLY corrupt the exif portion of the file. Usually will only affect the height, width and date settings (at least regarding the settings that my code is attempting to parse) but, other than title and gps coordinates, those are the only fields I am trying to extract.
A MUCH safer way of changing the file's attributes is to use one of the proven perl-based routines, such as
http://www.sno.phy.queensu.ca/~phil/exiftool/) which, by the way, is free and has a windows executable version.
Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.
Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.