//mobile and embedded /
entries, each with a structure that provides the data the directories hold.
Finally, the 8 bytes at the end link to the
next IFD, if there is one, or they contain all zeros, if there are no more IFDs.
Typically, this would mark the end of the
EXIF container as well.
Each directory entry follows the same
structure. The first 4 bytes (TTTT) represent a tag number that is relevant to the
type of IFD. Because we are concentrating on GPS IFDs, the first tag would be
0x0000, which represents the GPS version number. Thus, what we are saying
is that this directory entry contains the
GPS version number.
The next 4 bytes (FFFF) tell us the
format of this data. There are 12 different types of data formats, from ASCII, to
byte, to double float. Each type has its
own number, for example, ASCII is represented by the number 2 and unsigned
rational is represented by the number 5.
Thus, if this were the directory structure
for the GPS version number, these 4
bytes would contain the value 0x02 0x00.
The next 8 bytes are
NNNNNNNN, and they tell
us how many components
are available for this value.
Each data value might have
multiple components that
together make up the data.
Because the GPS version
number contains only a
single component, we would
just use the value 0x01 0x00
0x00 0x00.
Finally, the last 8 bytes
(DDDDDDDD) are where the
data is stored or they are the offset to
where the data is stored. For the GPS
version number, this is typically 0x32
0x32 0x00 0x00 (representing GPS version 2. 2.0.0).
LISTING 6 LISTING 7 LISTING 8 LISTING 9 LISTING 10
imageArray = videoControl.getSnapshot("encoding=jpeg");
// read it
ByteArrayInputStream bis = new ByteArrayInputStream(imageArray);
// for writing the modified array
ByteArrayOutputStream bos = new ByteArrayOutputStream();
COMMUNITY
Modifying the Image Data
In the prior sections, we gathered the
location data and took a snapshot. We
will gather this data in a byte array and
proceed to modify it, as shown in
Listing 6.
I haven’t shown it here, but we are
doing this process (including the taking
of the snapshot) in a separate thread
so we don’t block the main application.
(See the complete source code.)
Now we will go through this array one
byte at a time and modify it accordingly,
as shown in Listing 7.
The EXIF format uses the marker
0xE1. The image that we process using
the Sun Java Wireless Toolkit has the
marker 0xE0 to represent a
pure JPEG image. We replace
that with the E1 tag and then
write the total size (which we
calculate manually).
Then we write the familiar
Exif string to identify that we
are now writing an EXIF section. This is followed by the
mandatory TIFF header. See
Listing 8.
We then have the first IFD,
the GPS IFD, as shown in
Listing 9. Note that the GPS
JAVA IN ACTION
ABOUT US
Geotagging is
not enabled by
default in GPS-enabled devices,
so you need to write
your own special
application to add
the metadata.
Download all listings in this issue as text
IFD doesn’t contain the actual data, but
an offset to the location of the actual
GPS IFD structure, which starts with an
indication of how many entries it contains (three: version, latitude, and longitude) followed by the first entry (the GPS
version), as shown in Listing 10.
The next entry is the GPS latitude. See
Listing 11. Notice that it doesn’t actually
contain the data. It links to the data via
the offset.
blog
57
ORACLE.COM/JAVAMAGAZINE /////////////////////////////////////////////// MAY/JUNE 2012