File Coverage

blib/lib/Image/MetaData/JPEG/parsers/image.pl
Criterion Covered Total %
statement 66 66 100.0
branch 4 4 100.0
condition n/a
subroutine 12 12 100.0
pod 0 8 0.0
total 82 90 91.1


line stmt bran cond sub pod time code
1             ###########################################################
2             # A Perl package for showing/modifying JPEG (meta)data. #
3             # Copyright (C) 2004,2005,2006 Stefano Bettelli #
4             # See the COPYING and LICENSE files for license terms. #
5             ###########################################################
6 15     15   65 use Image::MetaData::JPEG::data::Tables qw();
  15         24  
  15         316  
7 15     15   56 no integer;
  15         17  
  15         58  
8 15     15   242 use strict;
  15         19  
  15         337  
9 15     15   51 use warnings;
  15         17  
  15         8453  
10              
11             ###########################################################
12             # This method parses a Quantization Table (DQT) segment, #
13             # which can specify one or more quantization tables. The #
14             # structure is the following: #
15             #------ multiple times -----------------------------------#
16             # 4 bits quantization table element precision #
17             # 4 bits quantization table destination identifier #
18             # 64 times quantization table elements #
19             #---------------------------------------------------------#
20             # Quantization table elements span either 1 or 2 bytes, #
21             # depending on the precision (0 -> 1 byte, 1 -> 2 bytes). #
22             ###########################################################
23             # Ref: "Digital compression and coding of continuous-tone #
24             # still images: requirements and guidelines", CCITT #
25             # recommendation T.81, 09/1992, pag. 39-40. #
26             ###########################################################
27             sub parse_dqt {
28 31     31 0 53 my ($this) = @_;
29 31         53 my $offset = 0;
30             # there can be multiple quantization tables
31 31         94 while ($offset < $this->size()) {
32             # read a byte, containing the quantization table element
33             # precision (first nibble) and the destination identifier.
34 86         281 my $precision = $this->store_record
35             ('PrecisionAndIdentifier', $NIBBLES, $offset)->get_value(0);
36             # Then decode the first four bits to get the size
37             # of the table (64 bytes or 128 bytes).
38 86 100       163 my $element_size = ($precision == 0) ? 1 : 2;
39 86         96 my $table_size = $element_size * 64;
40             # check that there is enough data
41 86         198 $this->test_size($offset + $table_size);
42             # read the table in (always 64 elements, but bytes or shorts)
43 85 100       259 $this->store_record('QuantizationTable',
44             $element_size == 1 ? $BYTE : $SHORT, $offset, 64);
45             }
46             }
47              
48             ###########################################################
49             # This method parses a Huffman table (DHT) segment, which #
50             # can specify one or more Huffman tables. The structure #
51             # is the following: #
52             #------ multiple times -----------------------------------#
53             # 4 bits table class #
54             # 4 bits destination identifier #
55             # 16 bytes number of Huffman codes of given length for #
56             # each of the 16 possible lengths. #
57             # ..... values associated with each Huffman code; #
58             # each value needs a byte, and the total number #
59             # of values is the sum of the previous 16 bytes #
60             ###########################################################
61             # Ref: "Digital compression and coding of continuous-tone #
62             # still images: requirements and guidelines", CCITT #
63             # recommendation T.81, 09/1992, pag. 40-41. #
64             ###########################################################
65             sub parse_dht {
66 70     70 0 83 my ($this) = @_;
67 70         72 my $offset = 0;
68 70         72 my $huffman_codes = 16;
69             # there can be multiple Huffman tables
70 70         159 while ($offset < $this->size()) {
71             # read a byte, containing the table class and destination
72 76         185 $this->store_record('ClassAndIdentifier', $NIBBLES, $offset);
73             # read the number of Huffman codes of length i
74             # (i in 1..16) as a single multi-valued record,
75             # then extract the sum of all these values
76 76         188 my $huffman_size = $this->store_record
77             ('CodeLengths', $BYTE, $offset, $huffman_codes)->get_value();
78             # extract of values associated with all Huffman codes
79             # as a single multi-valued record
80 76         346 $this->store_record('CodeData', $BYTE, $offset, $huffman_size);
81             }
82             # be sure there is no size mismatch
83 70         179 $this->test_size($offset);
84             }
85              
86             ###########################################################
87             # This method parses an Arithmetic Coding table (DAC) #
88             # segment, which can specify one or more arithmetic co- #
89             # ding conditioning tables (replacing the default one set #
90             # up by the SOI segment). The structure is the following: #
91             #------ multiple times -----------------------------------#
92             # 4 bits table class #
93             # 4 bits destination identifier #
94             # 1 byte conditioning table value #
95             #---------------------------------------------------------#
96             # It seems the arithmetic coding is covered by three pa- #
97             # tents by three different companies; since its gain over #
98             # the Huffman coding scheme is only 5-10%, in practise #
99             # you will never find this segment in your lifetime. #
100             ###########################################################
101             # Ref: "Digital compression and coding of continuous-tone #
102             # still images: requirements and guidelines", CCITT #
103             # recommendation T.81, 09/1992, sec.B.2.43, pag.42. #
104             ###########################################################
105             sub parse_dac {
106 2     2 0 2 my ($this) = @_;
107 2         3 my $offset = 0;
108             # there can be multiple Huffman tables
109 2         6 while ($offset < $this->size()) {
110             # read a byte, containing the table class and destination,
111             # then another byte with the conditioning table value
112 4         9 $this->store_record('ClassAndIdentifier' , $NIBBLES, $offset);
113 4         7 $this->store_record('ConditioningTableValue', $BYTE, $offset);
114             }
115             # be sure there is no size mismatch
116 1         5 $this->test_size($offset);
117             }
118              
119             ###########################################################
120             # This method parses an EXPansion segment (EXP), which #
121             # specifies horizontal and vertical expansion parameters #
122             # for the next frame. The structure is the following: #
123             #------ multiple times -----------------------------------#
124             # 4 bits horizontal expansion coefficient #
125             # 4 bits vertical expansion coefficient #
126             ###########################################################
127             # Ref: "Digital compression and coding of continuous-tone #
128             # still images: requirements and guidelines", CCITT #
129             # recommendation T.81, 09/1992, sec.B.3.3, pag.46. #
130             ###########################################################
131             sub parse_exp {
132 2     2 0 2 my ($this) = @_;
133             # this segments contains exactly one data byte
134 2         7 $this->test_size(-1);
135             # read a byte, containing both expansion coefficients
136 1         4 $this->store_record('ExpansionCoefficients', $NIBBLES, 0);
137             }
138              
139             ###########################################################
140             # This method parses a Define Num of Lines (DNL) segment. #
141             # Such a segment provides a mechanism for defining or re- #
142             # defining the number of lines in the frame at the end of #
143             # the first scan. This marker segment is mandatory if the #
144             # number of lines specified in the frame header has the #
145             # value zero. The structure is the following: #
146             #---------------------------------------------------------#
147             # 2 bytes number of lines in the frame. #
148             ###########################################################
149             # Ref: "Digital compression and coding of continuous-tone #
150             # still images: requirements and guidelines", CCITT #
151             # recommendation T.81, 09/1992, sec.B.2.5, pag.45. #
152             ###########################################################
153             sub parse_dnl {
154 3     3 0 4 my ($this) = @_;
155             # exactly two bytes, plese
156 3         8 $this->test_size(-2);
157             # read the number of lines
158 1         7 $this->store_record('NumberOfLines', $SHORT, 0);
159             }
160              
161             ###########################################################
162             # This method parses a Define Restart Interval (DRI) seg- #
163             # ment. There is only one parameter in this segment, and #
164             # it specifies the number of MCU (minimum coding units) #
165             # in the restart interval; a value equal to zero disables #
166             # the mechanism. The structure is the following: #
167             #---------------------------------------------------------#
168             # 2 bytes number of MCU in the restart interval. #
169             ###########################################################
170             # Ref: "Digital compression and coding of continuous-tone #
171             # still images: requirements and guidelines", CCITT #
172             # recommendation T.81, 09/1992, sec.B.2.4.4, pag.43.#
173             ###########################################################
174             sub parse_dri {
175 1     1 0 3 my ($this) = @_;
176             # exactly two bytes, plese
177 1         5 $this->test_size(-2);
178             # read the number of MCU in the interval
179 1         4 $this->store_record('NumMCU_inInterval', $SHORT, 0);
180             }
181              
182             ###########################################################
183             # This method parses a Start Of Frame (SOF) segment (but #
184             # also a DHP segment, see note at the end). Such a seg- #
185             # ment specifies the source image characteristics, the #
186             # components in the frame, and the sampling factors for #
187             # each components, and specifies the destinations from #
188             # which the quantised tables to be used with each compo- #
189             # nent are retrieved. The structure is: #
190             #---------------------------------------------------------#
191             # 1 byte sample precision (in bits) #
192             # 2 bytes maximum number of lines in source image #
193             # 2 bytes max. num. of samples per line in source image #
194             # 1 byte number N of image components in frame #
195             #------ N times ------------------------------------------#
196             # 1 byte component identifier #
197             # 4 bits horizontal sampling factor #
198             # 4 bits vertical sampling factor #
199             # 1 byte quantisation table destination selector #
200             #=========================================================#
201             # A DHP segment defines the image components, size and #
202             # sampling factors for the completed hierarchical sequence#
203             # of frames. It precedes the first frame, and its struc- #
204             # ture is identical to the frame header syntax, except #
205             # that the quantisation table destination selector is 0. #
206             #=========================================================#
207             # The meaning of the different SOF segments is this: #
208             # #
209             # / Baseline \ (extended) Progressive Lossless #
210             # \ SOF_0 / sequential #
211             # #
212             # (normal) SOF_1 SOF_2 SOF_3 #
213             # Differential SOF_5 SOF_6 SOF_7 #
214             # Arithmetic coding SOF_9 SOF_A SOF_B #
215             # Diff., arithm.cod. SOF_D SOF_E SOF_F #
216             #=========================================================#
217             # Ref: "Digital compression and coding of continuous-tone #
218             # still images: requirements and guidelines", CCITT #
219             # recommendation T.81, 09/1992, sec.B.2.2, pag.35-36#
220             # (DHP --> sec. B.3.2, pag. 46). #
221             ###########################################################
222             sub parse_sof {
223 29     29 0 51 my ($this) = @_;
224 29         40 my $offset = 0;
225 29         38 my $minimum_size = 6;
226             # at least six bytes, plese
227 29         88 $this->test_size($minimum_size);
228             # read the first four values (the last value is
229             # the number of image components in this frame)
230 29         88 $this->store_record('SamplePrecision' , $BYTE , $offset);
231 29         86 $this->store_record('MaxLineNumber' , $SHORT, $offset);
232 29         84 $this->store_record('MaxSamplesPerLine', $SHORT, $offset);
233 29         89 my $components = $this->store_record
234             ('ImageComponents', $BYTE , $offset)->get_value();
235             # the number of image components allows us to calculate
236             # the size of the remaining part of the segment
237 29         119 $this->test_size($offset + 3*$components, "in component block");
238             # scan all the frame component
239 29         74 for (1..$components) {
240             # three values per component
241 39         111 $this->store_record('ComponentIdentifier' , $BYTE , $offset);
242 39         102 $this->store_record('SamplingFactors' , $NIBBLES, $offset);
243 39         99 $this->store_record('QTDestinationSelector', $BYTE , $offset);
244             }
245             }
246              
247             ###########################################################
248             # This method parses the Start Of Scan (SOS) segment: it #
249             # gives various scan-related parameters and introduces #
250             # the JPEG raw data. The structure is the following: #
251             #---------------------------------------------------------#
252             # 1 byte number n of components in scan #
253             #------------ n times ----------------------------------- #
254             # 1 byte scan component selector #
255             # 4 bits DC entropy coding table destination selector #
256             # 4 bits AC entropy coding table destination selector #
257             #---------------------------------------------------------#
258             # 1 byte start of spectral or prediction selection #
259             # 1 byte end of spectral selection #
260             # 2 nibbles Successive approximation bit position #
261             ###########################################################
262             # Ref: "Digital compression and coding of continuous-tone #
263             # still images: requirements and guidelines", CCITT #
264             # recommendation T.81, 09/1992, pag. 37-38. #
265             ###########################################################
266             sub parse_sos {
267 51     51 0 64 my ($this) = @_;
268 51         68 my $offset = 0;
269             # read the number of components in the scan and calculate
270             # the length of this segment; then, compare with what we
271             # have in reality and produce an error if they differ
272 51         142 my $components = $this->store_record
273             ('ScanComponents', $BYTE, $offset)->get_value();
274 51         187 $this->test_size(-(1 + $components * 2 + 3));
275             # Read two bytes for each component. The first byte is the
276             # scan component selector (as numbered in the frame header);
277             # the second byte contains the DC/AC entropy coding table
278             # destination selector (a nibble each).
279 51         114 for (1..$components) {
280 65         152 $this->store_record('ComponentSelector', $BYTE, $offset);
281 65         157 $this->store_record('EntropySelector' , $NIBBLES, $offset); }
282             # the meaning of the last three bytes is the following:
283             # 1) Start of spectral or prediction selection
284             # 2) End of spectral selection
285             # 3) Successive approximation bit position (2 nibbles)
286 51         145 $this->store_record('SpectralSelectionStart' , $BYTE, $offset);
287 51         125 $this->store_record('SpectralSelectionEnd' , $BYTE, $offset);
288 51         126 $this->store_record('SuccessiveApproxBitPosition', $NIBBLES, $offset);
289             }
290              
291             # successful load
292             1;