Coverage Report

Created: 2026-02-26 06:18

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/guetzli/guetzli/jpeg_data_reader.cc
Line
Count
Source
1
/*
2
 * Copyright 2016 Google Inc.
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 * http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16
17
#include "guetzli/jpeg_data_reader.h"
18
19
#include <algorithm>
20
#include <stdio.h>
21
#include <string.h>
22
23
#include "guetzli/jpeg_huffman_decode.h"
24
25
namespace guetzli {
26
27
namespace {
28
29
// Macros for commonly used error conditions.
30
31
#define VERIFY_LEN(n)                                                   \
32
4.99M
  if (*pos + (n) > len) {                                               \
33
501
    fprintf(stderr, "Unexpected end of input: pos=%d need=%d len=%d\n", \
34
501
            static_cast<int>(*pos), static_cast<int>(n),                \
35
501
            static_cast<int>(len));                                     \
36
501
    jpg->error = JPEG_UNEXPECTED_EOF;                                   \
37
501
    return false;                                                       \
38
501
  }
39
40
#define VERIFY_INPUT(var, low, high, code)                              \
41
3.35M
  if (var < low || var > high) {                                        \
42
168
    fprintf(stderr, "Invalid %s: %d\n", #var, static_cast<int>(var));   \
43
168
    jpg->error = JPEG_INVALID_ ## code;                                 \
44
168
        return false;                                                   \
45
168
  }
46
47
#define VERIFY_MARKER_END()                                             \
48
41.1k
  if (start_pos + marker_len != *pos) {                                 \
49
151
    fprintf(stderr, "Invalid marker length: declared=%d actual=%d\n",   \
50
151
            static_cast<int>(marker_len),                               \
51
151
            static_cast<int>(*pos - start_pos));                        \
52
151
    jpg->error = JPEG_WRONG_MARKER_SIZE;                                \
53
151
    return false;                                                       \
54
151
  }
55
56
#define EXPECT_MARKER() \
57
7.12M
  if (pos + 2 > len || data[pos] != 0xff) {                             \
58
601
    fprintf(stderr, "Marker byte (0xff) expected, found: %d "           \
59
601
            "pos=%d len=%d\n",                                          \
60
601
            (pos < len ? data[pos] : 0), static_cast<int>(pos),         \
61
601
            static_cast<int>(len));                                     \
62
601
    jpg->error = JPEG_MARKER_BYTE_NOT_FOUND;                            \
63
601
    return false;                                                       \
64
601
  }
65
66
9.07M
inline int SignedLeftshift(int v, int s) {
67
9.07M
  return (v >= 0) ? (v << s) : -((-v) << s);
68
9.07M
}
69
70
// Returns ceil(a/b).
71
27.7k
inline int DivCeil(int a, int b) {
72
27.7k
  return (a + b - 1) / b;
73
27.7k
}
74
75
5.26M
inline int ReadUint8(const uint8_t* data, size_t* pos) {
76
5.26M
  return data[(*pos)++];
77
5.26M
}
78
79
2.26M
inline int ReadUint16(const uint8_t* data, size_t* pos) {
80
2.26M
  int v = (data[*pos] << 8) + data[*pos + 1];
81
2.26M
  *pos += 2;
82
2.26M
  return v;
83
2.26M
}
84
85
// Reads the Start of Frame (SOF) marker segment and fills in *jpg with the
86
// parsed data.
87
bool ProcessSOF(const uint8_t* data, const size_t len,
88
8.51k
                JpegReadMode mode, size_t* pos, JPEGData* jpg) {
89
8.51k
  if (jpg->width != 0) {
90
13
    fprintf(stderr, "Duplicate SOF marker.\n");
91
13
    jpg->error = JPEG_DUPLICATE_SOF;
92
13
    return false;
93
13
  }
94
8.50k
  const size_t start_pos = *pos;
95
8.50k
  VERIFY_LEN(8);
96
8.49k
  size_t marker_len = ReadUint16(data, pos);
97
8.49k
  int precision = ReadUint8(data, pos);
98
8.49k
  int height = ReadUint16(data, pos);
99
8.49k
  int width = ReadUint16(data, pos);
100
8.49k
  int num_components = ReadUint8(data, pos);
101
8.49k
  VERIFY_INPUT(precision, 8, 8, PRECISION);
102
8.48k
  VERIFY_INPUT(height, 1, 65535, HEIGHT);
103
8.47k
  VERIFY_INPUT(width, 1, 65535, WIDTH);
104
8.47k
  VERIFY_INPUT(num_components, 1, kMaxComponents, NUMCOMP);
105
8.46k
  VERIFY_LEN(3 * num_components);
106
8.45k
  jpg->height = height;
107
8.45k
  jpg->width = width;
108
8.45k
  jpg->components.resize(num_components);
109
110
  // Read sampling factors and quant table index for each component.
111
8.45k
  std::vector<bool> ids_seen(256, false);
112
28.8k
  for (size_t i = 0; i < jpg->components.size(); ++i) {
113
20.4k
    const int id = ReadUint8(data, pos);
114
20.4k
    if (ids_seen[id]) {   // (cf. section B.2.2, syntax of Ci)
115
1
      fprintf(stderr, "Duplicate ID %d in SOF.\n", id);
116
1
      jpg->error = JPEG_DUPLICATE_COMPONENT_ID;
117
1
      return false;
118
1
    }
119
20.4k
    ids_seen[id] = true;
120
20.4k
    jpg->components[i].id = id;
121
20.4k
    int factor = ReadUint8(data, pos);
122
20.4k
    int h_samp_factor = factor >> 4;
123
20.4k
    int v_samp_factor = factor & 0xf;
124
20.4k
    VERIFY_INPUT(h_samp_factor, 1, 15, SAMP_FACTOR);
125
20.4k
    VERIFY_INPUT(v_samp_factor, 1, 15, SAMP_FACTOR);
126
20.4k
    jpg->components[i].h_samp_factor = h_samp_factor;
127
20.4k
    jpg->components[i].v_samp_factor = v_samp_factor;
128
20.4k
    jpg->components[i].quant_idx = ReadUint8(data, pos);
129
20.4k
    jpg->max_h_samp_factor = std::max(jpg->max_h_samp_factor, h_samp_factor);
130
20.4k
    jpg->max_v_samp_factor = std::max(jpg->max_v_samp_factor, v_samp_factor);
131
20.4k
  }
132
133
  // We have checked above that none of the sampling factors are 0, so the max
134
  // sampling factors can not be 0.
135
8.45k
  jpg->MCU_rows = DivCeil(jpg->height, jpg->max_v_samp_factor * 8);
136
8.45k
  jpg->MCU_cols = DivCeil(jpg->width, jpg->max_h_samp_factor * 8);
137
  // Compute the block dimensions for each component.
138
8.45k
  if (mode == JPEG_READ_ALL) {
139
14.3k
    for (size_t i = 0; i < jpg->components.size(); ++i) {
140
10.1k
      JPEGComponent* c = &jpg->components[i];
141
10.1k
      if (jpg->max_h_samp_factor % c->h_samp_factor != 0 ||
142
10.1k
          jpg->max_v_samp_factor % c->v_samp_factor != 0) {
143
21
        fprintf(stderr, "Non-integral subsampling ratios.\n");
144
21
        jpg->error = JPEG_INVALID_SAMPLING_FACTORS;
145
21
        return false;
146
21
      }
147
10.1k
      c->width_in_blocks = jpg->MCU_cols * c->h_samp_factor;
148
10.1k
      c->height_in_blocks = jpg->MCU_rows * c->v_samp_factor;
149
10.1k
      const uint64_t num_blocks =
150
10.1k
          static_cast<uint64_t>(c->width_in_blocks) * c->height_in_blocks;
151
10.1k
      if (num_blocks > (1ull << 21)) {
152
        // Refuse to allocate more than 1 GB of memory for the coefficients,
153
        // that is 2M blocks x 64 coeffs x 2 bytes per coeff x max 4 components.
154
        // TODO(user) Add this limit to a GuetzliParams struct.
155
0
        fprintf(stderr, "Image too large.\n");
156
0
        jpg->error = JPEG_IMAGE_TOO_LARGE;
157
0
        return false;
158
0
      }
159
10.1k
      c->num_blocks = static_cast<int>(num_blocks);
160
10.1k
      c->coeffs.resize(c->num_blocks * kDCTBlockSize);
161
10.1k
    }
162
4.20k
  }
163
8.42k
  VERIFY_MARKER_END();
164
8.40k
  return true;
165
8.42k
}
166
167
// Reads the Start of Scan (SOS) marker segment and fills in *scan_info with the
168
// parsed data.
169
bool ProcessSOS(const uint8_t* data, const size_t len, size_t* pos,
170
6.28k
                JPEGData* jpg) {
171
6.28k
  const size_t start_pos = *pos;
172
6.28k
  VERIFY_LEN(3);
173
6.27k
  size_t marker_len = ReadUint16(data, pos);
174
6.27k
  int comps_in_scan = ReadUint8(data, pos);
175
6.27k
  VERIFY_INPUT(comps_in_scan, 1, static_cast<int>(jpg->components.size()),
176
6.27k
               COMPS_IN_SCAN);
177
178
6.25k
  JPEGScanInfo scan_info;
179
6.25k
  scan_info.components.resize(comps_in_scan);
180
6.25k
  VERIFY_LEN(2 * comps_in_scan);
181
6.24k
  std::vector<bool> ids_seen(256, false);
182
13.8k
  for (int i = 0; i < comps_in_scan; ++i) {
183
7.63k
    int id = ReadUint8(data, pos);
184
7.63k
    if (ids_seen[id]) {   // (cf. section B.2.3, regarding CSj)
185
2
      fprintf(stderr, "Duplicate ID %d in SOS.\n", id);
186
2
      jpg->error = JPEG_DUPLICATE_COMPONENT_ID;
187
2
      return false;
188
2
    }
189
7.62k
    ids_seen[id] = true;
190
7.62k
    bool found_index = false;
191
28.1k
    for (size_t j = 0; j < jpg->components.size(); ++j) {
192
20.5k
      if (jpg->components[j].id == id) {
193
7.61k
        scan_info.components[i].comp_idx = j;
194
7.61k
        found_index = true;
195
7.61k
      }
196
20.5k
    }
197
7.62k
    if (!found_index) {
198
13
      fprintf(stderr, "SOS marker: Could not find component with id %d\n", id);
199
13
      jpg->error = JPEG_COMPONENT_NOT_FOUND;
200
13
      return false;
201
13
    }
202
7.61k
    int c = ReadUint8(data, pos);
203
7.61k
    int dc_tbl_idx = c >> 4;
204
7.61k
    int ac_tbl_idx = c & 0xf;
205
7.61k
    VERIFY_INPUT(dc_tbl_idx, 0, 3, HUFFMAN_INDEX);
206
7.61k
    VERIFY_INPUT(ac_tbl_idx, 0, 3, HUFFMAN_INDEX);
207
7.60k
    scan_info.components[i].dc_tbl_idx = dc_tbl_idx;
208
7.60k
    scan_info.components[i].ac_tbl_idx = ac_tbl_idx;
209
7.60k
  }
210
6.21k
  VERIFY_LEN(3);
211
6.20k
  scan_info.Ss = ReadUint8(data, pos);
212
6.20k
  scan_info.Se = ReadUint8(data, pos);
213
6.20k
  VERIFY_INPUT(scan_info.Ss, 0, 63, START_OF_SCAN);
214
6.19k
  VERIFY_INPUT(scan_info.Se, scan_info.Ss, 63, END_OF_SCAN);
215
6.18k
  int c = ReadUint8(data, pos);
216
6.18k
  scan_info.Ah = c >> 4;
217
6.18k
  scan_info.Al = c & 0xf;
218
  // Check that all the Huffman tables needed for this scan are defined.
219
13.7k
  for (int i = 0; i < comps_in_scan; ++i) {
220
7.54k
    bool found_dc_table = false;
221
7.54k
    bool found_ac_table = false;
222
131k
    for (size_t j = 0; j < jpg->huffman_code.size(); ++j) {
223
124k
      int slot_id = jpg->huffman_code[j].slot_id;
224
124k
      if (slot_id == scan_info.components[i].dc_tbl_idx) {
225
32.3k
        found_dc_table = true;
226
91.7k
      } else if (slot_id == scan_info.components[i].ac_tbl_idx + 16) {
227
53.1k
        found_ac_table = true;
228
53.1k
      }
229
124k
    }
230
7.54k
    if (scan_info.Ss == 0 && !found_dc_table) {
231
11
      fprintf(stderr, "SOS marker: Could not find DC Huffman table with index "
232
11
              "%d\n", scan_info.components[i].dc_tbl_idx);
233
11
      jpg->error = JPEG_HUFFMAN_TABLE_NOT_FOUND;
234
11
      return false;
235
11
    }
236
7.53k
    if (scan_info.Se > 0 && !found_ac_table) {
237
10
      fprintf(stderr, "SOS marker: Could not find AC Huffman table with index "
238
10
              "%d\n", scan_info.components[i].ac_tbl_idx);
239
10
      jpg->error = JPEG_HUFFMAN_TABLE_NOT_FOUND;
240
10
      return false;
241
10
    }
242
7.53k
  }
243
6.16k
  jpg->scan_info.push_back(scan_info);
244
6.16k
  VERIFY_MARKER_END();
245
6.13k
  return true;
246
6.16k
}
247
248
// Reads the Define Huffman Table (DHT) marker segment and fills in *jpg with
249
// the parsed data. Builds the Huffman decoding table in either dc_huff_lut or
250
// ac_huff_lut, depending on the type and solt_id of Huffman code being read.
251
bool ProcessDHT(const uint8_t* data, const size_t len,
252
                JpegReadMode mode,
253
                std::vector<HuffmanTableEntry>* dc_huff_lut,
254
                std::vector<HuffmanTableEntry>* ac_huff_lut,
255
                size_t* pos,
256
19.4k
                JPEGData* jpg) {
257
19.4k
  const size_t start_pos = *pos;
258
19.4k
  VERIFY_LEN(2);
259
19.4k
  size_t marker_len = ReadUint16(data, pos);
260
19.4k
  if (marker_len == 2) {
261
1
    fprintf(stderr, "DHT marker: no Huffman table found\n");
262
1
    jpg->error = JPEG_EMPTY_DHT;
263
1
    return false;
264
1
  }
265
283k
  while (*pos < start_pos + marker_len) {
266
264k
    VERIFY_LEN(1 + kJpegHuffmanMaxBitLength);
267
264k
    JPEGHuffmanCode huff;
268
264k
    huff.slot_id = ReadUint8(data, pos);
269
264k
    int huffman_index = huff.slot_id;
270
264k
    int is_ac_table = (huff.slot_id & 0x10) != 0;
271
264k
    HuffmanTableEntry* huff_lut;
272
264k
    if (is_ac_table) {
273
14.4k
      huffman_index -= 0x10;
274
14.4k
      VERIFY_INPUT(huffman_index, 0, 3, HUFFMAN_INDEX);
275
14.4k
      huff_lut = &(*ac_huff_lut)[huffman_index * kJpegHuffmanLutSize];
276
250k
    } else {
277
250k
      VERIFY_INPUT(huffman_index, 0, 3, HUFFMAN_INDEX);
278
250k
      huff_lut = &(*dc_huff_lut)[huffman_index * kJpegHuffmanLutSize];
279
250k
    }
280
264k
    huff.counts[0] = 0;
281
264k
    int total_count = 0;
282
264k
    int space = 1 << kJpegHuffmanMaxBitLength;
283
264k
    int max_depth = 1;
284
4.49M
    for (int i = 1; i <= kJpegHuffmanMaxBitLength; ++i) {
285
4.23M
      int count = ReadUint8(data, pos);
286
4.23M
      if (count != 0) {
287
117k
        max_depth = i;
288
117k
      }
289
4.23M
      huff.counts[i] = count;
290
4.23M
      total_count += count;
291
4.23M
      space -= count * (1 << (kJpegHuffmanMaxBitLength - i));
292
4.23M
    }
293
264k
    if (is_ac_table) {
294
14.4k
      VERIFY_INPUT(total_count, 0, kJpegHuffmanAlphabetSize, HUFFMAN_CODE);
295
250k
    } else {
296
250k
      VERIFY_INPUT(total_count, 0, kJpegDCAlphabetSize, HUFFMAN_CODE);
297
250k
    }
298
264k
    VERIFY_LEN(total_count);
299
264k
    std::vector<bool> values_seen(256, false);
300
481k
    for (int i = 0; i < total_count; ++i) {
301
217k
      uint8_t value = ReadUint8(data, pos);
302
217k
      if (!is_ac_table) {
303
73.9k
        VERIFY_INPUT(value, 0, kJpegDCAlphabetSize - 1, HUFFMAN_CODE);
304
73.9k
      }
305
217k
      if (values_seen[value]) {
306
11
        fprintf(stderr, "Duplicate Huffman code value %d\n", value);
307
11
        jpg->error = JPEG_INVALID_HUFFMAN_CODE;
308
11
        return false;
309
11
      }
310
217k
      values_seen[value] = true;
311
217k
      huff.values[i] = value;
312
217k
    }
313
    // Add an invalid symbol that will have the all 1 code.
314
264k
    ++huff.counts[max_depth];
315
264k
    huff.values[total_count] = kJpegHuffmanAlphabetSize;
316
264k
    space -= (1 << (kJpegHuffmanMaxBitLength - max_depth));
317
264k
    if (space < 0) {
318
20
      fprintf(stderr, "Invalid Huffman code lengths.\n");
319
20
      jpg->error = JPEG_INVALID_HUFFMAN_CODE;
320
20
      return false;
321
264k
    } else if (space > 0 && huff_lut[0].value != 0xffff) {
322
      // Re-initialize the values to an invalid symbol so that we can recognize
323
      // it when reading the bit stream using a Huffman code with space > 0.
324
93.7M
      for (int i = 0; i < kJpegHuffmanLutSize; ++i) {
325
93.6M
        huff_lut[i].bits = 0;
326
93.6M
        huff_lut[i].value = 0xffff;
327
93.6M
      }
328
123k
    }
329
264k
    huff.is_last = (*pos == start_pos + marker_len);
330
264k
    if (mode == JPEG_READ_ALL &&
331
134k
        !BuildJpegHuffmanTable(&huff.counts[0], &huff.values[0], huff_lut)) {
332
0
      fprintf(stderr, "Failed to build Huffman table.\n");
333
0
      jpg->error = JPEG_INVALID_HUFFMAN_CODE;
334
0
      return false;
335
0
    }
336
264k
    jpg->huffman_code.push_back(huff);
337
264k
  }
338
19.1k
  VERIFY_MARKER_END();
339
19.0k
  return true;
340
19.1k
}
341
342
// Reads the Define Quantization Table (DQT) marker segment and fills in *jpg
343
// with the parsed data.
344
bool ProcessDQT(const uint8_t* data, const size_t len, size_t* pos,
345
6.85k
                JPEGData* jpg) {
346
6.85k
  const size_t start_pos = *pos;
347
6.85k
  VERIFY_LEN(2);
348
6.85k
  size_t marker_len = ReadUint16(data, pos);
349
6.85k
  if (marker_len == 2) {
350
1
    fprintf(stderr, "DQT marker: no quantization table found\n");
351
1
    jpg->error = JPEG_EMPTY_DQT;
352
1
    return false;
353
1
  }
354
13.6k
  while (*pos < start_pos + marker_len && jpg->quant.size() < kMaxQuantTables) {
355
6.90k
    VERIFY_LEN(1);
356
6.88k
    int quant_table_index = ReadUint8(data, pos);
357
6.88k
    int quant_table_precision = quant_table_index >> 4;
358
6.88k
    quant_table_index &= 0xf;
359
6.88k
    VERIFY_INPUT(quant_table_index, 0, 3, QUANT_TBL_INDEX);
360
6.88k
    VERIFY_LEN((quant_table_precision ? 2 : 1) * kDCTBlockSize);
361
6.84k
    JPEGQuantTable table;
362
6.84k
    table.index = quant_table_index;
363
6.84k
    table.precision = quant_table_precision;
364
444k
    for (int i = 0; i < kDCTBlockSize; ++i) {
365
437k
      int quant_val = quant_table_precision ?
366
8.21k
          ReadUint16(data, pos) :
367
437k
          ReadUint8(data, pos);
368
437k
      VERIFY_INPUT(quant_val, 1, 65535, QUANT_VAL);
369
437k
      table.values[kJPEGNaturalOrder[i]] = quant_val;
370
437k
    }
371
6.83k
    table.is_last = (*pos == start_pos + marker_len);
372
6.83k
    jpg->quant.push_back(table);
373
6.83k
  }
374
6.78k
  VERIFY_MARKER_END();
375
6.74k
  return true;
376
6.78k
}
377
378
// Reads the DRI marker and saved the restart interval into *jpg.
379
bool ProcessDRI(const uint8_t* data, const size_t len, size_t* pos,
380
671
                JPEGData* jpg) {
381
671
  if (jpg->restart_interval > 0) {
382
15
    fprintf(stderr, "Duplicate DRI marker.\n");
383
15
    jpg->error = JPEG_DUPLICATE_DRI;
384
15
    return false;
385
15
  }
386
656
  const size_t start_pos = *pos;
387
656
  VERIFY_LEN(4);
388
648
  size_t marker_len = ReadUint16(data, pos);
389
648
  int restart_interval = ReadUint16(data, pos);
390
648
  jpg->restart_interval = restart_interval;
391
648
  VERIFY_MARKER_END();
392
639
  return true;
393
648
}
394
395
// Saves the APP marker segment as a string to *jpg.
396
bool ProcessAPP(const uint8_t* data, const size_t len, size_t* pos,
397
1.77M
                JPEGData* jpg) {
398
1.77M
  VERIFY_LEN(2);
399
1.77M
  size_t marker_len = ReadUint16(data, pos);
400
1.77M
  VERIFY_INPUT(marker_len, 2, 65535, MARKER_LEN);
401
1.77M
  VERIFY_LEN(marker_len - 2);
402
  // Save the marker type together with the app data.
403
1.77M
  std::string app_str(reinterpret_cast<const char*>(
404
1.77M
      &data[*pos - 3]), marker_len + 1);
405
1.77M
  *pos += marker_len - 2;
406
1.77M
  jpg->app_data.push_back(app_str);
407
1.77M
  return true;
408
1.77M
}
409
410
// Saves the COM marker segment as a string to *jpg.
411
bool ProcessCOM(const uint8_t* data, const size_t len, size_t* pos,
412
418k
                JPEGData* jpg) {
413
418k
  VERIFY_LEN(2);
414
418k
  size_t marker_len = ReadUint16(data, pos);
415
418k
  VERIFY_INPUT(marker_len, 2, 65535, MARKER_LEN);
416
418k
  VERIFY_LEN(marker_len - 2);
417
418k
  std::string com_str(reinterpret_cast<const char*>(
418
418k
      &data[*pos - 2]), marker_len);
419
418k
  *pos += marker_len - 2;
420
418k
  jpg->com_data.push_back(com_str);
421
418k
  return true;
422
418k
}
423
424
// Helper structure to read bits from the entropy coded data segment.
425
struct BitReaderState {
426
  BitReaderState(const uint8_t* data, const size_t len, size_t pos)
427
6.13k
      : data_(data), len_(len) {
428
6.13k
    Reset(pos);
429
6.13k
  }
430
431
6.20k
  void Reset(size_t pos) {
432
6.20k
    pos_ = pos;
433
6.20k
    val_ = 0;
434
6.20k
    bits_left_ = 0;
435
6.20k
    next_marker_pos_ = len_ - 2;
436
6.20k
    FillBitWindow();
437
6.20k
  }
438
439
  // Returns the next byte and skips the 0xff/0x00 escape sequences.
440
23.0M
  uint8_t GetNextByte() {
441
23.0M
    if (pos_ >= next_marker_pos_) {
442
22.4M
      ++pos_;
443
22.4M
      return 0;
444
22.4M
    }
445
641k
    uint8_t c = data_[pos_++];
446
641k
    if (c == 0xff) {
447
5.62k
      uint8_t escape = data_[pos_];
448
5.62k
      if (escape == 0) {
449
2.93k
        ++pos_;
450
2.93k
      } else {
451
        // 0xff was followed by a non-zero byte, which means that we found the
452
        // start of the next marker segment.
453
2.69k
        next_marker_pos_ = pos_ - 1;
454
2.69k
      }
455
5.62k
    }
456
641k
    return c;
457
23.0M
  }
458
459
29.3M
  void FillBitWindow() {
460
29.3M
    if (bits_left_ <= 16) {
461
26.8M
      while (bits_left_ <= 56) {
462
23.0M
        val_ <<= 8;
463
23.0M
        val_ |= (uint64_t)GetNextByte();
464
23.0M
        bits_left_ += 8;
465
23.0M
      }
466
3.76M
    }
467
29.3M
  }
468
469
14.7M
  int ReadBits(int nbits) {
470
14.7M
    FillBitWindow();
471
14.7M
    uint64_t val = (val_ >> (bits_left_ - nbits)) & ((1ULL << nbits) - 1);
472
14.7M
    bits_left_ -= nbits;
473
14.7M
    return val;
474
14.7M
  }
475
476
  // Sets *pos to the next stream position where parsing should continue.
477
  // Returns false if the stream ended too early.
478
5.80k
  bool FinishStream(size_t* pos) {
479
    // Give back some bytes that we did not use.
480
5.80k
    int unused_bytes_left = bits_left_ >> 3;
481
38.4k
    while (unused_bytes_left-- > 0) {
482
32.6k
      --pos_;
483
      // If we give back a 0 byte, we need to check if it was a 0xff/0x00 escape
484
      // sequence, and if yes, we need to give back one more byte.
485
32.6k
      if (pos_ < next_marker_pos_ &&
486
10.1k
          data_[pos_] == 0 && data_[pos_ - 1] == 0xff) {
487
176
        --pos_;
488
176
      }
489
32.6k
    }
490
5.80k
    if (pos_ > next_marker_pos_) {
491
      // Data ran out before the scan was complete.
492
316
      fprintf(stderr, "Unexpected end of scan.\n");
493
316
      return false;
494
316
    }
495
5.49k
    *pos = pos_;
496
5.49k
    return true;
497
5.80k
  }
498
499
  const uint8_t* data_;
500
  const size_t len_;
501
  size_t pos_;
502
  uint64_t val_;
503
  int bits_left_;
504
  size_t next_marker_pos_;
505
};
506
507
// Returns the next Huffman-coded symbol.
508
14.6M
int ReadSymbol(const HuffmanTableEntry* table, BitReaderState* br) {
509
14.6M
  int nbits;
510
14.6M
  br->FillBitWindow();
511
14.6M
  int val = (br->val_ >> (br->bits_left_ - 8)) & 0xff;
512
14.6M
  table += val;
513
14.6M
  nbits = table->bits - 8;
514
14.6M
  if (nbits > 0) {
515
9.99M
    br->bits_left_ -= 8;
516
9.99M
    table += table->value;
517
9.99M
    val = (br->val_ >> (br->bits_left_ - nbits)) & ((1 << nbits) - 1);
518
9.99M
    table += val;
519
9.99M
  }
520
14.6M
  br->bits_left_ -= table->bits;
521
14.6M
  return table->value;
522
14.6M
}
523
524
// Returns the DC diff or AC value for extra bits value x and prefix code s.
525
// See Tables F.1 and F.2 of the spec.
526
9.03M
int HuffExtend(int x, int s) {
527
9.03M
  return (x < (1 << (s - 1)) ? x - (1 << s) + 1 : x);
528
9.03M
}
529
530
// Decodes one 8x8 block of DCT coefficients from the bit stream.
531
bool DecodeDCTBlock(const HuffmanTableEntry* dc_huff,
532
                    const HuffmanTableEntry* ac_huff,
533
                    int Ss, int Se, int Al,
534
                    int* eobrun,
535
                    BitReaderState* br,
536
                    JPEGData* jpg,
537
                    coeff_t* last_dc_coeff,
538
314k
                    coeff_t* coeffs) {
539
314k
  int s;
540
314k
  int r;
541
314k
  bool eobrun_allowed = Ss > 0;
542
314k
  if (Ss == 0) {
543
68.2k
    s = ReadSymbol(dc_huff, br);
544
68.2k
    if (s >= kJpegDCAlphabetSize) {
545
48
      fprintf(stderr, "Invalid Huffman symbol %d for DC coefficient.\n", s);
546
48
      jpg->error = JPEG_INVALID_SYMBOL;
547
48
      return false;
548
48
    }
549
68.2k
    if (s > 0) {
550
31.2k
      r = br->ReadBits(s);
551
31.2k
      s = HuffExtend(r, s);
552
31.2k
    }
553
68.2k
    s += *last_dc_coeff;
554
68.2k
    const int dc_coeff = SignedLeftshift(s, Al);
555
68.2k
    coeffs[0] = dc_coeff;
556
68.2k
    if (dc_coeff != coeffs[0]) {
557
24
      fprintf(stderr, "Invalid DC coefficient %d\n", dc_coeff);
558
24
      jpg->error = JPEG_NON_REPRESENTABLE_DC_COEFF;
559
24
      return false;
560
24
    }
561
68.1k
    *last_dc_coeff = s;
562
68.1k
    ++Ss;
563
68.1k
  }
564
314k
  if (Ss > Se) {
565
12.0k
    return true;
566
12.0k
  }
567
302k
  if (*eobrun > 0) {
568
40.6k
    --(*eobrun);
569
40.6k
    return true;
570
40.6k
  }
571
9.27M
  for (int k = Ss; k <= Se; k++) {
572
9.07M
    s = ReadSymbol(ac_huff, br);
573
9.07M
    if (s >= kJpegHuffmanAlphabetSize) {
574
36
      fprintf(stderr, "Invalid Huffman symbol %d for AC coefficient %d\n",
575
36
              s, k);
576
36
      jpg->error = JPEG_INVALID_SYMBOL;
577
36
      return false;
578
36
    }
579
9.07M
    r = s >> 4;
580
9.07M
    s &= 15;
581
9.07M
    if (s > 0) {
582
9.00M
      k += r;
583
9.00M
      if (k > Se) {
584
14
        fprintf(stderr, "Out-of-band coefficient %d band was %d-%d\n",
585
14
                k, Ss, Se);
586
14
        jpg->error = JPEG_OUT_OF_BAND_COEFF;
587
14
        return false;
588
14
      }
589
9.00M
      if (s + Al >= kJpegDCAlphabetSize) {
590
2
        fprintf(stderr, "Out of range AC coefficient value: s=%d Al=%d k=%d\n",
591
2
                s, Al, k);
592
2
        jpg->error = JPEG_NON_REPRESENTABLE_AC_COEFF;
593
2
        return false;
594
2
      }
595
9.00M
      r = br->ReadBits(s);
596
9.00M
      s = HuffExtend(r, s);
597
9.00M
      coeffs[kJPEGNaturalOrder[k]] = SignedLeftshift(s, Al);
598
9.00M
    } else if (r == 15) {
599
6.18k
      k += 15;
600
66.0k
    } else {
601
66.0k
      *eobrun = 1 << r;
602
66.0k
      if (r > 0) {
603
17.9k
        if (!eobrun_allowed) {
604
1
          fprintf(stderr, "End-of-block run crossing DC coeff.\n");
605
1
          jpg->error = JPEG_EOB_RUN_TOO_LONG;
606
1
          return false;
607
1
        }
608
17.9k
        *eobrun += br->ReadBits(r);
609
17.9k
      }
610
66.0k
      break;
611
66.0k
    }
612
9.07M
  }
613
261k
  --(*eobrun);
614
261k
  return true;
615
261k
}
616
617
bool RefineDCTBlock(const HuffmanTableEntry* ac_huff,
618
                    int Ss, int Se, int Al,
619
                    int* eobrun,
620
                    BitReaderState* br,
621
                    JPEGData* jpg,
622
310k
                    coeff_t* coeffs) {
623
310k
  bool eobrun_allowed = Ss > 0;
624
310k
  if (Ss == 0) {
625
72.3k
    int s = br->ReadBits(1);
626
72.3k
    coeff_t dc_coeff = coeffs[0];
627
72.3k
    dc_coeff |= s << Al;
628
72.3k
    coeffs[0] = dc_coeff;
629
72.3k
    ++Ss;
630
72.3k
  }
631
310k
  if (Ss > Se) {
632
72.2k
    return true;
633
72.2k
  }
634
238k
  int p1 = 1 << Al;
635
238k
  int m1 = -(1 << Al);
636
238k
  int k = Ss;
637
238k
  int r;
638
238k
  int s;
639
238k
  bool in_zero_run = false;
640
238k
  if (*eobrun <= 0) {
641
5.68M
    for (; k <= Se; k++) {
642
5.53M
      s = ReadSymbol(ac_huff, br);
643
5.53M
      if (s >= kJpegHuffmanAlphabetSize) {
644
72
        fprintf(stderr, "Invalid Huffman symbol %d for AC coefficient %d\n",
645
72
                s, k);
646
72
        jpg->error = JPEG_INVALID_SYMBOL;
647
72
        return false;
648
72
      }
649
5.53M
      r = s >> 4;
650
5.53M
      s &= 15;
651
5.53M
      if (s) {
652
5.49M
        if (s != 1) {
653
9
          fprintf(stderr, "Invalid Huffman symbol %d for AC coefficient %d\n",
654
9
                  s, k);
655
9
          jpg->error = JPEG_INVALID_SYMBOL;
656
9
          return false;
657
9
        }
658
5.49M
        s = br->ReadBits(1) ? p1 : m1;
659
5.49M
        in_zero_run = false;
660
5.49M
      } else {
661
37.2k
        if (r != 15) {
662
36.8k
          *eobrun = 1 << r;
663
36.8k
          if (r > 0) {
664
18.2k
            if (!eobrun_allowed) {
665
2
              fprintf(stderr, "End-of-block run crossing DC coeff.\n");
666
2
              jpg->error = JPEG_EOB_RUN_TOO_LONG;
667
2
              return false;
668
2
            }
669
18.2k
            *eobrun += br->ReadBits(r);
670
18.2k
          }
671
36.8k
          break;
672
36.8k
        }
673
344
        in_zero_run = true;
674
344
      }
675
5.99M
      do {
676
5.99M
        coeff_t thiscoef = coeffs[kJPEGNaturalOrder[k]];
677
5.99M
        if (thiscoef != 0) {
678
13.5k
          if (br->ReadBits(1)) {
679
1.49k
            if ((thiscoef & p1) == 0) {
680
1.49k
              if (thiscoef >= 0) {
681
367
                thiscoef += p1;
682
1.12k
              } else {
683
1.12k
                thiscoef += m1;
684
1.12k
              }
685
1.49k
            }
686
1.49k
          }
687
13.5k
          coeffs[kJPEGNaturalOrder[k]] = thiscoef;
688
5.98M
        } else {
689
5.98M
          if (--r < 0) {
690
5.49M
            break;
691
5.49M
          }
692
5.98M
        }
693
494k
        k++;
694
494k
      } while (k <= Se);
695
5.49M
      if (s) {
696
5.49M
        if (k > Se) {
697
15
          fprintf(stderr, "Out-of-band coefficient %d band was %d-%d\n",
698
15
                  k, Ss, Se);
699
15
          jpg->error = JPEG_OUT_OF_BAND_COEFF;
700
15
          return false;
701
15
        }
702
5.49M
        coeffs[kJPEGNaturalOrder[k]] = s;
703
5.49M
      }
704
5.49M
    }
705
188k
  }
706
238k
  if (in_zero_run) {
707
14
    fprintf(stderr, "Extra zero run before end-of-block.\n");
708
14
    jpg->error = JPEG_EXTRA_ZERO_RUN;
709
14
    return false;
710
14
  }
711
238k
  if (*eobrun > 0) {
712
3.56M
    for (; k <= Se; k++) {
713
3.47M
      coeff_t thiscoef = coeffs[kJPEGNaturalOrder[k]];
714
3.47M
      if (thiscoef != 0) {
715
44.5k
        if (br->ReadBits(1)) {
716
7.71k
          if ((thiscoef & p1) == 0) {
717
7.71k
            if (thiscoef >= 0) {
718
398
              thiscoef += p1;
719
7.32k
            } else {
720
7.32k
              thiscoef += m1;
721
7.32k
            }
722
7.71k
          }
723
7.71k
        }
724
44.5k
        coeffs[kJPEGNaturalOrder[k]] = thiscoef;
725
44.5k
      }
726
3.47M
    }
727
87.1k
  }
728
238k
  --(*eobrun);
729
238k
  return true;
730
238k
}
731
732
bool ProcessRestart(const uint8_t* data, const size_t len,
733
                    int* next_restart_marker, BitReaderState* br,
734
166
                    JPEGData* jpg) {
735
166
  size_t pos = 0;
736
166
  if (!br->FinishStream(&pos)) {
737
33
    jpg->error = JPEG_INVALID_SCAN;
738
33
    return false;
739
33
  }
740
133
  int expected_marker = 0xd0 + *next_restart_marker;
741
133
  EXPECT_MARKER();
742
93
  int marker = data[pos + 1];
743
93
  if (marker != expected_marker) {
744
21
    fprintf(stderr, "Did not find expected restart marker %d actual=%d\n",
745
21
            expected_marker, marker);
746
21
    jpg->error = JPEG_WRONG_RESTART_MARKER;
747
21
    return false;
748
21
  }
749
72
  br->Reset(pos + 2);
750
72
  *next_restart_marker += 1;
751
72
  *next_restart_marker &= 0x7;
752
72
  return true;
753
93
}
754
755
bool ProcessScan(const uint8_t* data, const size_t len,
756
                 const std::vector<HuffmanTableEntry>& dc_huff_lut,
757
                 const std::vector<HuffmanTableEntry>& ac_huff_lut,
758
                 uint16_t scan_progression[kMaxComponents][kDCTBlockSize],
759
                 bool is_progressive,
760
                 size_t* pos,
761
6.28k
                 JPEGData* jpg) {
762
6.28k
  if (!ProcessSOS(data, len, pos, jpg)) {
763
151
    return false;
764
151
  }
765
6.13k
  JPEGScanInfo* scan_info = &jpg->scan_info.back();
766
6.13k
  bool is_interleaved = (scan_info->components.size() > 1);
767
6.13k
  int MCUs_per_row;
768
6.13k
  int MCU_rows;
769
6.13k
  if (is_interleaved) {
770
686
    MCUs_per_row = jpg->MCU_cols;
771
686
    MCU_rows = jpg->MCU_rows;
772
5.44k
  } else {
773
5.44k
    const JPEGComponent& c = jpg->components[scan_info->components[0].comp_idx];
774
5.44k
    MCUs_per_row =
775
5.44k
        DivCeil(jpg->width * c.h_samp_factor, 8 * jpg->max_h_samp_factor);
776
5.44k
    MCU_rows =
777
5.44k
        DivCeil(jpg->height * c.v_samp_factor, 8 * jpg->max_v_samp_factor);
778
5.44k
  }
779
6.13k
  coeff_t last_dc_coeff[kMaxComponents] = {0};
780
6.13k
  BitReaderState br(data, len, *pos);
781
6.13k
  int restarts_to_go = jpg->restart_interval;
782
6.13k
  int next_restart_marker = 0;
783
6.13k
  int eobrun = -1;
784
6.13k
  int block_scan_index = 0;
785
6.13k
  const int Al = is_progressive ? scan_info->Al : 0;
786
6.13k
  const int Ah = is_progressive ? scan_info->Ah : 0;
787
6.13k
  const int Ss = is_progressive ? scan_info->Ss : 0;
788
6.13k
  const int Se = is_progressive ? scan_info->Se : 63;
789
6.13k
  const uint16_t scan_bitmask = Ah == 0 ? (0xffff << Al) : (1u << Al);
790
6.13k
  const uint16_t refinement_bitmask = (1 << Al) - 1;
791
13.5k
  for (size_t i = 0; i < scan_info->components.size(); ++i) {
792
7.45k
    int comp_idx = scan_info->components[i].comp_idx;
793
184k
    for (int k = Ss; k <= Se; ++k) {
794
176k
      if (scan_progression[comp_idx][k] & scan_bitmask) {
795
54
        fprintf(stderr, "Overlapping scans: component=%d k=%d prev_mask=%d "
796
54
                "cur_mask=%d\n", comp_idx, k, scan_progression[i][k],
797
54
                scan_bitmask);
798
54
        jpg->error = JPEG_OVERLAPPING_SCANS;
799
54
        return false;
800
54
      }
801
176k
      if (scan_progression[comp_idx][k] & refinement_bitmask) {
802
13
        fprintf(stderr, "Invalid scan order, a more refined scan was already "
803
13
                "done: component=%d k=%d prev_mask=%d cur_mask=%d\n", comp_idx,
804
13
                k, scan_progression[i][k], scan_bitmask);
805
13
        jpg->error = JPEG_INVALID_SCAN_ORDER;
806
13
        return false;
807
13
      }
808
176k
      scan_progression[comp_idx][k] |= scan_bitmask;
809
176k
    }
810
7.45k
  }
811
6.06k
  if (Al > 10) {
812
4
    fprintf(stderr, "Scan parameter Al=%d is not supported in guetzli.\n", Al);
813
4
    jpg->error = JPEG_NON_REPRESENTABLE_AC_COEFF;
814
4
    return false;
815
4
  }
816
97.3k
  for (int mcu_y = 0; mcu_y < MCU_rows; ++mcu_y) {
817
270k
    for (int mcu_x = 0; mcu_x < MCUs_per_row; ++mcu_x) {
818
      // Handle the restart intervals.
819
179k
      if (jpg->restart_interval > 0) {
820
10.2k
        if (restarts_to_go == 0) {
821
166
          if (ProcessRestart(data, len,
822
166
                             &next_restart_marker, &br, jpg)) {
823
72
            restarts_to_go = jpg->restart_interval;
824
72
            memset(last_dc_coeff, 0, sizeof(last_dc_coeff));
825
72
            if (eobrun > 0) {
826
3
              fprintf(stderr, "End-of-block run too long.\n");
827
3
              jpg->error = JPEG_EOB_RUN_TOO_LONG;
828
3
              return false;
829
3
            }
830
69
            eobrun = -1;   // fresh start
831
94
          } else {
832
94
            return false;
833
94
          }
834
166
        }
835
10.1k
        --restarts_to_go;
836
10.1k
      }
837
      // Decode one MCU.
838
395k
      for (size_t i = 0; i < scan_info->components.size(); ++i) {
839
215k
        JPEGComponentScanInfo* si = &scan_info->components[i];
840
215k
        JPEGComponent* c = &jpg->components[si->comp_idx];
841
215k
        const HuffmanTableEntry* dc_lut =
842
215k
            &dc_huff_lut[si->dc_tbl_idx * kJpegHuffmanLutSize];
843
215k
        const HuffmanTableEntry* ac_lut =
844
215k
            &ac_huff_lut[si->ac_tbl_idx * kJpegHuffmanLutSize];
845
215k
        int nblocks_y = is_interleaved ? c->v_samp_factor : 1;
846
215k
        int nblocks_x = is_interleaved ? c->h_samp_factor : 1;
847
614k
        for (int iy = 0; iy < nblocks_y; ++iy) {
848
1.02M
          for (int ix = 0; ix < nblocks_x; ++ix) {
849
625k
            int block_y = mcu_y * nblocks_y + iy;
850
625k
            int block_x = mcu_x * nblocks_x + ix;
851
625k
            int block_idx = block_y * c->width_in_blocks + block_x;
852
625k
            coeff_t* coeffs = &c->coeffs[block_idx * kDCTBlockSize];
853
625k
            if (Ah == 0) {
854
314k
              if (!DecodeDCTBlock(dc_lut, ac_lut, Ss, Se, Al, &eobrun, &br, jpg,
855
314k
                                  &last_dc_coeff[si->comp_idx], coeffs)) {
856
125
                return false;
857
125
              }
858
314k
            } else {
859
310k
              if (!RefineDCTBlock(ac_lut, Ss, Se, Al,
860
310k
                                  &eobrun, &br, jpg, coeffs)) {
861
112
                return false;
862
112
              }
863
310k
            }
864
624k
            ++block_scan_index;
865
624k
          }
866
398k
        }
867
215k
      }
868
179k
    }
869
91.6k
  }
870
5.72k
  if (eobrun > 0) {
871
87
    fprintf(stderr, "End-of-block run too long.\n");
872
87
    jpg->error = JPEG_EOB_RUN_TOO_LONG;
873
87
    return false;
874
87
  }
875
5.64k
  if (!br.FinishStream(pos)) {
876
283
    jpg->error = JPEG_INVALID_SCAN;
877
283
    return false;
878
283
  }
879
5.35k
  if (*pos > len) {
880
0
    fprintf(stderr, "Unexpected end of file during scan. pos=%d len=%d\n",
881
0
            static_cast<int>(*pos), static_cast<int>(len));
882
0
    jpg->error = JPEG_UNEXPECTED_EOF;
883
0
    return false;
884
0
  }
885
5.35k
  return true;
886
5.35k
}
887
888
// Changes the quant_idx field of the components to refer to the index of the
889
// quant table in the jpg->quant array.
890
2.66k
bool FixupIndexes(JPEGData* jpg) {
891
10.4k
  for (size_t i = 0; i < jpg->components.size(); ++i) {
892
7.79k
    JPEGComponent* c = &jpg->components[i];
893
7.79k
    bool found_index = false;
894
8.89k
    for (size_t j = 0; j < jpg->quant.size(); ++j) {
895
8.87k
      if (jpg->quant[j].index == c->quant_idx) {
896
7.78k
        c->quant_idx = j;
897
7.78k
        found_index = true;
898
7.78k
        break;
899
7.78k
      }
900
8.87k
    }
901
7.79k
    if (!found_index) {
902
14
      fprintf(stderr, "Quantization table with index %zd not found\n",
903
14
              c->quant_idx);
904
14
      jpg->error = JPEG_QUANT_TABLE_NOT_FOUND;
905
14
      return false;
906
14
    }
907
7.79k
  }
908
2.64k
  return true;
909
2.66k
}
910
911
7.11M
size_t FindNextMarker(const uint8_t* data, const size_t len, size_t pos) {
912
  // kIsValidMarker[i] == 1 means (0xc0 + i) is a valid marker.
913
7.11M
  static const uint8_t kIsValidMarker[] = {
914
7.11M
    1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
915
7.11M
    1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0,
916
7.11M
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
917
7.11M
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
918
7.11M
  };
919
7.11M
  size_t num_skipped = 0;
920
56.2M
  while (pos + 1 < len &&
921
56.2M
         (data[pos] != 0xff || data[pos + 1] < 0xc0 ||
922
49.1M
          !kIsValidMarker[data[pos + 1] - 0xc0])) {
923
49.1M
    ++pos;
924
49.1M
    ++num_skipped;
925
49.1M
  }
926
7.11M
  return num_skipped;
927
7.11M
}
928
929
}  // namespace
930
931
bool ReadJpeg(const uint8_t* data, const size_t len, JpegReadMode mode,
932
9.18k
              JPEGData* jpg) {
933
9.18k
  size_t pos = 0;
934
  // Check SOI marker.
935
9.18k
  EXPECT_MARKER();
936
9.16k
  int marker = data[pos + 1];
937
9.16k
  pos += 2;
938
9.16k
  if (marker != 0xd8) {
939
12
    fprintf(stderr, "Did not find expected SOI marker, actual=%d\n", marker);
940
12
    jpg->error = JPEG_SOI_NOT_FOUND;
941
12
    return false;
942
12
  }
943
9.15k
  int lut_size = kMaxHuffmanTables * kJpegHuffmanLutSize;
944
9.15k
  std::vector<HuffmanTableEntry> dc_huff_lut(lut_size);
945
9.15k
  std::vector<HuffmanTableEntry> ac_huff_lut(lut_size);
946
9.15k
  bool found_sof = false;
947
9.15k
  uint16_t scan_progression[kMaxComponents][kDCTBlockSize] = { { 0 } };
948
949
9.15k
  bool is_progressive = false;   // default
950
7.11M
  do {
951
    // Read next marker.
952
7.11M
    size_t num_skipped = FindNextMarker(data, len, pos);
953
7.11M
    if (num_skipped > 0) {
954
      // Add a fake marker to indicate arbitrary in-between-markers data.
955
6.69M
      jpg->marker_order.push_back(0xff);
956
6.69M
      jpg->inter_marker_data.push_back(
957
6.69M
          std::string(reinterpret_cast<const char*>(&data[pos]),
958
6.69M
                                      num_skipped));
959
6.69M
      pos += num_skipped;
960
6.69M
    }
961
7.11M
    EXPECT_MARKER();
962
7.11M
    marker = data[pos + 1];
963
7.11M
    pos += 2;
964
7.11M
    bool ok = true;
965
7.11M
    switch (marker) {
966
1.05k
      case 0xc0:
967
2.52k
      case 0xc1:
968
8.51k
      case 0xc2:
969
8.51k
        is_progressive = (marker == 0xc2);
970
8.51k
        ok = ProcessSOF(data, len, mode, &pos, jpg);
971
8.51k
        found_sof = true;
972
8.51k
        break;
973
19.4k
      case 0xc4:
974
19.4k
        ok = ProcessDHT(data, len, mode, &dc_huff_lut, &ac_huff_lut, &pos, jpg);
975
19.4k
        break;
976
3.88M
      case 0xd0:
977
3.88M
      case 0xd1:
978
3.88M
      case 0xd2:
979
3.90M
      case 0xd3:
980
3.90M
      case 0xd4:
981
3.91M
      case 0xd5:
982
4.16M
      case 0xd6:
983
4.87M
      case 0xd7:
984
        // RST markers do not have any data.
985
4.87M
        break;
986
2.66k
      case 0xd9:
987
        // Found end marker.
988
2.66k
        break;
989
6.69k
      case 0xda:
990
6.69k
        if (mode == JPEG_READ_ALL) {
991
6.28k
          ok = ProcessScan(data, len, dc_huff_lut, ac_huff_lut,
992
6.28k
                           scan_progression, is_progressive, &pos, jpg);
993
6.28k
        }
994
6.69k
        break;
995
6.85k
      case 0xdb:
996
6.85k
        ok = ProcessDQT(data, len, &pos, jpg);
997
6.85k
        break;
998
671
      case 0xdd:
999
671
        ok = ProcessDRI(data, len, &pos, jpg);
1000
671
        break;
1001
127k
      case 0xe0:
1002
713k
      case 0xe1:
1003
714k
      case 0xe2:
1004
714k
      case 0xe3:
1005
714k
      case 0xe4:
1006
899k
      case 0xe5:
1007
899k
      case 0xe6:
1008
900k
      case 0xe7:
1009
900k
      case 0xe8:
1010
1.24M
      case 0xe9:
1011
1.24M
      case 0xea:
1012
1.24M
      case 0xeb:
1013
1.24M
      case 0xec:
1014
1.24M
      case 0xed:
1015
1.24M
      case 0xee:
1016
1.77M
      case 0xef:
1017
1.77M
        if (mode != JPEG_READ_TABLES) {
1018
1.77M
          ok = ProcessAPP(data, len, &pos, jpg);
1019
1.77M
        }
1020
1.77M
        break;
1021
418k
      case 0xfe:
1022
418k
        if (mode != JPEG_READ_TABLES) {
1023
418k
          ok = ProcessCOM(data, len, &pos, jpg);
1024
418k
        }
1025
418k
        break;
1026
0
      default:
1027
0
        fprintf(stderr, "Unsupported marker: %d pos=%d len=%d\n",
1028
0
                marker, static_cast<int>(pos), static_cast<int>(len));
1029
0
        jpg->error = JPEG_UNSUPPORTED_MARKER;
1030
0
        ok = false;
1031
0
        break;
1032
7.11M
    }
1033
7.11M
    if (!ok) {
1034
1.71k
      return false;
1035
1.71k
    }
1036
7.11M
    jpg->marker_order.push_back(marker);
1037
7.11M
    if (mode == JPEG_READ_HEADER && found_sof) {
1038
4.22k
      break;
1039
4.22k
    }
1040
7.11M
  } while (marker != 0xd9);
1041
1042
6.89k
  if (!found_sof) {
1043
6
    fprintf(stderr, "Missing SOF marker.\n");
1044
6
    jpg->error = JPEG_SOF_NOT_FOUND;
1045
6
    return false;
1046
6
  }
1047
1048
  // Supplemental checks.
1049
6.88k
  if (mode == JPEG_READ_ALL) {
1050
2.66k
    if (pos < len) {
1051
275
      jpg->tail_data.assign(reinterpret_cast<const char*>(&data[pos]),
1052
275
                            len - pos);
1053
275
    }
1054
2.66k
    if (!FixupIndexes(jpg)) {
1055
14
      return false;
1056
14
    }
1057
2.64k
    if (jpg->huffman_code.size() == 0) {
1058
      // Section B.2.4.2: "If a table has never been defined for a particular
1059
      // destination, then when this destination is specified in a scan header,
1060
      // the results are unpredictable."
1061
6
      fprintf(stderr, "Need at least one Huffman code table.\n");
1062
6
      jpg->error = JPEG_HUFFMAN_TABLE_ERROR;
1063
6
      return false;
1064
6
    }
1065
2.64k
    if (jpg->huffman_code.size() >= kMaxDHTMarkers) {
1066
1
      fprintf(stderr, "Too many Huffman tables.\n");
1067
1
      jpg->error = JPEG_HUFFMAN_TABLE_ERROR;
1068
1
      return false;
1069
1
    }
1070
2.64k
  }
1071
6.86k
  return true;
1072
6.88k
}
1073
1074
bool ReadJpeg(const std::string& data, JpegReadMode mode,
1075
4.20k
              JPEGData* jpg) {
1076
4.20k
  return ReadJpeg(reinterpret_cast<const uint8_t*>(data.data()),
1077
4.20k
                  static_cast<const size_t>(data.size()),
1078
4.20k
                  mode, jpg);
1079
4.20k
}
1080
1081
}  // namespace guetzli