Question
Assignment 11: JPEG Information Extractor Goals Practice with binary I/O in Java. Get a feel for working with binary file formats. Prerequisites This assignment requires
Assignment 11: JPEG Information Extractor
Goals
Practice with binary I/O in Java.
Get a feel for working with binary file formats.
Prerequisites
This assignment requires knowledge of the material presented in class through week 11 and/or sections on binary I/O and exception handling in the various textbooks.
Background: JPEG File Interchange Format (JFIF)
The structure of all JPEG fileswhether they were created in an image editing program, produced by a digital camera of some kind, etc.is specified by a standard called the JPEG File Interchange Format (JFIF). These are files that you're probably accustomed to seeing with the file extension .jpg or .jpeg.
The following is adapted from the arbiter of all human information's article on the JFIF, as well as the official JFIF specification. All numbers are in hexadecimal, unless otherwise specified.
Overall Format
A JFIF file consists of a sequence of markers or marker segments. Each marker consists of two bytes: an FF byte followed by a byte which is not equal to 00 or FF and specifies the type of the marker. For example, the start of image segment is specified by the marker FF D8. Some markers stand alone (specifically, markers FF D0 through FF D9), but most indicate the start of a marker segment that contains data bytes according to the following pattern:
FF xx s1 s2 [data bytes]
The bytes s1 and s2 are taken together to represent a big-endian 16-bit integer specifying the length of the following data bytes plus the 2 bytes used to represent the length. In other words, s1 and s2 specify the number of the following data bytes as 256 * s1 + s2 - 2, where 256 is in decimal.
The general structure of a valid JFIF file is then as follows, in the specified order:
Segment | Marker (and byte pattern, if applicable) | Description |
---|---|---|
SOI (must be at the beginning of the file) | FF D8 | Start of Image |
JFIF-APP0 (must immediately follow the SOI marker) | FF E0 s1 s2 4A 46 49 46 00 | Image metadata |
JFXX-APP0 | FF E0 s1 s2 4A 46 58 58 00 | Optional |
additional marker segments (for example SOF, DHT, COM) in any order | ||
SOS | FF DA | Start of Scan |
compressed image data | ||
EOI | FF D9 | End of Image |
JFIF-APP0 Marker Segment
The metadata/parameters of the image are specified in the mandatory JFIF-APP0 marker segment. An uncompressed thumbnail can also be embedded, optionally.
Field | Size (bytes) | Description |
---|---|---|
APP0 marker | 2 | FF E0 |
Length | 2* | Length of segment excluding APP0 marker |
Identifier | 5 | 4A 46 49 46 00 = JFIF in ASCII, terminated by a null byte |
JFIF version | 2 | First byte for major version, second byte for minor version (01 02 for 1.02) |
Density units | 1 | Units for the following pixel density fields: 00 : Pixels (px) 01 : Pixels per inch (ppi) 02 : Pixels per centimeter (ppcm) |
Xdensity | 2* | Horizontal pixel density. Must not be zero. |
Ydensity | 2* | Vertical pixel density. Must not be zero. |
Xthumbnail | 1 | Horizontal pixel count of the following embedded RGB thumbnail. May be zero. |
Ythumbnail | 1 | Vertical pixel count of the following embedded RGB thumbnail. May be zero. |
Thumbnail data | 3 * n | Uncompressed 24-bit RGB (8 bits per color channel) raster thumbnail data in the order R0, G0, B0, Rn-1, Gn-1, Bn-1; with n = Xthumbnail Ythumbnail. |
SOF Marker Segment
The resolution (width and height in pixels) of a JPEG image can be found in a SOF (Start of Frame) marker segment. Your program needs to find a SOF marker segment in order to determine the image resolution.The structure of a SOF segment is as follows:
Field | Size (bytes) | Description |
---|---|---|
SOF marker | 2 | A value between FF C0 and FF CF1). |
Length | 2* | Length of segment excluding SOF marker |
Precision | 1 | Precision (bits per pixel per color component) |
Image Height | 2* | Image height (in pixels) |
Image Height | 2* | Image width (in pixels) |
(more information, not relevant to this assignment) |
*Decoding Integers
All 2-byte (16-bit) integers in the JFIF format (segment data length, image height, etc.) can be computed in Java as follows2):
A 16-bit integer is composed of two bytes; let's call them B1 and B2:
B1 B2
Together, the two bytes represent an integer that can be computed as:
B1 * 256 + B2
where 256 is in decimal.
For example, if a 16-bit integer is represented as:
02 F9
the value of that integer (in decimal) is:
2 * 256 + 249 = 761
Assignment
You shall write a Java program that expects one command-line argument indicating the path to a valid JFIF file containing a JPEG image. Your program shall then do the following:
If the program is able to find valid JFIF information in the file, print (to standard output) up to three facts about the file, each fact on its own line, as follows:
A line containing the word version describing the JFIF version specified in the 'APP0' segment, formatted as [major].[minor], where [major] is the major version number in decimal, and [minor] is the minor version number in decimal, to two digits (e.g. 1.05).
A line containing the word density describing the pixel density and units, as [Xdensity]x[Ydensity] [units]
where [Xdensity] and [Ydensity] are substituted with the horizontal and vertical pixel densities specified in the APP0 segment, respectively;
and [units] is either px for unit-less pixel density, ppi for pixels per inch or ppcm for pixels per centimeter.
A line containing the word resolution describing the JPEG image resolution specified in a SOF segment, formatted as [width]x[height], substituting [width] and [height] for the image width and height, respectively.
Getting the resolution correct by skipping irrelevant segments until finding and parsing a SOF segment (without simply finding it by brute force) is worth up to 50% extra credit.
The process for doing this should be roughly:
Make sure the file begins with a SOI marker. If so:
Make sure a JFIF-APP0 marker follows.
The JFIF-APP0 segment contains the version and density information.
Search for a SOF marker segment by proceeding from segment to segment. This can be accomplished without too much trouble: Since each segment begins with a two-byte integer specifying the segment's length, you can simply skip that many bytes and continue reading the next segment.
The SOF segment contains resolution information.
Otherwiseif no file is specified, or the file can't be read, or the file does not contain valid JFIF informationprint a one-line error message to standard error (i.e., System.err) and exit with a nonzero status code.
Determine the image resolution purely by reading through the binary file using java.io.FileInputStream. Do not use any third-party libraries or any parts of the Java API specifically designed for working with image files.
A sample executable named cs12j_jfif_info is available on the server. It replicates all of the expected behavior of your program, e.g.:
cs12j_jfif_info /usr/share/unicode/UnicodeData.txt cs12j_jfif_info /srv/datasets/logo.jpg cs12j_jfif_info /srv/datasets/logo.png cs12j_jfif_info /srv/datasets/the-room-poster.jpg cs12j_jfif_info /etc/shadow
Here is some code to get you startedfeel free to adapt:
for (String file : new String[] { "/srv/datasets/logo.jpg", "/srv/datasets/logo.png" }) { System.out.printf("%nFile: %s%n", file); FileInputStream input = new FileInputStream(file); if (input.read() == 0xff && input.read() == 0xd8) { System.out.println("I see the expected SOI marker"); if (input.read() == 0xff && input.read() == 0xe0) { int app0Length = input.read() * 256 + input.read() - 2; System.out.println("Looks like the JFIF-APP0 field is this long: " + app0Length); input.skip(app0Length); System.out.printf("Next two bytes are: %x %x%n", input.read(), input.read()); } else { System.out.println("Did not find an expected APP0 marker"); } } else { System.out.println("The file doesn't begin with the expected SOI marker"); } }
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started