| 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 |  | 96 | use Image::MetaData::JPEG::data::Tables qw(); | 
|  | 15 |  |  |  |  | 114 |  | 
|  | 15 |  |  |  |  | 332 |  | 
| 7 | 15 |  |  | 15 |  | 78 | no  integer; | 
|  | 15 |  |  |  |  | 33 |  | 
|  | 15 |  |  |  |  | 87 |  | 
| 8 | 15 |  |  | 15 |  | 336 | use strict; | 
|  | 15 |  |  |  |  | 34 |  | 
|  | 15 |  |  |  |  | 458 |  | 
| 9 | 15 |  |  | 15 |  | 76 | use warnings; | 
|  | 15 |  |  |  |  | 32 |  | 
|  | 15 |  |  |  |  | 12745 |  | 
| 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 | 27 |  |  | 27 | 0 | 62 | my ($this) = @_; | 
| 29 | 27 |  |  |  |  | 54 | my $offset = 0; | 
| 30 |  |  |  |  |  |  | # there can be multiple quantization tables | 
| 31 | 27 |  |  |  |  | 135 | while ($offset < $this->size()) { | 
| 32 |  |  |  |  |  |  | # read a byte, containing the quantization table element | 
| 33 |  |  |  |  |  |  | # precision (first nibble) and the destination identifier. | 
| 34 | 82 |  |  |  |  | 299 | 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 | 82 | 100 |  |  |  | 215 | my $element_size = ($precision == 0) ? 1 : 2; | 
| 39 | 82 |  |  |  |  | 132 | my $table_size = $element_size * 64; | 
| 40 |  |  |  |  |  |  | # check that there is enough data | 
| 41 | 82 |  |  |  |  | 284 | $this->test_size($offset + $table_size); | 
| 42 |  |  |  |  |  |  | # read the table in (always 64 elements, but bytes or shorts) | 
| 43 | 81 | 100 |  |  |  | 397 | $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 | 56 |  |  | 56 | 0 | 100 | my ($this) = @_; | 
| 67 | 56 |  |  |  |  | 92 | my $offset = 0; | 
| 68 | 56 |  |  |  |  | 76 | my $huffman_codes = 16; | 
| 69 |  |  |  |  |  |  | # there can be multiple Huffman tables | 
| 70 | 56 |  |  |  |  | 202 | while ($offset < $this->size()) { | 
| 71 |  |  |  |  |  |  | # read a byte, containing the table class and destination | 
| 72 | 62 |  |  |  |  | 433 | $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 | 62 |  |  |  |  | 237 | 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 | 62 |  |  |  |  | 410 | $this->store_record('CodeData', $BYTE, $offset, $huffman_size); | 
| 81 |  |  |  |  |  |  | } | 
| 82 |  |  |  |  |  |  | # be sure there is no size mismatch | 
| 83 | 56 |  |  |  |  | 222 | $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 | 3 | my ($this) = @_; | 
| 107 | 2 |  |  |  |  | 4 | my $offset = 0; | 
| 108 |  |  |  |  |  |  | # there can be multiple Huffman tables | 
| 109 | 2 |  |  |  |  | 7 | 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 |  |  |  |  | 13 | $this->store_record('ClassAndIdentifier'    , $NIBBLES, $offset); | 
| 113 | 4 |  |  |  |  | 10 | $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 | 3 | my ($this) = @_; | 
| 133 |  |  |  |  |  |  | # this segments contains exactly one data byte | 
| 134 | 2 |  |  |  |  | 10 | $this->test_size(-1); | 
| 135 |  |  |  |  |  |  | # read a byte, containing both expansion coefficients | 
| 136 | 1 |  |  |  |  | 9 | $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 | 6 | my ($this) = @_; | 
| 155 |  |  |  |  |  |  | # exactly two bytes, plese | 
| 156 | 3 |  |  |  |  | 12 | $this->test_size(-2); | 
| 157 |  |  |  |  |  |  | # read the number of lines | 
| 158 | 1 |  |  |  |  | 6 | $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 | 4 | my ($this) = @_; | 
| 176 |  |  |  |  |  |  | # exactly two bytes, plese | 
| 177 | 1 |  |  |  |  | 8 | $this->test_size(-2); | 
| 178 |  |  |  |  |  |  | # read the number of MCU in the interval | 
| 179 | 1 |  |  |  |  | 5 | $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 | 27 |  |  | 27 | 0 | 56 | my ($this) = @_; | 
| 224 | 27 |  |  |  |  | 52 | my $offset = 0; | 
| 225 | 27 |  |  |  |  | 44 | my $minimum_size = 6; | 
| 226 |  |  |  |  |  |  | # at least six bytes, plese | 
| 227 | 27 |  |  |  |  | 112 | $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 | 27 |  |  |  |  | 125 | $this->store_record('SamplePrecision'  , $BYTE , $offset); | 
| 231 | 27 |  |  |  |  | 124 | $this->store_record('MaxLineNumber'    , $SHORT, $offset); | 
| 232 | 27 |  |  |  |  | 149 | $this->store_record('MaxSamplesPerLine', $SHORT, $offset); | 
| 233 | 27 |  |  |  |  | 114 | 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 | 27 |  |  |  |  | 148 | $this->test_size($offset + 3*$components, "in component block"); | 
| 238 |  |  |  |  |  |  | # scan all the frame component | 
| 239 | 27 |  |  |  |  | 90 | for (1..$components) { | 
| 240 |  |  |  |  |  |  | # three values per component | 
| 241 | 33 |  |  |  |  | 145 | $this->store_record('ComponentIdentifier'  , $BYTE   , $offset); | 
| 242 | 33 |  |  |  |  | 135 | $this->store_record('SamplingFactors'      , $NIBBLES, $offset); | 
| 243 | 33 |  |  |  |  | 160 | $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 | 40 |  |  | 40 | 0 | 85 | my ($this) = @_; | 
| 268 | 40 |  |  |  |  | 80 | 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 | 40 |  |  |  |  | 195 | my $components = $this->store_record | 
| 273 |  |  |  |  |  |  | ('ScanComponents', $BYTE, $offset)->get_value(); | 
| 274 | 40 |  |  |  |  | 212 | $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 | 40 |  |  |  |  | 211 | for (1..$components) { | 
| 280 | 48 |  |  |  |  | 165 | $this->store_record('ComponentSelector', $BYTE,    $offset); | 
| 281 | 48 |  |  |  |  | 187 | $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 | 40 |  |  |  |  | 166 | $this->store_record('SpectralSelectionStart'     , $BYTE,    $offset); | 
| 287 | 40 |  |  |  |  | 148 | $this->store_record('SpectralSelectionEnd'       , $BYTE,    $offset); | 
| 288 | 40 |  |  |  |  | 161 | $this->store_record('SuccessiveApproxBitPosition', $NIBBLES, $offset); | 
| 289 |  |  |  |  |  |  | } | 
| 290 |  |  |  |  |  |  |  | 
| 291 |  |  |  |  |  |  | # successful load | 
| 292 |  |  |  |  |  |  | 1; |