| 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; |