Coverage Report

Created: 2023-03-26 07:20

/src/libwebsockets/lib/misc/jpeg.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * lws jpeg
3
 *
4
 * Copyright (C) 2019 - 2022 Andy Green <andy@warmcat.com>
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
 * of this software and associated documentation files (the "Software"), to
8
 * deal in the Software without restriction, including without limitation the
9
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10
 * sell copies of the Software, and to permit persons to whom the Software is
11
 * furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included in
14
 * all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22
 * IN THE SOFTWARE.
23
 *
24
 * Based on public domain original with notice -->
25
 *
26
 * picojpeg.c v1.1 - Public domain, Rich Geldreich <richgel99@gmail.com>
27
 * Nov. 27, 2010 - Initial release
28
 * Feb. 9, 2013 - Added H1V2/H2V1 support, cleaned up macros, signed shift fixes
29
 * Also integrated and tested changes from Chris Phoenix <cphoenix@gmail.com>.
30
 *
31
 * https://github.com/richgel999/picojpeg
32
 *
33
 * This version is rewritten for lws, changing the whole approach to decode on
34
 * demand to issue a line of output at a time, statefully.  This version is
35
 * licensed MIT.
36
 *
37
 * Rasterization works into an 8 or 16-line buffer on Y, 444, 422 and 420 MCU
38
 * layouts.
39
 */
40
41
#include <private-lib-core.h>
42
43
0
#define jpeg_loglevel   LLL_NOTICE
44
#if (_LWS_ENABLED_LOGS & jpeg_loglevel)
45
0
#define lwsl_jpeg(...)    _lws_log(jpeg_loglevel, __VA_ARGS__)
46
#else
47
#define lwsl_jpeg(...)
48
#endif
49
50
0
#define MARKER_SCAN_LIMIT 1536
51
52
/*
53
 * Set to 1 if right shifts on signed ints are always unsigned (logical) shifts
54
 * When 1, arithmetic right shifts will be emulated by using a logical shift
55
 * with special case code to ensure the sign bit is replicated.
56
 */
57
58
#define PJPG_RIGHT_SHIFT_IS_ALWAYS_UNSIGNED 0
59
60
typedef enum {
61
  LWSJDS_FIND_SOI_INIT1,
62
  LWSJDS_FIND_SOI_INIT2,
63
  LWSJDS_FIND_SOI,
64
  LWSJDS_FIND_SOF1,
65
  LWSJDS_FIND_SOF2,
66
  LWSJDS_INIT_FRAME,
67
  LWSJDS_INIT_SCAN,
68
  LWSJDS_DECODE_MCU,
69
70
} lws_jpeg_decode_state_t;
71
72
// Scan types
73
typedef enum
74
{
75
   PJPG_GRAYSCALE,
76
   PJPG_YH1V1,
77
   PJPG_YH2V1,
78
   PJPG_YH1V2,
79
   PJPG_YH2V2
80
} pjpeg_scan_type_t;
81
82
#if PJPG_RIGHT_SHIFT_IS_ALWAYS_UNSIGNED
83
static int16_t replicateSignBit16(int8_t n)
84
{
85
   switch (n)
86
   {
87
      case 0:  return 0x0000;
88
      case 1:  return 0x8000;
89
      case 2:  return 0xC000;
90
      case 3:  return 0xE000;
91
      case 4:  return 0xF000;
92
      case 5:  return 0xF800;
93
      case 6:  return 0xFC00;
94
      case 7:  return 0xFE00;
95
      case 8:  return 0xFF00;
96
      case 9:  return 0xFF80;
97
      case 10: return 0xFFC0;
98
      case 11: return 0xFFE0;
99
      case 12: return 0xFFF0; 
100
      case 13: return 0xFFF8;
101
      case 14: return 0xFFFC;
102
      case 15: return 0xFFFE;
103
      default: return 0xFFFF;
104
   }
105
}
106
static LWS_INLINE int16_t arithmeticRightShiftN16(int16_t x, int8_t n) 
107
{
108
   int16_t r = (uint16_t)x >> (uint8_t)n;
109
   if (x < 0)
110
      r |= replicateSignBit16(n);
111
   return r;
112
}
113
static LWS_INLINE long arithmeticRightShift8L(long x) 
114
{
115
   long r = (unsigned long)x >> 8U;
116
   if (x < 0)
117
      r |= ~(~(unsigned long)0U >> 8U);
118
   return r;
119
}
120
#define PJPG_ARITH_SHIFT_RIGHT_N_16(x, n) arithmeticRightShiftN16(x, n)
121
#define PJPG_ARITH_SHIFT_RIGHT_8_L(x) arithmeticRightShift8L(x)
122
#else
123
0
#define PJPG_ARITH_SHIFT_RIGHT_N_16(x, n) ((x) >> (n))
124
0
#define PJPG_ARITH_SHIFT_RIGHT_8_L(x) ((x) >> 8)
125
#endif
126
127
0
#define PJPG_MAX_WIDTH 16384
128
0
#define PJPG_MAX_HEIGHT 16384
129
0
#define PJPG_MAXCOMPSINSCAN 3
130
131
enum {
132
  PJM_SOF0    = 0xC0,
133
  PJM_SOF1    = 0xC1,
134
  PJM_SOF2    = 0xC2,
135
  PJM_SOF3    = 0xC3,
136
137
  PJM_SOF5    = 0xC5,
138
  PJM_SOF6    = 0xC6,
139
  PJM_SOF7    = 0xC7,
140
141
  PJM_JPG     = 0xC8,
142
  PJM_SOF9    = 0xC9,
143
  PJM_SOF10   = 0xCA,
144
  PJM_SOF11   = 0xCB,
145
146
  PJM_SOF13   = 0xCD,
147
  PJM_SOF14   = 0xCE,
148
  PJM_SOF15   = 0xCF,
149
150
  PJM_DHT     = 0xC4,
151
152
  PJM_DAC     = 0xCC,
153
154
  PJM_RST0    = 0xD0,
155
  PJM_RST1    = 0xD1,
156
  PJM_RST2    = 0xD2,
157
  PJM_RST3    = 0xD3,
158
  PJM_RST4    = 0xD4,
159
  PJM_RST5    = 0xD5,
160
  PJM_RST6    = 0xD6,
161
  PJM_RST7    = 0xD7,
162
163
  PJM_SOI     = 0xD8,
164
  PJM_EOI     = 0xD9,
165
  PJM_SOS     = 0xDA,
166
  PJM_DQT     = 0xDB,
167
  PJM_DNL     = 0xDC,
168
  PJM_DRI     = 0xDD,
169
  PJM_DHP     = 0xDE,
170
  PJM_EXP     = 0xDF,
171
172
  PJM_APP0    = 0xE0,
173
  PJM_APP15   = 0xEF,
174
175
  PJM_JPG0    = 0xF0,
176
  PJM_JPG13   = 0xFD,
177
  PJM_COM     = 0xFE,
178
179
  PJM_TEM     = 0x01,
180
181
  PJM_ERROR   = 0x100,
182
183
  RST0      = 0xD0
184
};
185
186
typedef struct huff_table {
187
  uint16_t    min_code[16];
188
  uint16_t    max_code[16];
189
  uint8_t     value[16];
190
} huff_table_t;
191
192
typedef struct lws_jpeg {
193
194
  pjpeg_scan_type_t scan_type;
195
  
196
  const uint8_t   *inbuf;
197
  uint8_t     *lines;
198
  size_t      insize;
199
200
  lws_jpeg_decode_state_t dstate;
201
202
  int16_t     coeffs[8 * 8];
203
  int16_t     quant0[8 * 8];
204
  int16_t     quant1[8 * 8];
205
  int16_t     last_dc[3];
206
  uint16_t    bits;
207
  uint16_t    image_width;
208
  uint16_t    image_height;
209
  uint16_t    restart_interval;
210
  uint16_t    restart_num;
211
  uint16_t    restarts_left;
212
  uint16_t    mcu_max_row;
213
  uint16_t    mcu_max_col;
214
215
  uint16_t    mcu_ofs_x;
216
  uint16_t    mcu_ofs_y;
217
218
  uint16_t    mcu_count_left_x;
219
  uint16_t    mcu_count_left_y;
220
221
  huff_table_t    huff_tab0;
222
  huff_table_t    huff_tab1;
223
  huff_table_t    huff_tab2;
224
  huff_table_t    huff_tab3;
225
226
  uint8_t     mcu_buf_R[256];
227
  uint8_t     mcu_buf_G[256];
228
  uint8_t     mcu_buf_B[256];
229
230
  uint8_t     huff_val0[16];
231
  uint8_t     huff_val1[16];
232
  uint8_t     huff_val2[256];
233
  uint8_t     huff_val3[256];
234
235
  uint8_t     mcu_org_id[6];
236
  uint8_t     comp_id[3];
237
  uint8_t     comp_h_samp[3];
238
  uint8_t     comp_v_samp[3];
239
  uint8_t     comp_quant[3];
240
241
  uint8_t     comp_scan_count;
242
  uint8_t     comp_list[3];
243
  uint8_t     comp_dc[3]; // 0,1
244
  uint8_t     comp_ac[3]; // 0,1
245
246
  uint8_t     mcu_max_blocks;
247
  uint8_t     mcu_max_size_x;
248
  uint8_t     mcu_max_size_y;
249
250
  uint8_t     stash[2];
251
  uint8_t     stashc;
252
  uint8_t     ringy;
253
254
  uint8_t     huff_valid;
255
  uint8_t     quant_valid;
256
257
  uint8_t     seen_eoi;
258
259
  uint8_t     bits_left;
260
261
  uint8_t     frame_comps;
262
  
263
  uint8_t     ff_skip;
264
  char      hold_at_metadata;
265
  
266
  /* interruptible fine states */
267
  uint16_t    fs_hd_code; /* huff_decode() */
268
  uint16_t    fs_emit_budget; /* lws_jpeg_emit_next_line */
269
  uint16_t    fs_pm_skip_budget;
270
  uint16_t    fs_pm_count;
271
  uint16_t    fs_pm_temp;
272
  uint16_t    fs_sos_left;
273
  uint16_t    fs_sof_left;
274
  uint16_t    fs_ir_i;
275
  uint8_t     fs_gb16; /* get_bits16() */
276
  uint8_t     fs_hd;   /* huff_decode() */
277
  uint8_t     fs_hd_i; /* huff_decode() */
278
  uint8_t     fs_emit_lc;
279
  uint8_t     fs_emit_tc;
280
  uint8_t     fs_emit_c;
281
  uint8_t     fs_pm_s1;
282
  uint8_t     fs_pm_c;
283
  uint8_t     fs_pm_skip;
284
  uint8_t     fs_pm_bits[16];
285
  uint8_t     fs_pm_i;
286
  uint8_t     fs_pm_n;
287
  uint8_t     fs_pm_have_n;
288
  uint8_t     fs_pm_ti;
289
  uint8_t     fs_sos_phase;
290
  uint8_t     fs_sos_phase_loop;
291
  uint8_t     fs_sos_i;
292
  uint8_t     fs_sos_cc;
293
  uint8_t     fs_sos_c;
294
  uint8_t     fs_mcu_phase;
295
  uint8_t     fs_mcu_phase_loop;
296
  uint8_t     fs_mcu_mb;
297
  uint8_t     fs_mcu_k;
298
  uint8_t     fs_mcu_s;
299
  uint8_t     fs_sof_phase;
300
  uint8_t     fs_sof_i;
301
  uint8_t     fs_ir_phase;
302
  uint8_t     fs_is_phase;
303
304
} lws_jpeg_t;
305
306
static const int8_t ZAG[] = { 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18,
307
            11, 4, 5, 12, 19, 26, 33, 40, 48, 41, 34, 27,
308
            20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57,
309
            50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51,
310
            58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61,
311
            54, 47, 55, 62, 63, };
312
313
static LWS_INLINE lws_stateful_ret_t
314
get_char(lws_jpeg_t *j, uint8_t *c)
315
0
{
316
0
  if (j->stashc) {
317
0
    *c = j->stash[0];
318
0
    j->stash[0] = j->stash[1];
319
0
    j->stashc--;
320
0
    return LWS_SRET_OK;
321
0
  }
322
323
0
  if (!j->insize)
324
0
    return LWS_SRET_WANT_INPUT;
325
  
326
0
  *c = *j->inbuf++;
327
0
  j->insize--;
328
  
329
0
  return LWS_SRET_OK;
330
0
}
331
332
static lws_stateful_ret_t
333
get_octet(lws_jpeg_t *j, uint8_t *c, uint8_t ffcheck)
334
0
{
335
0
  lws_stateful_ret_t r;
336
0
  uint8_t c1;
337
338
0
  if (!j->ff_skip) {
339
0
    r = get_char(j, c);
340
0
    if (r)
341
0
      return r;
342
0
  }
343
344
0
  if (ffcheck && (j->ff_skip || *c == 0xff)) {
345
0
    j->ff_skip = 1;
346
0
    r = get_char(j, &c1);
347
0
    if (r)
348
0
      return r;
349
0
    j->ff_skip = 0;
350
0
    if (c1) {
351
0
      if (c1 == PJM_EOI) {
352
0
        j->seen_eoi = 1;
353
0
        return LWS_SRET_OK;
354
0
      }
355
0
      lwsl_jpeg("%s: nonzero stuffed 0x%02X\n", __func__, c1);
356
0
      return LWS_SRET_FATAL + 1;
357
0
    }
358
359
0
    *c = 0xff;
360
0
  }
361
362
0
  return LWS_SRET_OK;
363
0
}
364
365
static lws_stateful_ret_t
366
get_bits8(lws_jpeg_t *j, uint8_t *v, uint8_t numBits, uint8_t ffcheck)
367
0
{
368
0
  uint8_t origBits = numBits, c = 0;
369
0
  uint16_t ret = j->bits;
370
0
  lws_stateful_ret_t r;
371
372
0
  if (j->bits_left < numBits) {
373
    
374
0
    r = get_octet(j, &c, ffcheck);
375
0
    if (r)
376
0
      return r;
377
    
378
0
    j->bits = (uint16_t)(j->bits << j->bits_left);
379
0
    j->bits = (uint16_t)(j->bits | c);
380
0
    j->bits = (uint16_t)(j->bits << (numBits - j->bits_left));
381
382
0
    j->bits_left = (uint8_t)(8 - (numBits - j->bits_left));
383
0
  } else {
384
0
    j->bits_left = (uint8_t) (j->bits_left - numBits);
385
0
    j->bits = (uint16_t)(j->bits << numBits);
386
0
  }
387
388
0
  *v = (uint8_t)(ret >> (16 - origBits));
389
  
390
0
  return LWS_SRET_OK;
391
0
}
392
393
static lws_stateful_ret_t
394
get_bits16(lws_jpeg_t *j, uint16_t *v, uint8_t numBits, uint8_t ffcheck)
395
0
{
396
0
  uint8_t origBits = numBits, c = 0;
397
0
  uint16_t ret = j->bits;
398
0
  lws_stateful_ret_t r;
399
400
0
  assert(numBits > 8); /* otherwise, use get_bits8 */
401
0
  numBits = (uint8_t)(numBits - 8);
402
403
0
  if (!j->fs_gb16) { /* if not interrupted in second part */
404
  
405
0
    r = get_octet(j, &c, ffcheck);
406
0
    if (r)
407
0
      return r;
408
  
409
0
    j->bits = (uint16_t)(j->bits << j->bits_left);
410
0
    j->bits = (uint16_t)(j->bits | c);
411
0
    j->bits = (uint16_t)(j->bits << (8 - j->bits_left));
412
0
  }
413
414
0
  ret = (uint16_t)((ret & 0xff00) | (j->bits >> 8));
415
416
0
  if (j->bits_left < numBits) {
417
    
418
0
    j->fs_gb16 = 1; /* so we skip to here if retrying */
419
0
    r = get_octet(j, &c, ffcheck);
420
0
    if (r)
421
0
      return r;
422
423
0
    j->fs_gb16 = 0; /* cancel skip to here flag */
424
    
425
0
    j->bits = (uint16_t)(j->bits << j->bits_left);
426
0
    j->bits = (uint16_t)(j->bits | c);
427
0
    j->bits = (uint16_t)(j->bits << (numBits - j->bits_left));
428
0
    j->bits_left = (uint8_t)(8 - (numBits - j->bits_left));
429
0
  } else {
430
0
    j->bits_left = (uint8_t) (j->bits_left - numBits);
431
0
    j->bits = (uint16_t)(j->bits << numBits);
432
0
  }
433
434
0
  *v = (uint16_t)(ret >> (16 - origBits));
435
  
436
0
  return LWS_SRET_OK;
437
0
}
438
439
static LWS_INLINE lws_stateful_ret_t
440
get_bit(lws_jpeg_t *j, uint16_t *v)
441
0
{
442
0
  lws_stateful_ret_t r;
443
0
  uint16_t ret = 0;
444
0
  uint8_t c = 0;
445
446
0
  if (j->bits & 0x8000)
447
0
    ret = 1;
448
449
0
  if (!j->bits_left) {
450
0
    r = get_octet(j, &c, 1);
451
0
    if (r)
452
0
      return r;
453
454
0
    j->bits = (uint16_t)(j->bits | c);
455
0
    j->bits_left = (uint8_t)(j->bits_left + 8);
456
0
  }
457
458
0
  j->bits_left--;
459
0
  j->bits = (uint16_t)(j->bits << 1);
460
461
0
  *v = ret;
462
  
463
0
  return LWS_SRET_OK;
464
0
}
465
466
static uint16_t
467
get_extend_test(uint8_t i)
468
0
{
469
0
  if (!i || i > 15)
470
0
    return 0;
471
472
0
  return (uint16_t)(1 << (i - 1));
473
0
}
474
475
static int16_t
476
get_extend_offset(uint8_t i)
477
0
{
478
0
  if (!i || i > 15)
479
0
    return 0;
480
  
481
0
  return (int16_t)((int16_t)(0xffffffff << i) + 1);
482
0
}
483
484
static LWS_INLINE int16_t
485
huff_extend(uint16_t x, uint8_t s)
486
0
{
487
0
  return (int16_t)(((x < get_extend_test(s)) ?
488
0
        x + get_extend_offset(s) : x));
489
0
}
490
491
static LWS_INLINE lws_stateful_ret_t
492
huff_decode(lws_jpeg_t *j, uint8_t *v, const huff_table_t *ht, const uint8_t *p)
493
0
{
494
0
  lws_stateful_ret_t r;
495
0
  uint16_t c;
496
  
497
0
  if (!j->fs_hd) {
498
0
    r = get_bit(j, &j->fs_hd_code);
499
0
    if (r)
500
0
      return r;
501
0
    if (j->seen_eoi)
502
0
      return LWS_SRET_OK;
503
0
    j->fs_hd = 1;
504
0
    j->fs_hd_i = 0;
505
0
  }
506
507
0
  for (;;) {
508
0
    uint16_t maxCode;
509
510
0
    if (j->fs_hd_i == 16) {
511
0
      j->fs_hd = 0;
512
0
      *v = 0;
513
0
      return LWS_SRET_OK;
514
0
    }
515
516
0
    maxCode = ht->max_code[j->fs_hd_i];
517
0
    if ((j->fs_hd_code <= maxCode) && (maxCode != 0xFFFF))
518
0
      break;
519
    
520
0
    r = get_bit(j, &c);
521
0
    if (r)
522
0
      return r;
523
524
0
    if (j->seen_eoi)
525
0
      return LWS_SRET_OK;
526
527
0
    j->fs_hd_i++;
528
0
    j->fs_hd_code = (uint16_t)((j->fs_hd_code << 1) | c);
529
0
  }
530
531
0
  j->fs_hd = 0;
532
533
0
  *v = p[(ht->value[j->fs_hd_i] +
534
0
    (j->fs_hd_code - ht->min_code[j->fs_hd_i]))];
535
  
536
0
  return LWS_SRET_OK;
537
0
}
538
539
static void
540
huffCreate(const uint8_t *pBits, huff_table_t *ht)
541
0
{
542
0
  uint8_t i = 0;
543
0
  uint8_t jj = 0;
544
545
0
  uint16_t code = 0;
546
547
0
  for (;;) {
548
0
    uint8_t num = pBits[i];
549
550
0
    if (!num) {
551
0
      ht->min_code[i] = 0x0000;
552
0
      ht->max_code[i] = 0xFFFF;
553
0
      ht->value[i] = 0;
554
0
    } else {
555
0
      ht->min_code[i] = code;
556
0
      ht->max_code[i] = (uint16_t)(code + num - 1);
557
0
      ht->value[i] = jj;
558
559
0
      jj = (uint8_t) (jj + num);
560
561
0
      code = (uint16_t) (code + num);
562
0
    }
563
564
0
    code = (uint16_t)(code << 1);
565
566
0
    i++;
567
0
    if (i > 15)
568
0
      break;
569
0
  }
570
0
}
571
572
static huff_table_t *
573
get_huff_table(lws_jpeg_t *j, uint8_t index)
574
0
{
575
  // 0-1 = DC
576
  // 2-3 = AC
577
0
  switch (index) {
578
0
  case 0:
579
0
    return &j->huff_tab0;
580
0
  case 1:
581
0
    return &j->huff_tab1;
582
0
  case 2:
583
0
    return &j->huff_tab2;
584
0
  case 3:
585
0
    return &j->huff_tab3;
586
0
  default:
587
0
    return NULL;
588
0
  }
589
0
}
590
591
static uint8_t *
592
get_huff_value(lws_jpeg_t *j, uint8_t index)
593
0
{
594
  // 0-1 = DC
595
  // 2-3 = AC
596
0
  switch (index) {
597
0
  case 0:
598
0
    return j->huff_val0;
599
0
  case 1:
600
0
    return j->huff_val1;
601
0
  case 2:
602
0
    return j->huff_val2;
603
0
  case 3:
604
0
    return j->huff_val3;
605
0
  default:
606
0
    return 0;
607
0
  }
608
0
}
609
610
static uint16_t
611
getMaxHuffCodes(uint8_t index)
612
0
{
613
0
  return (index < 2) ? 12 : 255;
614
0
}
615
616
static void createWinogradQuant(lws_jpeg_t *j, int16_t *pq);
617
618
619
static lws_stateful_ret_t
620
read_sof_marker(lws_jpeg_t *j)
621
0
{
622
0
  lws_stateful_ret_t r;
623
0
  uint8_t c;
624
625
0
  switch (j->fs_sof_phase) {
626
0
  case 0:
627
0
    r = get_bits16(j, &j->fs_sof_left, 16, 0);
628
0
    if (r)
629
0
      return r;
630
631
0
    j->fs_sof_phase++;
632
    
633
    /* fallthru */
634
635
0
  case 1:
636
0
    r = get_bits8(j, &c, 8, 0);
637
0
    if (r)
638
0
      return r;
639
    
640
0
    if (c != 8) {
641
0
      lwsl_jpeg("%s: required 8\n", __func__);
642
0
      return LWS_SRET_FATAL + 2;
643
0
    }
644
645
0
    j->fs_sof_phase++;
646
    
647
    /* fallthru */
648
649
0
  case 2:
650
0
    r = get_bits16(j, &j->image_height, 16, 0);
651
0
    if (r)
652
0
      return r;
653
  
654
0
    if ((!j->image_height) || (j->image_height > PJPG_MAX_HEIGHT)) {
655
0
      lwsl_jpeg("%s: image height range\n", __func__);
656
0
      return LWS_SRET_FATAL + 3;
657
0
    }
658
    
659
0
    j->fs_sof_phase++;
660
    
661
    /* fallthru */
662
    
663
0
  case 3:
664
0
    r = get_bits16(j, &j->image_width, 16, 0);
665
0
    if (r)
666
0
      return r;
667
668
0
    if ((!j->image_width) || (j->image_width > PJPG_MAX_WIDTH)) {
669
0
      lwsl_jpeg("%s: image width range\n", __func__);
670
0
      return LWS_SRET_FATAL + 4;
671
0
    }
672
673
0
    lwsl_warn("%s: %d x %d\n", __func__, j->image_width, j->image_height);
674
675
0
    j->fs_sof_phase++;
676
    
677
    /* fallthru */
678
    
679
0
  case 4:
680
0
    r = get_bits8(j, &j->frame_comps, 8, 0);
681
0
    if (r)
682
0
      return r;
683
684
0
    if (j->frame_comps > 3) {
685
0
      lwsl_jpeg("%s: too many comps\n", __func__);
686
0
      return LWS_SRET_FATAL + 5;
687
0
    }
688
  
689
0
    if (j->fs_sof_left !=
690
0
        (j->frame_comps + j->frame_comps + j->frame_comps + 8)) {
691
0
      lwsl_jpeg("%s: unexpected soft_left\n", __func__);
692
0
      return LWS_SRET_FATAL + 6;
693
0
    }
694
    
695
0
    j->fs_sof_i = 0;
696
    
697
0
    j->fs_sof_phase++;
698
    
699
    /* fallthru */
700
    
701
0
  default:
702
703
0
    while (j->fs_sof_i < j->frame_comps) {
704
0
      switch (j->fs_sof_phase) {
705
0
      case 5:
706
0
        r = get_bits8(j, &j->comp_id[j->fs_sof_i], 8, 0);
707
0
        if (r)
708
0
          return r;
709
710
0
        j->fs_sof_phase++;
711
        
712
        /* fallthru */
713
714
0
      case 6:
715
0
        r = get_bits8(j, &j->comp_h_samp[j->fs_sof_i], 4, 0);
716
0
        if (r)
717
0
          return r;
718
719
0
        j->fs_sof_phase++;
720
        
721
        /* fallthru */
722
723
0
      case 7:
724
0
        r = get_bits8(j, &j->comp_v_samp[j->fs_sof_i], 4, 0);
725
0
        if (r)
726
0
          return r;
727
728
0
        j->fs_sof_phase++;
729
        
730
        /* fallthru */
731
732
0
      case 8:
733
0
        r = get_bits8(j, &j->comp_quant[j->fs_sof_i], 8, 0);
734
0
        if (r)
735
0
          return r;
736
    
737
0
        if (j->comp_quant[j->fs_sof_i] > 1) {
738
0
          lwsl_jpeg("%s: comp_quant > 1\n", __func__);
739
0
          return LWS_SRET_FATAL + 7;
740
0
        }
741
0
        break;
742
0
      } /* loop switch */
743
      
744
0
      j->fs_sof_phase = 5;
745
0
      j->fs_sof_i++;
746
0
    } /* while */
747
748
0
  } /* switch */
749
750
0
  return LWS_SRET_OK;
751
0
}
752
753
// Read a start of scan (SOS) marker.
754
static lws_stateful_ret_t
755
read_sos_marker(lws_jpeg_t *j)
756
0
{
757
0
  lws_stateful_ret_t r;
758
0
  uint8_t c;
759
760
0
  switch (j->fs_sos_phase) {
761
0
  case 0:
762
0
    r = get_bits16(j, &j->fs_sos_left, 16, 0);
763
0
    if (r)
764
0
      return r;
765
    
766
0
    j->fs_sos_i = 0;
767
0
    j->fs_sos_phase++;
768
769
    /* fallthru */
770
    
771
0
  case 1:
772
0
    r = get_bits8(j, &j->comp_scan_count, 8, 0);
773
0
    if (r)
774
0
      return r;
775
776
0
    j->fs_sos_left = (uint16_t)(j->fs_sos_left - 3);
777
778
0
    if ((j->fs_sos_left !=
779
0
        (j->comp_scan_count + j->comp_scan_count + 3)) ||
780
0
        (j->comp_scan_count < 1) ||
781
0
        (j->comp_scan_count > PJPG_MAXCOMPSINSCAN)) {
782
0
      lwsl_jpeg("%s: scan comps limit\n", __func__);
783
0
      return LWS_SRET_FATAL + 8;
784
0
    }
785
786
0
    j->fs_sos_phase++;
787
0
    j->fs_sos_phase_loop = 0;
788
789
    /* fallthru */
790
    
791
0
  case 2:
792
0
    while (j->fs_sos_i < j->comp_scan_count) {
793
0
      switch (j->fs_sos_phase_loop) {
794
0
      case 0:
795
0
        r = get_bits8(j, &j->fs_sos_cc, 8, 0);
796
0
        if (r)
797
0
          return r;
798
0
        j->fs_sos_phase_loop++;
799
        
800
        /* fallthru */
801
        
802
0
      case 1:
803
0
        r = get_bits8(j, &j->fs_sos_c, 8, 0);
804
0
        if (r)
805
0
          return r;
806
        
807
0
        j->fs_sos_left = (uint16_t)(j->fs_sos_left - 2);
808
        
809
0
        for (c = 0; c < j->frame_comps; c++)
810
0
          if (j->fs_sos_cc == j->comp_id[c])
811
0
            break;
812
    
813
0
        if (c >= j->frame_comps) {
814
0
          lwsl_jpeg("%s: SOS comps\n", __func__);
815
0
          return LWS_SRET_FATAL + 9;
816
0
        }
817
        
818
0
        j->comp_list[j->fs_sos_i] = c;
819
0
        j->comp_dc[c] = (j->fs_sos_c >> 4) & 15;
820
0
        j->comp_ac[c] = (j->fs_sos_c & 15);
821
        
822
0
        break;
823
0
      }
824
      
825
0
      j->fs_sos_i++;
826
0
      j->fs_sos_phase_loop = 0;
827
0
    }
828
    
829
0
    j->fs_sos_phase++;
830
831
    /* fallthru */
832
        
833
0
  case 3:
834
0
    r = get_bits8(j, &c, 8, 0);
835
0
    if (r)
836
0
      return r;
837
838
0
    j->fs_sos_phase++;
839
840
    /* fallthru */
841
        
842
0
  case 4:
843
0
    r = get_bits8(j, &c, 8, 0);
844
0
    if (r)
845
0
      return r;
846
847
0
    j->fs_sos_phase++;
848
849
    /* fallthru */
850
        
851
0
  case 5:
852
0
    r = get_bits8(j, &c, 4, 0);
853
0
    if (r)
854
0
      return r;
855
856
0
    j->fs_sos_phase++;
857
858
    /* fallthru */
859
        
860
0
  case 6:
861
0
    r = get_bits8(j, &c, 4, 0);
862
0
    if (r)
863
0
      return r;
864
    
865
0
    j->fs_sos_left = (uint16_t)(j->fs_sos_left - 3);
866
867
0
    j->fs_sos_phase++;
868
869
    /* fallthru */
870
        
871
0
  case 7:
872
0
    while (j->fs_sos_left) {
873
0
      r = get_bits8(j, &c, 8, 0);
874
0
      if (r)
875
0
        return r;
876
877
0
      j->fs_sos_left--;
878
0
    }
879
    
880
0
    j->fs_sos_phase = 0;
881
882
0
    return LWS_SRET_OK;
883
0
  }
884
885
0
  lwsl_jpeg("%s: SOS marker fail\n", __func__);
886
887
0
  return LWS_SRET_FATAL + 10;
888
0
}
889
890
// Process markers. Returns when an SOFx, SOI, EOI, or SOS marker is
891
// encountered.
892
static lws_stateful_ret_t
893
process_markers(lws_jpeg_t *j, uint8_t *pMarker)
894
0
{
895
0
  lws_stateful_ret_t r;
896
0
  uint16_t w;
897
0
  uint8_t c;
898
899
0
  do {
900
0
    if (j->fs_pm_s1 < 2) {
901
0
      do {
902
0
        if (j->fs_pm_s1 == 0) {
903
0
          do {
904
0
            r = get_bits8(j, &j->fs_pm_c, 8, 0);
905
0
            if (r)
906
0
              return r;
907
      
908
0
          } while (j->fs_pm_c != 0xFF);
909
            
910
0
          j->fs_pm_s1 = 1;
911
0
        }
912
  
913
0
        do {
914
0
          r = get_bits8(j, &j->fs_pm_c, 8, 0);
915
0
          if (r)
916
0
            return r;
917
  
918
0
        } while (j->fs_pm_c == 0xFF);
919
  
920
0
      } while (!j->fs_pm_c);
921
      
922
0
      j->fs_pm_skip = 0;
923
0
      j->fs_pm_i = 0;
924
0
      j->fs_pm_s1 = 2;
925
0
    }
926
927
0
    switch (j->fs_pm_c) {
928
0
    case PJM_SOF0:
929
0
    case PJM_SOF1:
930
0
    case PJM_SOF2:
931
0
    case PJM_SOF3:
932
0
    case PJM_SOF5:
933
0
    case PJM_SOF6:
934
0
    case PJM_SOF7:
935
      //      case PJM_JPG:
936
0
    case PJM_SOF9:
937
0
    case PJM_SOF10:
938
0
    case PJM_SOF11:
939
0
    case PJM_SOF13:
940
0
    case PJM_SOF14:
941
0
    case PJM_SOF15:
942
0
    case PJM_SOI:
943
0
    case PJM_EOI:
944
0
    case PJM_SOS:
945
0
      *pMarker = j->fs_pm_c;
946
947
0
      goto exit_ok;
948
949
0
    case PJM_DHT:
950
0
      if (!j->fs_pm_skip) { /* step zero */
951
0
        r = get_bits16(j, &j->fs_pm_skip_budget, 16, 0);
952
0
        if (r)
953
0
          return r;
954
955
0
        if (j->fs_pm_skip_budget < 2) {
956
0
          lwsl_jpeg("%s: inadequate skip\n",
957
0
                __func__);
958
0
          return LWS_SRET_FATAL + 11;
959
0
        }
960
961
0
        j->fs_pm_skip_budget = (uint16_t)(
962
0
            j->fs_pm_skip_budget -  2);
963
0
        j->fs_pm_skip = 1;
964
0
        j->fs_pm_i = 0;
965
0
      }
966
967
0
      while (j->fs_pm_skip_budget) {
968
0
        uint8_t index;
969
0
        uint16_t totalRead;
970
0
        huff_table_t *ht;
971
0
        uint8_t *p;
972
973
0
        switch (j->fs_pm_skip) {
974
0
        case 1:
975
0
          r = get_bits8(j, &index, 8, 0);
976
0
          if (r)
977
0
            return r;
978
979
0
          if (((index & 0x0f) > 1) ||
980
0
              ((index & 0xf0) > 0x10)) {
981
0
            lwsl_jpeg("%s: idx range\n", __func__);
982
0
            return LWS_SRET_FATAL + 12;
983
0
          }
984
985
0
          j->fs_pm_ti = (uint8_t)
986
0
            (((index >> 3) & 2) + (index & 1));
987
0
          j->huff_valid = (uint8_t)(j->huff_valid |
988
0
              (1 << j->fs_pm_ti));
989
0
          j->fs_pm_count = 0;
990
0
          j->fs_pm_i = 0;
991
0
          j->fs_pm_skip = 2;
992
993
          /* fallthru */
994
995
0
        case 2:
996
0
          while (j->fs_pm_i <= 15) {
997
0
            r = get_bits8(j, &j->fs_pm_bits[
998
0
                 j->fs_pm_i], 8, 0);
999
0
            if (r)
1000
0
              return r;
1001
0
            j->fs_pm_count =
1002
0
              (uint16_t)(
1003
0
              j->fs_pm_count +
1004
0
              j->fs_pm_bits[j->fs_pm_i]);
1005
0
            j->fs_pm_i++;
1006
0
          }
1007
1008
0
          if (j->fs_pm_count >
1009
0
              getMaxHuffCodes(j->fs_pm_ti)) {
1010
0
            lwsl_jpeg("%s: huff count\n", __func__);
1011
0
            return LWS_SRET_FATAL + 13;
1012
0
          }
1013
          
1014
0
          j->fs_pm_i = 0;
1015
0
          j->fs_pm_skip = 3;
1016
1017
          /* fallthru */
1018
1019
0
        case 3:
1020
0
          ht = get_huff_table(j, j->fs_pm_ti);
1021
0
          p = get_huff_value(j, j->fs_pm_ti);
1022
1023
0
          while (j->fs_pm_i < j->fs_pm_count) {
1024
0
            r = get_bits8(j, &p[j->fs_pm_i], 8, 0);
1025
0
            if (r)
1026
0
              return r;
1027
  
1028
0
            j->fs_pm_i++;
1029
0
          }
1030
  
1031
0
          totalRead = (uint16_t)(1 + 16 +
1032
0
                j->fs_pm_count);
1033
  
1034
0
          if (j->fs_pm_skip_budget < totalRead) {
1035
0
            lwsl_jpeg("%s: read budget\n",
1036
0
                __func__);
1037
0
            return LWS_SRET_FATAL + 14;
1038
0
          }
1039
  
1040
0
          j->fs_pm_skip_budget = (uint16_t)
1041
0
            (j->fs_pm_skip_budget - totalRead);
1042
  
1043
0
          huffCreate(j->fs_pm_bits, ht);
1044
0
          break;
1045
0
        }
1046
0
      }
1047
0
      break;
1048
1049
      /* No arithmetic coding support */
1050
0
    case PJM_DAC:
1051
0
      lwsl_jpeg("%s: arithmetic coding not supported\n",
1052
0
                __func__);
1053
1054
0
      return LWS_SRET_FATAL;
1055
1056
0
    case PJM_DQT:
1057
0
      switch (j->fs_pm_skip) {
1058
0
      case 0:
1059
0
        r = get_bits16(j, &j->fs_pm_skip_budget, 16, 0);
1060
0
        if (r)
1061
0
          return r;
1062
1063
0
        if (j->fs_pm_skip_budget < 2) {
1064
0
          lwsl_jpeg("%s: inadequate DQT skip\n",
1065
0
                __func__);
1066
1067
0
          return LWS_SRET_FATAL + 15;
1068
0
        }
1069
1070
0
        j->fs_pm_skip_budget = (uint16_t)
1071
0
            (j->fs_pm_skip_budget - 2);
1072
0
        j->fs_pm_skip = 1;
1073
0
        j->fs_pm_have_n = 0;
1074
1075
        /* fallthru */
1076
        
1077
0
      case 1:
1078
0
        while (j->fs_pm_skip_budget) {
1079
0
          uint16_t totalRead;
1080
1081
0
          if (!j->fs_pm_have_n) {
1082
0
            r = get_bits8(j, &j->fs_pm_n, 8, 0);
1083
0
            if (r)
1084
0
              return r;
1085
0
            if ((j->fs_pm_n & 0xf) > 1) {
1086
0
              lwsl_jpeg("%s: PM n too big\n",
1087
0
                  __func__);
1088
0
              return LWS_SRET_FATAL + 16;
1089
0
            }
1090
            
1091
0
            j->quant_valid = (uint8_t)(
1092
0
              j->quant_valid |
1093
0
              ((j->fs_pm_n & 0xf) ? 2 : 1));
1094
            
1095
0
            j->fs_pm_i = 0;
1096
0
            j->fs_pm_have_n = 1;
1097
0
          }
1098
1099
          // read quantization entries, in zag order
1100
0
          while (j->fs_pm_i < 64) {
1101
0
            switch (j->fs_pm_have_n) {
1102
0
            case 1:
1103
0
              r = get_bits8(j, &c, 8, 0);
1104
0
              if (r)
1105
0
                return r;
1106
              
1107
0
              j->fs_pm_temp = (uint16_t)c;
1108
              
1109
0
              j->fs_pm_have_n++;
1110
1111
              /* fallthru */
1112
1113
0
            case 2:
1114
0
              if (j->fs_pm_n >> 4) {
1115
0
                r = get_bits8(j, &c, 8, 0);
1116
0
                if (r)
1117
0
                  return r;
1118
0
                j->fs_pm_temp =
1119
0
                  (uint16_t)(
1120
0
                  (j->fs_pm_temp << 8) + c);
1121
0
              }
1122
1123
0
              if (j->fs_pm_n & 0xf)
1124
0
                j->quant1[j->fs_pm_i] =
1125
0
                  (int16_t)j->fs_pm_temp;
1126
0
              else
1127
0
                j->quant0[j->fs_pm_i] =
1128
0
                  (int16_t)j->fs_pm_temp;
1129
0
              break;
1130
0
            }
1131
            
1132
0
            j->fs_pm_i++;
1133
0
            j->fs_pm_have_n = 1;
1134
1135
0
          } /* 64 zags */
1136
          
1137
0
          j->fs_pm_have_n = 0;
1138
1139
0
          createWinogradQuant(j,
1140
0
            (j->fs_pm_n & 0xf) ?
1141
0
              j->quant1 : j->quant0);
1142
1143
0
          totalRead = 64 + 1;
1144
1145
0
          if (j->fs_pm_n >> 4)
1146
0
            totalRead = (uint16_t)(totalRead + 64);
1147
1148
0
          if (j->fs_pm_skip_budget < totalRead) {
1149
0
            lwsl_jpeg("%s: DQT: skip budget"
1150
0
                " underflow\n", __func__);
1151
0
            return LWS_SRET_FATAL + 17;
1152
0
          }
1153
1154
0
          j->fs_pm_skip_budget = (uint16_t)
1155
0
            (j->fs_pm_skip_budget - totalRead);
1156
0
        } /* while skip_budget / left */
1157
1158
0
        j->fs_pm_skip = 0;
1159
0
        break;
1160
0
      } /* DQT phase separation */
1161
0
      break;
1162
1163
0
    case PJM_DRI:
1164
0
      switch (j->fs_pm_i) {
1165
0
      case 0:
1166
0
        r = get_bits16(j, &w, 16, 0);
1167
0
        if (r)
1168
0
          return r;
1169
0
        if (w != 4) {
1170
0
          lwsl_jpeg("%s: DRI wrong val\n", __func__);
1171
0
          return LWS_SRET_FATAL + 18;
1172
0
        }
1173
        
1174
0
        j->fs_pm_i = 1;
1175
1176
        /* fallthru */
1177
1178
0
      case 1:
1179
0
        r = get_bits16(j, &j->restart_interval, 16, 0);
1180
0
        if (r)
1181
0
          return r;
1182
1183
0
        break;
1184
0
      }
1185
0
      break;
1186
1187
      //case PJM_APP0:  /* no need to read the JFIF marker */
1188
1189
0
    case PJM_JPG:
1190
0
    case PJM_RST0: /* no parameters */
1191
0
    case PJM_RST1:
1192
0
    case PJM_RST2:
1193
0
    case PJM_RST3:
1194
0
    case PJM_RST4:
1195
0
    case PJM_RST5:
1196
0
    case PJM_RST6:
1197
0
    case PJM_RST7:
1198
0
    case PJM_TEM:
1199
0
      lwsl_jpeg("%s: bad MCU type\n", __func__);
1200
1201
0
      return LWS_SRET_FATAL;
1202
1203
0
    default: /* must be DNL, DHP, EXP, APPn, JPGn, COM, or RESn or APP0
1204
        * Used to skip unrecognized markers.
1205
        */
1206
1207
0
      if (!j->fs_pm_skip) {
1208
0
        r = get_bits16(j, &j->fs_pm_skip_budget, 16, 0);
1209
0
        if (r)
1210
0
          return r;
1211
0
        if (j->fs_pm_skip_budget < 2) {
1212
0
          lwsl_jpeg("%s: inadequate skip 3\n",
1213
0
                __func__);
1214
1215
0
          return LWS_SRET_FATAL + 19;
1216
0
        }
1217
1218
0
        j->fs_pm_skip_budget = (uint16_t)
1219
0
            (j->fs_pm_skip_budget - 2);
1220
0
        j->fs_pm_skip = 1;
1221
0
      }
1222
1223
0
      while (j->fs_pm_skip_budget) {
1224
0
        uint8_t c;
1225
0
        r = get_bits8(j, &c, 8, 0);
1226
0
        if (r)
1227
0
          return r;
1228
0
        j->fs_pm_skip_budget--;
1229
0
      }
1230
0
      break;
1231
0
    } /* switch */
1232
    
1233
0
    j->fs_pm_s1 = 0; /* do next_marker() flow next loop */
1234
    
1235
0
  } while(1);
1236
  
1237
0
exit_ok:
1238
0
  j->fs_pm_s1 = 0;
1239
1240
0
  return LWS_SRET_OK;
1241
0
}
1242
1243
// Restart interval processing.
1244
static lws_stateful_ret_t
1245
interval_restart(lws_jpeg_t *j)
1246
0
{
1247
0
  lws_stateful_ret_t r;
1248
0
  uint8_t c;
1249
1250
0
  switch (j->fs_ir_phase) {
1251
0
  case 0:
1252
0
    while (j->fs_ir_i < MARKER_SCAN_LIMIT) {
1253
0
      r = get_char(j, &c);
1254
0
      if (r)
1255
0
        return r;
1256
  
1257
0
      if (c == 0xFF)
1258
0
        break;
1259
  
1260
0
      j->fs_ir_i++;
1261
0
    }
1262
  
1263
0
    if (j->fs_ir_i == MARKER_SCAN_LIMIT) {
1264
      /* we judge it unreasonable */
1265
0
      lwsl_jpeg("%s: scan limit exceeded\n", __func__);
1266
1267
0
      return LWS_SRET_FATAL;
1268
0
    }
1269
    
1270
0
    j->fs_ir_phase++;
1271
    
1272
    /* fallthru */
1273
    
1274
0
  case 1:
1275
0
    while (j->fs_ir_i < MARKER_SCAN_LIMIT) {
1276
0
      r = get_char(j, &c);
1277
0
      if (r)
1278
0
        return r;
1279
  
1280
0
      if (c != 0xFF)
1281
0
        break;
1282
0
      j->fs_ir_i++;
1283
0
    }
1284
1285
0
    if (j->fs_ir_i == MARKER_SCAN_LIMIT) {
1286
      /* we judge it unreasonable */
1287
0
      lwsl_jpeg("%s: scan limit exceeded 2\n", __func__);
1288
1289
0
      return LWS_SRET_FATAL + 20;
1290
0
    }
1291
1292
    /* Is it the expected marker? If not, something bad happened. */
1293
0
    if (c != (j->restart_num + PJM_RST0)) {
1294
0
      lwsl_jpeg("%s: unexpected marker\n", __func__);
1295
1296
0
      return LWS_SRET_FATAL + 21;
1297
0
    }
1298
1299
    /* Reset each component's DC prediction values. */
1300
0
    j->last_dc[0] = 0;
1301
0
    j->last_dc[1] = 0;
1302
0
    j->last_dc[2] = 0;
1303
  
1304
0
    j->restarts_left = j->restart_interval;
1305
  
1306
0
    j->restart_num = (j->restart_num + 1) & 7;
1307
    
1308
0
    j->bits_left = 8;
1309
1310
0
    j->fs_ir_phase++;
1311
    
1312
    /* fallthru */
1313
    
1314
0
  case 2:
1315
0
    r = get_bits8(j, &c, 8, 1);
1316
0
    if (r)
1317
0
      return r;
1318
0
    j->fs_ir_phase++;
1319
    
1320
    /* fallthru */
1321
    
1322
0
  case 3:
1323
0
    r = get_bits8(j, &c, 8, 1);
1324
0
    if (r)
1325
0
      return r;
1326
1327
0
    j->fs_ir_phase = 0;
1328
0
    break;
1329
0
  }
1330
1331
0
  return LWS_SRET_OK;
1332
0
}
1333
1334
static lws_stateful_ret_t
1335
check_huff_tables(lws_jpeg_t *j)
1336
0
{
1337
0
  uint8_t i;
1338
1339
0
  for (i = 0; i < j->comp_scan_count; i++) {
1340
0
    uint8_t compDCTab = j->comp_dc[j->comp_list[i]];
1341
0
    uint8_t compACTab = (uint8_t)(j->comp_ac[j->comp_list[i]] + 2);
1342
1343
0
    if (((j->huff_valid & (1 << compDCTab)) == 0) ||
1344
0
        ((j->huff_valid & (1 << compACTab)) == 0)) {
1345
0
      lwsl_jpeg("%s: invalid hufftable\n", __func__);
1346
1347
0
      return LWS_SRET_FATAL;
1348
0
    }
1349
0
  }
1350
1351
0
  return LWS_SRET_OK;
1352
0
}
1353
1354
static lws_stateful_ret_t
1355
check_quant_tables(lws_jpeg_t *j)
1356
0
{
1357
0
  uint8_t i;
1358
1359
0
  for (i = 0; i < j->comp_scan_count; i++) {
1360
0
    uint8_t compqMask = j->comp_quant[j->comp_list[i]] ? 2 : 1;
1361
1362
0
    if ((j->quant_valid & compqMask) == 0) {
1363
0
      lwsl_jpeg("%s: invalid quant table\n", __func__);
1364
1365
0
      return LWS_SRET_FATAL + 22;
1366
0
    }
1367
0
  }
1368
1369
0
  return LWS_SRET_OK;
1370
0
}
1371
1372
static lws_stateful_ret_t
1373
init_scan(lws_jpeg_t *j)
1374
0
{
1375
0
  lws_stateful_ret_t r;
1376
0
  uint8_t c;
1377
1378
0
  switch (j->fs_is_phase) {
1379
0
  case 0:
1380
0
    r = process_markers(j, &c);
1381
0
    if (r)
1382
0
      return r;
1383
1384
0
    if (c == PJM_EOI) {
1385
0
      lwsl_jpeg("%s: scan reached EOI\n", __func__);
1386
1387
0
      return LWS_SRET_FATAL + 23;
1388
0
    }
1389
1390
0
    if (c != PJM_SOS) {
1391
0
      lwsl_jpeg("%s: not SOS\n", __func__);
1392
1393
0
      return LWS_SRET_FATAL + 24;
1394
0
    }
1395
1396
0
    j->fs_is_phase++;
1397
1398
    /* fallthru */
1399
1400
0
  case 1:
1401
0
    r = read_sos_marker(j);
1402
0
    if (r)
1403
0
      return r;
1404
1405
0
    j->fs_is_phase++;
1406
1407
    /* fallthru */
1408
1409
0
  case 2:
1410
0
    r = check_huff_tables(j);
1411
0
    if (r)
1412
0
      return r;
1413
1414
0
    r = check_quant_tables(j);
1415
0
    if (r)
1416
0
      return r;
1417
1418
0
    j->last_dc[0] = 0;
1419
0
    j->last_dc[1] = 0;
1420
0
    j->last_dc[2] = 0;
1421
1422
0
    if (j->restart_interval) {
1423
0
      j->restarts_left = j->restart_interval;
1424
0
      j->restart_num = 0;
1425
0
    }
1426
1427
0
    if (j->bits_left > 0)
1428
0
      j->stash[j->stashc++] = (uint8_t)j->bits;
1429
1430
0
    j->stash[j->stashc++] = (uint8_t) (j->bits >> 8);
1431
0
    j->bits_left = 8;
1432
1433
0
    j->fs_is_phase++;
1434
1435
    /* fallthru */
1436
1437
0
  case 3:
1438
0
    r = get_bits8(j, &c, 8, 1);
1439
0
    if (r)
1440
0
      return r;
1441
0
    j->fs_is_phase++;
1442
1443
    /* fallthru */
1444
1445
0
  case 4:
1446
0
    r = get_bits8(j, &c, 8, 1);
1447
0
    if (r)
1448
0
      return r;
1449
0
    break;
1450
0
  }
1451
1452
0
  j->fs_is_phase = 0;
1453
1454
0
  return LWS_SRET_OK;
1455
0
}
1456
1457
static lws_stateful_ret_t
1458
init_frame(lws_jpeg_t *j)
1459
0
{
1460
0
  switch (j->frame_comps) {
1461
0
  case 1:
1462
0
    if ((j->comp_h_samp[0] != 1) || (j->comp_v_samp[0] != 1)) {
1463
0
      lwsl_jpeg("%s: samps not 1\n", __func__);
1464
1465
0
      return LWS_SRET_FATAL + 25;
1466
0
    }
1467
1468
0
    j->scan_type = PJPG_GRAYSCALE;
1469
1470
0
    j->mcu_max_blocks = 1;
1471
0
    j->mcu_org_id[0] = 0;
1472
1473
0
    j->mcu_max_size_x = 8;
1474
0
    j->mcu_max_size_y = 8;
1475
0
    break;
1476
    
1477
0
  case 3:
1478
0
    if (((j->comp_h_samp[1] != 1) || (j->comp_v_samp[1] != 1)) ||
1479
0
        ((j->comp_h_samp[2] != 1) || (j->comp_v_samp[2] != 1))) {
1480
0
      lwsl_jpeg("%s: samps not 1 (2)\n", __func__);
1481
1482
0
      return LWS_SRET_FATAL + 26;
1483
0
    }
1484
1485
0
    if ((j->comp_h_samp[0] == 1) && (j->comp_v_samp[0] == 1)) {
1486
0
      j->scan_type = PJPG_YH1V1;
1487
1488
0
      j->mcu_max_blocks = 3;
1489
0
      j->mcu_org_id[0] = 0;
1490
0
      j->mcu_org_id[1] = 1;
1491
0
      j->mcu_org_id[2] = 2;
1492
1493
0
      j->mcu_max_size_x = 8;
1494
0
      j->mcu_max_size_y = 8;
1495
0
      break;
1496
0
    }
1497
    
1498
0
    if ((j->comp_h_samp[0] == 1) && (j->comp_v_samp[0] == 2)) {
1499
0
      j->scan_type = PJPG_YH1V2;
1500
1501
0
      j->mcu_max_blocks = 4;
1502
0
      j->mcu_org_id[0] = 0;
1503
0
      j->mcu_org_id[1] = 0;
1504
0
      j->mcu_org_id[2] = 1;
1505
0
      j->mcu_org_id[3] = 2;
1506
1507
0
      j->mcu_max_size_x = 8;
1508
0
      j->mcu_max_size_y = 16;
1509
      
1510
0
      break;
1511
0
    }
1512
    
1513
0
    if ((j->comp_h_samp[0] == 2) && (j->comp_v_samp[0] == 1)) {
1514
0
      j->scan_type = PJPG_YH2V1;
1515
1516
0
      j->mcu_max_blocks = 4;
1517
0
      j->mcu_org_id[0] = 0;
1518
0
      j->mcu_org_id[1] = 0;
1519
0
      j->mcu_org_id[2] = 1;
1520
0
      j->mcu_org_id[3] = 2;
1521
1522
0
      j->mcu_max_size_x = 16;
1523
0
      j->mcu_max_size_y = 8;
1524
      
1525
0
      break;
1526
0
    }
1527
    
1528
0
    if ((j->comp_h_samp[0] == 2) && (j->comp_v_samp[0] == 2)) {
1529
0
      j->scan_type = PJPG_YH2V2;
1530
1531
0
      j->mcu_max_blocks = 6;
1532
0
      j->mcu_org_id[0] = 0;
1533
0
      j->mcu_org_id[1] = 0;
1534
0
      j->mcu_org_id[2] = 0;
1535
0
      j->mcu_org_id[3] = 0;
1536
0
      j->mcu_org_id[4] = 1;
1537
0
      j->mcu_org_id[5] = 2;
1538
1539
0
      j->mcu_max_size_x = 16;
1540
0
      j->mcu_max_size_y = 16;
1541
      
1542
0
      break;
1543
0
    }
1544
    
1545
    /* fallthru */
1546
1547
0
  default:
1548
0
    lwsl_jpeg("%s: unknown chroma scheme\n", __func__);
1549
1550
0
    return LWS_SRET_FATAL;
1551
0
  }
1552
1553
0
  j->mcu_max_row = (uint16_t)
1554
0
      ((j->image_width + (j->mcu_max_size_x - 1)) >>
1555
0
                  ((j->mcu_max_size_x == 8) ? 3 : 4));
1556
0
  j->mcu_max_col = (uint16_t)
1557
0
      ((j->image_height + (j->mcu_max_size_y - 1)) >>
1558
0
                  ((j->mcu_max_size_y == 8) ? 3 : 4));
1559
1560
0
  j->mcu_count_left_x = j->mcu_max_row;
1561
0
  j->mcu_count_left_y = j->mcu_max_col;
1562
1563
0
  return LWS_SRET_OK;
1564
0
}
1565
//----------------------------------------------------------------------------
1566
// Winograd IDCT: 5 multiplies per row/col, up to 80 muls for the 2D IDCT
1567
1568
0
#define PJPG_DCT_SCALE_BITS 7
1569
1570
#define PJPG_DCT_SCALE (1U << PJPG_DCT_SCALE_BITS)
1571
1572
0
#define PJPG_DESCALE(x) PJPG_ARITH_SHIFT_RIGHT_N_16(((x) + \
1573
0
    (1 << (PJPG_DCT_SCALE_BITS - 1))), PJPG_DCT_SCALE_BITS)
1574
1575
#define PJPG_WFIX(x) ((x) * PJPG_DCT_SCALE + 0.5f)
1576
1577
0
#define PJPG_WINOGRAD_QUANT_SCALE_BITS 10
1578
1579
const uint8_t winograd[] = { 128, 178, 178, 167, 246, 167, 151, 232, 232,
1580
                151, 128, 209, 219, 209, 128, 101, 178, 197, 197, 178, 101, 69,
1581
                139, 167, 177, 167, 139, 69, 35, 96, 131, 151, 151, 131, 96, 35,
1582
                49, 91, 118, 128, 118, 91, 49, 46, 81, 101, 101, 81, 46, 42, 69,
1583
                79, 69, 42, 35, 54, 54, 35, 28, 37, 28, 19, 19, 10, };
1584
1585
// Multiply quantization matrix by the Winograd IDCT scale factors
1586
static void
1587
createWinogradQuant(lws_jpeg_t *j, int16_t *pq)
1588
0
{
1589
0
  uint8_t i;
1590
1591
0
  for (i = 0; i < 64; i++) {
1592
0
    long x = pq[i];
1593
1594
0
    x *= winograd[i];
1595
0
    pq[i] = (int16_t)((x + (1 << (PJPG_WINOGRAD_QUANT_SCALE_BITS -
1596
0
                                      PJPG_DCT_SCALE_BITS - 1))) >>
1597
0
                           (PJPG_WINOGRAD_QUANT_SCALE_BITS -
1598
0
                            PJPG_DCT_SCALE_BITS));
1599
0
  }
1600
0
}
1601
1602
/*
1603
 * These multiply helper functions are the 4 types of signed multiplies needed
1604
 * by the Winograd IDCT.
1605
 * A smart C compiler will optimize them to use 16x8 = 24 bit muls, if not you
1606
 * may need to tweak these functions or drop to CPU specific inline assembly.
1607
 */
1608
1609
// 1/cos(4*pi/16)
1610
// 362, 256+106
1611
static LWS_INLINE int16_t
1612
imul_b1_b3(int16_t w)
1613
0
{
1614
0
  long x = (w * 362L);
1615
1616
0
  x += 128L;
1617
0
  return (int16_t) (PJPG_ARITH_SHIFT_RIGHT_8_L(x));
1618
0
}
1619
1620
// 1/cos(6*pi/16)
1621
// 669, 256+256+157
1622
static LWS_INLINE int16_t
1623
imul_b2(int16_t w)
1624
0
{
1625
0
  long x = (w * 669L);
1626
1627
0
  x += 128L;
1628
0
  return (int16_t) (PJPG_ARITH_SHIFT_RIGHT_8_L(x));
1629
0
}
1630
1631
// 1/cos(2*pi/16)
1632
// 277, 256+21
1633
static LWS_INLINE int16_t
1634
imul_b4(int16_t w)
1635
0
{
1636
0
  long x = (w * 277L);
1637
1638
0
  x += 128L;
1639
0
  return (int16_t) (PJPG_ARITH_SHIFT_RIGHT_8_L(x));
1640
0
}
1641
1642
// 1/(cos(2*pi/16) + cos(6*pi/16))
1643
// 196, 196
1644
static LWS_INLINE int16_t
1645
imul_b5(int16_t w)
1646
0
{
1647
0
  long x = (w * 196L);
1648
1649
0
  x += 128L;
1650
0
  return (int16_t) (PJPG_ARITH_SHIFT_RIGHT_8_L(x));
1651
0
}
1652
1653
static LWS_INLINE uint8_t
1654
clamp(int16_t s)
1655
0
{
1656
0
  if (s < 0)
1657
0
    return 0;
1658
1659
0
  if (s > 255)
1660
0
    return 255;
1661
1662
0
  return (uint8_t)s;
1663
0
}
1664
1665
static void
1666
idct_rows(lws_jpeg_t *j)
1667
0
{
1668
0
  int16_t *ps = j->coeffs;
1669
0
  uint8_t i;
1670
1671
0
  for (i = 0; i < 8; i++) {
1672
0
    if (!(ps[1] | ps[2] | ps[3] | ps[4] | ps[5] | ps[6] | ps[7])) {
1673
      /*
1674
       * Short circuit the 1D IDCT if only the DC component
1675
       * is non-zero
1676
       */
1677
0
      int16_t src0 = *ps;
1678
1679
0
      *(ps + 1) = src0;
1680
0
      *(ps + 2) = src0;
1681
0
      *(ps + 3) = src0;
1682
0
      *(ps + 4) = src0;
1683
0
      *(ps + 5) = src0;
1684
0
      *(ps + 6) = src0;
1685
0
      *(ps + 7) = src0;
1686
0
      ps += 8;
1687
0
      continue;
1688
0
    }
1689
1690
0
    int16_t src4 = *(ps + 5);
1691
0
    int16_t src7 = *(ps + 3);
1692
0
    int16_t x4 = (int16_t)(src4 - src7);
1693
0
    int16_t x7 = (int16_t)(src4 + src7);
1694
1695
0
    int16_t src5 = *(ps + 1);
1696
0
    int16_t src6 = *(ps + 7);
1697
0
    int16_t x5 = (int16_t)(src5 + src6);
1698
0
    int16_t x6 = (int16_t)(src5 - src6);
1699
1700
0
    int16_t tmp1 = (int16_t)(imul_b5((int16_t)(x4 - x6)));
1701
0
    int16_t stg26 = (int16_t)(imul_b4(x6) - tmp1);
1702
1703
0
    int16_t x24 = (int16_t)(tmp1 - imul_b2(x4));
1704
1705
0
    int16_t x15 = (int16_t)(x5 - x7);
1706
0
    int16_t x17 = (int16_t)(x5 + x7);
1707
1708
0
    int16_t tmp2 = (int16_t)(stg26 - x17);
1709
0
    int16_t tmp3 = (int16_t)(imul_b1_b3(x15) - tmp2);
1710
0
    int16_t x44 = (int16_t)(tmp3 + x24);
1711
1712
0
    int16_t src0 = *(ps + 0);
1713
0
    int16_t src1 = *(ps + 4);
1714
0
    int16_t x30 = (int16_t)(src0 + src1);
1715
0
    int16_t x31 = (int16_t)(src0 - src1);
1716
1717
0
    int16_t src2 = *(ps + 2);
1718
0
    int16_t src3 = *(ps + 6);
1719
0
    int16_t x12 = (int16_t)(src2 - src3);
1720
0
    int16_t x13 = (int16_t)(src2 + src3);
1721
1722
0
    int16_t x32 = (int16_t)(imul_b1_b3(x12) - x13);
1723
1724
0
    int16_t x40 = (int16_t)(x30 + x13);
1725
0
    int16_t x43 = (int16_t)(x30 - x13);
1726
0
    int16_t x41 = (int16_t)(x31 + x32);
1727
0
    int16_t x42 = (int16_t)(x31 - x32);
1728
1729
0
    *(ps + 0) = (int16_t)(x40 + x17);
1730
0
    *(ps + 1) = (int16_t)(x41 + tmp2);
1731
0
    *(ps + 2) = (int16_t)(x42 + tmp3);
1732
0
    *(ps + 3) = (int16_t)(x43 - x44);
1733
0
    *(ps + 4) = (int16_t)(x43 + x44);
1734
0
    *(ps + 5) = (int16_t)(x42 - tmp3);
1735
0
    *(ps + 6) = (int16_t)(x41 - tmp2);
1736
0
    *(ps + 7) = (int16_t)(x40 - x17);
1737
1738
0
    ps += 8;
1739
0
  }
1740
0
}
1741
1742
static void
1743
idct_cols(lws_jpeg_t *j)
1744
0
{
1745
0
  int16_t *ps = j->coeffs;
1746
0
  uint8_t i;
1747
1748
0
  for (i = 0; i < 8; i++) {
1749
0
    if (!(ps[1 * 8] | ps[2 * 8] | ps[3 * 8] | ps[4 * 8]
1750
0
                    | ps[5 * 8] | ps[6 * 8] | ps[7 * 8])) {
1751
      /*
1752
       * Short circuit the 1D IDCT if only the DC component
1753
       * is non-zero
1754
       */
1755
0
      uint8_t c = clamp((int16_t)(PJPG_DESCALE(*ps) + 128));
1756
0
      *(ps + 0 * 8) = c;
1757
0
      *(ps + 1 * 8) = c;
1758
0
      *(ps + 2 * 8) = c;
1759
0
      *(ps + 3 * 8) = c;
1760
0
      *(ps + 4 * 8) = c;
1761
0
      *(ps + 5 * 8) = c;
1762
0
      *(ps + 6 * 8) = c;
1763
0
      *(ps + 7 * 8) = c;
1764
0
      ps++;
1765
0
      continue;
1766
0
    }
1767
1768
0
    int16_t src4 = *(ps + 5 * 8);
1769
0
    int16_t src7 = *(ps + 3 * 8);
1770
0
    int16_t x4 = (int16_t)(src4 - src7);
1771
0
    int16_t x7 = (int16_t)(src4 + src7);
1772
1773
0
    int16_t src5 = *(ps + 1 * 8);
1774
0
    int16_t src6 = *(ps + 7 * 8);
1775
0
    int16_t x5 = (int16_t)(src5 + src6);
1776
0
    int16_t x6 = (int16_t)(src5 - src6);
1777
1778
0
    int16_t tmp1 = (int16_t)(imul_b5((int16_t)(x4 - x6)));
1779
0
    int16_t stg26 = (int16_t)(imul_b4(x6) - tmp1);
1780
1781
0
    int16_t x24 = (int16_t)(tmp1 - imul_b2(x4));
1782
1783
0
    int16_t x15 = (int16_t)(x5 - x7);
1784
0
    int16_t x17 = (int16_t)(x5 + x7);
1785
1786
0
    int16_t tmp2 = (int16_t)(stg26 - x17);
1787
0
    int16_t tmp3 = (int16_t)(imul_b1_b3(x15) - tmp2);
1788
0
    int16_t x44 = (int16_t)(tmp3 + x24);
1789
1790
0
    int16_t src0 = *(ps + 0 * 8);
1791
0
    int16_t src1 = *(ps + 4 * 8);
1792
0
    int16_t x30 = (int16_t)(src0 + src1);
1793
0
    int16_t x31 = (int16_t)(src0 - src1);
1794
1795
0
    int16_t src2 = *(ps + 2 * 8);
1796
0
    int16_t src3 = *(ps + 6 * 8);
1797
0
    int16_t x12 = (int16_t)(src2 - src3);
1798
0
    int16_t x13 = (int16_t)(src2 + src3);
1799
1800
0
    int16_t x32 = (int16_t)(imul_b1_b3(x12) - x13);
1801
1802
0
    int16_t x40 = (int16_t)(x30 + x13);
1803
0
    int16_t x43 = (int16_t)(x30 - x13);
1804
0
    int16_t x41 = (int16_t)(x31 + x32);
1805
0
    int16_t x42 = (int16_t)(x31 - x32);
1806
1807
    // descale, convert to unsigned and clamp to 8-bit
1808
0
    *(ps + 0 * 8) = clamp((int16_t)(PJPG_DESCALE(x40 + x17) + 128));
1809
0
    *(ps + 1 * 8) = clamp((int16_t)(PJPG_DESCALE(x41 + tmp2) + 128));
1810
0
    *(ps + 2 * 8) = clamp((int16_t)(PJPG_DESCALE(x42 + tmp3) + 128));
1811
0
    *(ps + 3 * 8) = clamp((int16_t)(PJPG_DESCALE(x43 - x44) + 128));
1812
0
    *(ps + 4 * 8) = clamp((int16_t)(PJPG_DESCALE(x43 + x44) + 128));
1813
0
    *(ps + 5 * 8) = clamp((int16_t)(PJPG_DESCALE(x42 - tmp3) + 128));
1814
0
    *(ps + 6 * 8) = clamp((int16_t)(PJPG_DESCALE(x41 - tmp2) + 128));
1815
0
    *(ps + 7 * 8) = clamp((int16_t)(PJPG_DESCALE(x40 - x17) + 128));
1816
1817
0
    ps++;
1818
0
  }
1819
0
}
1820
1821
static LWS_INLINE uint8_t
1822
add_clamp(uint8_t a, int16_t b)
1823
0
{
1824
0
  b = (int16_t)(a + b);
1825
1826
0
  if (b > 255)
1827
0
    return 255;
1828
1829
0
  if (b < 0)
1830
0
    return 0;
1831
1832
0
  return (uint8_t)b;
1833
0
}
1834
1835
static LWS_INLINE uint8_t
1836
sub_clamp(uint8_t a, int16_t b)
1837
0
{
1838
0
  b = (int16_t)(a - b);
1839
1840
0
  if (b > 255)
1841
0
    return 255;
1842
1843
0
  if (b < 0)
1844
0
    return 0;
1845
1846
0
  return (uint8_t)b;
1847
0
}
1848
1849
// 103/256
1850
//R = Y + 1.402 (Cr-128)
1851
// 88/256, 183/256
1852
//G = Y - 0.34414 (Cb-128) - 0.71414 (Cr-128)
1853
// 198/256
1854
//B = Y + 1.772 (Cb-128)
1855
1856
// Cb upsample and accumulate, 4x4 to 8x8
1857
static void
1858
upsample_cb(lws_jpeg_t *j, uint8_t src_ofs, uint8_t dst_ofs)
1859
0
{
1860
  // Cb - affects G and B
1861
0
  uint8_t x, y;
1862
0
  int16_t *ps = j->coeffs + src_ofs;
1863
0
  uint8_t *pg = j->mcu_buf_G + dst_ofs;
1864
0
  uint8_t *pb = j->mcu_buf_B + dst_ofs;
1865
1866
0
  for (y = 0; y < 4; y++) {
1867
0
    for (x = 0; x < 4; x++) {
1868
0
      uint8_t cb = (uint8_t) *ps++;
1869
0
      int16_t cbG, cbB;
1870
1871
0
      cbG = (int16_t)(((cb * 88U) >> 8U) - 44U);
1872
0
      pg[0] = sub_clamp(pg[0], cbG);
1873
0
      pg[1] = sub_clamp(pg[1], cbG);
1874
0
      pg[8] = sub_clamp(pg[8], cbG);
1875
0
      pg[9] = sub_clamp(pg[9], cbG);
1876
1877
0
      cbB = (int16_t)((cb + ((cb * 198U) >> 8U)) - 227U);
1878
0
      pb[0] = add_clamp(pb[0], cbB);
1879
0
      pb[1] = add_clamp(pb[1], cbB);
1880
0
      pb[8] = add_clamp(pb[8], cbB);
1881
0
      pb[9] = add_clamp(pb[9], cbB);
1882
1883
0
      pg += 2;
1884
0
      pb += 2;
1885
0
    }
1886
1887
0
    ps = ps - 4 + 8;
1888
0
    pg = pg - 8 + 16;
1889
0
    pb = pb - 8 + 16;
1890
0
  }
1891
0
}
1892
1893
// Cb upsample and accumulate, 4x8 to 8x8
1894
static void
1895
upsample_cbh(lws_jpeg_t *j, uint8_t src_ofs, uint8_t dst_ofs)
1896
0
{
1897
  // Cb - affects G and B
1898
0
  int16_t *ps = j->coeffs + src_ofs;
1899
0
  uint8_t *pg = j->mcu_buf_G + dst_ofs;
1900
0
  uint8_t *pb = j->mcu_buf_B + dst_ofs;
1901
0
  uint8_t x, y;
1902
1903
0
  for (y = 0; y < 8; y++) {
1904
0
    for (x = 0; x < 4; x++) {
1905
0
      uint8_t cb = (uint8_t) *ps++;
1906
0
      int16_t cbG, cbB;
1907
1908
0
      cbG = (int16_t)(((cb * 88U) >> 8U) - 44U);
1909
0
      pg[0] = sub_clamp(pg[0], cbG);
1910
0
      pg[1] = sub_clamp(pg[1], cbG);
1911
1912
0
      cbB = (int16_t)((cb + ((cb * 198U) >> 8U)) - 227U);
1913
0
      pb[0] = add_clamp(pb[0], cbB);
1914
0
      pb[1] = add_clamp(pb[1], cbB);
1915
1916
0
      pg += 2;
1917
0
      pb += 2;
1918
0
    }
1919
1920
0
    ps = ps - 4 + 8;
1921
0
  }
1922
0
}
1923
1924
// Cb upsample and accumulate, 8x4 to 8x8
1925
static void
1926
upsample_cbv(lws_jpeg_t *j, uint8_t src_ofs, uint8_t dst_ofs)
1927
0
{
1928
  // Cb - affects G and B
1929
0
  int16_t *ps = j->coeffs + src_ofs;
1930
0
  uint8_t *pg = j->mcu_buf_G + dst_ofs;
1931
0
  uint8_t *pb = j->mcu_buf_B + dst_ofs;
1932
0
  uint8_t x, y;
1933
1934
0
  for (y = 0; y < 4; y++) {
1935
0
    for (x = 0; x < 8; x++) {
1936
0
      uint8_t cb = (uint8_t) *ps++;
1937
0
      int16_t cbG, cbB;
1938
1939
0
      cbG = (int16_t)(((cb * 88U) >> 8U) - 44U);
1940
0
      pg[0] = sub_clamp(pg[0], cbG);
1941
0
      pg[8] = sub_clamp(pg[8], cbG);
1942
1943
0
      cbB = (int16_t)((cb + ((cb * 198U) >> 8U)) - 227U);
1944
0
      pb[0] = add_clamp(pb[0], cbB);
1945
0
      pb[8] = add_clamp(pb[8], cbB);
1946
1947
0
      ++pg;
1948
0
      ++pb;
1949
0
    }
1950
1951
0
    pg = pg - 8 + 16;
1952
0
    pb = pb - 8 + 16;
1953
0
  }
1954
0
}
1955
1956
// 103/256
1957
//R = Y + 1.402 (Cr-128)
1958
// 88/256, 183/256
1959
//G = Y - 0.34414 (Cb-128) - 0.71414 (Cr-128)
1960
// 198/256
1961
//B = Y + 1.772 (Cb-128)
1962
1963
// Cr upsample and accumulate, 4x4 to 8x8
1964
static void
1965
upsample_cr(lws_jpeg_t *j, uint8_t src_ofs, uint8_t dst_ofs)
1966
0
{
1967
  // Cr - affects R and G
1968
0
  uint8_t x, y;
1969
0
  int16_t *ps = j->coeffs + src_ofs;
1970
0
  uint8_t *pr = j->mcu_buf_R + dst_ofs;
1971
0
  uint8_t *pg = j->mcu_buf_G + dst_ofs;
1972
1973
0
  for (y = 0; y < 4; y++) {
1974
0
    for (x = 0; x < 4; x++) {
1975
0
      uint8_t cr = (uint8_t) *ps++;
1976
0
      int16_t crR, crG;
1977
1978
0
      crR = (int16_t)((cr + ((cr * 103U) >> 8U)) - 179);
1979
0
      pr[0] = add_clamp(pr[0], crR);
1980
0
      pr[1] = add_clamp(pr[1], crR);
1981
0
      pr[8] = add_clamp(pr[8], crR);
1982
0
      pr[9] = add_clamp(pr[9], crR);
1983
1984
0
      crG = (int16_t)(((cr * 183U) >> 8U) - 91);
1985
0
      pg[0] = sub_clamp(pg[0], crG);
1986
0
      pg[1] = sub_clamp(pg[1], crG);
1987
0
      pg[8] = sub_clamp(pg[8], crG);
1988
0
      pg[9] = sub_clamp(pg[9], crG);
1989
1990
0
      pr += 2;
1991
0
      pg += 2;
1992
0
    }
1993
1994
0
    ps = ps - 4 + 8;
1995
0
    pr = pr - 8 + 16;
1996
0
    pg = pg - 8 + 16;
1997
0
  }
1998
0
}
1999
2000
// Cr upsample and accumulate, 4x8 to 8x8
2001
static void
2002
upsample_crh(lws_jpeg_t *j, uint8_t src_ofs, uint8_t dst_ofs)
2003
0
{
2004
  // Cr - affects R and G
2005
0
  uint8_t x, y;
2006
0
  int16_t *ps = j->coeffs + src_ofs;
2007
0
  uint8_t *pr = j->mcu_buf_R + dst_ofs;
2008
0
  uint8_t *pg = j->mcu_buf_G + dst_ofs;
2009
2010
0
  for (y = 0; y < 8; y++) {
2011
0
    for (x = 0; x < 4; x++) {
2012
0
      uint8_t cr = (uint8_t) *ps++;
2013
0
      int16_t crR, crG;
2014
2015
0
      crR = (int16_t)((cr + ((cr * 103U) >> 8U)) - 179);
2016
0
      pr[0] = add_clamp(pr[0], crR);
2017
0
      pr[1] = add_clamp(pr[1], crR);
2018
2019
0
      crG = (int16_t)(((cr * 183U) >> 8U) - 91);
2020
0
      pg[0] = sub_clamp(pg[0], crG);
2021
0
      pg[1] = sub_clamp(pg[1], crG);
2022
2023
0
      pr += 2;
2024
0
      pg += 2;
2025
0
    }
2026
2027
0
    ps = ps - 4 + 8;
2028
0
  }
2029
0
}
2030
2031
// Cr upsample and accumulate, 8x4 to 8x8
2032
static void
2033
upsample_crv(lws_jpeg_t *j, uint8_t src_ofs, uint8_t dst_ofs)
2034
0
{
2035
  // Cr - affects R and G
2036
0
  uint8_t x, y;
2037
0
  int16_t *ps = j->coeffs + src_ofs;
2038
0
  uint8_t *pr = j->mcu_buf_R + dst_ofs;
2039
0
  uint8_t *pg = j->mcu_buf_G + dst_ofs;
2040
2041
0
  for (y = 0; y < 4; y++) {
2042
0
    for (x = 0; x < 8; x++) {
2043
0
      uint8_t cr = (uint8_t) *ps++;
2044
0
      int16_t crR, crG;
2045
2046
0
      crR = (int16_t)((cr + ((cr * 103U) >> 8U)) - 179);
2047
0
      pr[0] = add_clamp(pr[0], crR);
2048
0
      pr[8] = add_clamp(pr[8], crR);
2049
2050
0
      crG = (int16_t)(((cr * 183U) >> 8U) - 91);
2051
0
      pg[0] = sub_clamp(pg[0], crG);
2052
0
      pg[8] = sub_clamp(pg[8], crG);
2053
2054
0
      ++pr;
2055
0
      ++pg;
2056
0
    }
2057
2058
0
    pr = pr - 8 + 16;
2059
0
    pg = pg - 8 + 16;
2060
0
  }
2061
0
}
2062
2063
// Convert Y to RGB
2064
static void
2065
copy_y(lws_jpeg_t *j, uint8_t dst_ofs)
2066
0
{
2067
0
  uint8_t i;
2068
0
  uint8_t *pRDst = j->mcu_buf_R + dst_ofs;
2069
0
  uint8_t *pGDst = j->mcu_buf_G + dst_ofs;
2070
0
  uint8_t *pBDst = j->mcu_buf_B + dst_ofs;
2071
0
  int16_t *ps = j->coeffs;
2072
2073
0
  for (i = 64; i > 0; i--) {
2074
0
    uint8_t c = (uint8_t) *ps++;
2075
2076
0
    *pRDst++ = c;
2077
0
    *pGDst++ = c;
2078
0
    *pBDst++ = c;
2079
0
  }
2080
0
}
2081
2082
// Cb convert to RGB and accumulate
2083
static void
2084
convert_cb(lws_jpeg_t *j, uint8_t dst_ofs)
2085
0
{
2086
0
  uint8_t i;
2087
0
  uint8_t *pg = j->mcu_buf_G + dst_ofs;
2088
0
  uint8_t *pb = j->mcu_buf_B + dst_ofs;
2089
0
  int16_t *ps = j->coeffs;
2090
2091
0
  for (i = 64; i > 0; i--) {
2092
0
    uint8_t cb = (uint8_t) *ps++;
2093
0
    int16_t cbG, cbB;
2094
2095
0
    cbG = (int16_t)(((cb * 88U) >> 8U) - 44U);
2096
0
    *pg = sub_clamp(pg[0], cbG);
2097
0
    pg++;
2098
2099
0
    cbB = (int16_t)((cb + ((cb * 198U) >> 8U)) - 227U);
2100
0
    *pb = add_clamp(pb[0], cbB);
2101
0
    pb++;
2102
0
  }
2103
0
}
2104
2105
// Cr convert to RGB and accumulate
2106
static void
2107
convert_cr(lws_jpeg_t *j, uint8_t dst_ofs)
2108
0
{
2109
0
  uint8_t i;
2110
0
  uint8_t *pr = j->mcu_buf_R + dst_ofs;
2111
0
  uint8_t *pg = j->mcu_buf_G + dst_ofs;
2112
0
  int16_t *ps = j->coeffs;
2113
2114
0
  for (i = 64; i > 0; i--) {
2115
0
    uint8_t cr = (uint8_t) *ps++;
2116
0
    int16_t crR, crG;
2117
2118
0
    crR = (int16_t)((cr + ((cr * 103U) >> 8U)) - 179);
2119
0
    *pr = add_clamp(pr[0], crR);
2120
0
    pr++;
2121
2122
0
    crG = (int16_t)(((cr * 183U) >> 8U) - 91);
2123
0
    *pg = sub_clamp(pg[0], crG);
2124
0
    pg++;
2125
0
  }
2126
0
}
2127
2128
static void
2129
transform_block(lws_jpeg_t *j, uint8_t mb)
2130
0
{
2131
0
  idct_rows(j);
2132
0
  idct_cols(j);
2133
2134
0
  switch (j->scan_type) {
2135
0
  case PJPG_GRAYSCALE:
2136
    // MCU size: 1, 1 block per MCU
2137
0
    copy_y(j, 0);
2138
0
    break;
2139
2140
0
  case PJPG_YH1V1:
2141
    // MCU size: 8x8, 3 blocks per MCU
2142
0
    switch (mb) {
2143
0
    case 0:
2144
0
      copy_y(j, 0);
2145
0
      break;
2146
2147
0
    case 1:
2148
0
      convert_cb(j, 0);
2149
0
      break;
2150
2151
0
    case 2:
2152
0
      convert_cr(j, 0);
2153
0
      break;
2154
0
    }
2155
2156
0
    break;
2157
2158
0
  case PJPG_YH1V2:
2159
    // MCU size: 8x16, 4 blocks per MCU
2160
0
    switch (mb) {
2161
0
    case 0:
2162
0
      copy_y(j, 0);
2163
0
      break;
2164
2165
0
    case 1:
2166
0
      copy_y(j, 128);
2167
0
      break;
2168
2169
0
    case 2:
2170
0
      upsample_cbv(j, 0, 0);
2171
0
      upsample_cbv(j, 4 * 8, 128);
2172
0
      break;
2173
2174
0
    case 3:
2175
0
      upsample_crv(j, 0, 0);
2176
0
      upsample_crv(j, 4 * 8, 128);
2177
0
      break;
2178
0
    }
2179
0
    break;
2180
2181
0
  case PJPG_YH2V1:
2182
    // MCU size: 16x8, 4 blocks per MCU
2183
0
    switch (mb) {
2184
0
    case 0:
2185
0
      copy_y(j, 0);
2186
0
      break;
2187
2188
0
    case 1:
2189
0
      copy_y(j, 64);
2190
0
      break;
2191
2192
0
    case 2:
2193
0
      upsample_cbh(j, 0, 0);
2194
0
      upsample_cbh(j, 4, 64);
2195
0
      break;
2196
2197
0
    case 3:
2198
0
      upsample_crh(j, 0, 0);
2199
0
      upsample_crh(j, 4, 64);
2200
0
      break;
2201
0
    }
2202
0
    break;
2203
2204
0
  case PJPG_YH2V2:
2205
    // MCU size: 16x16, 6 blocks per MCU
2206
0
    switch (mb) {
2207
0
    case 0:
2208
0
      copy_y(j, 0);
2209
0
      break;
2210
2211
0
    case 1:
2212
0
      copy_y(j, 64);
2213
0
      break;
2214
2215
0
    case 2:
2216
0
      copy_y(j, 128);
2217
0
      break;
2218
2219
0
    case 3:
2220
0
      copy_y(j, 192);
2221
0
      break;
2222
2223
0
    case 4:
2224
0
      upsample_cb(j, 0, 0);
2225
0
      upsample_cb(j, 4, 64);
2226
0
      upsample_cb(j, 4 * 8, 128);
2227
0
      upsample_cb(j, 4 + 4 * 8, 192);
2228
0
      break;
2229
2230
0
    case 5:
2231
0
      upsample_cr(j, 0, 0);
2232
0
      upsample_cr(j, 4, 64);
2233
0
      upsample_cr(j, 4 * 8, 128);
2234
0
      upsample_cr(j, 4 + 4 * 8, 192);
2235
0
      break;
2236
0
    }
2237
0
    break;
2238
0
  }
2239
0
}
2240
2241
static lws_stateful_ret_t
2242
lws_jpeg_mcu_next(lws_jpeg_t *j)
2243
0
{
2244
0
  unsigned int x, y, row_pitch = (unsigned int)(j->frame_comps *
2245
0
                  j->image_width);
2246
0
  lws_stateful_ret_t r;
2247
2248
0
  if (!j->fs_mcu_phase) {
2249
0
    if (j->restart_interval) {
2250
0
      if (j->restarts_left == 0) {
2251
0
        lwsl_err("%s: process_restart\n", __func__);
2252
0
        r = interval_restart(j);
2253
0
        if (r)
2254
0
          return r;
2255
0
      }
2256
0
      j->restarts_left--;
2257
0
    }
2258
    
2259
0
    j->fs_mcu_mb = 0;
2260
0
    j->fs_mcu_phase++;
2261
0
  }
2262
2263
0
  while (j->fs_mcu_mb < j->mcu_max_blocks) {
2264
0
    uint8_t id = j->mcu_org_id[j->fs_mcu_mb];
2265
0
    uint8_t compDCTab = j->comp_dc[id];
2266
0
    uint8_t compq = j->comp_quant[id];
2267
0
    const int16_t *pQ = compq ? j->quant1 : j->quant0;
2268
0
    uint8_t nexb, compACTab, c;
2269
0
    uint16_t xr;
2270
0
    int16_t dc;
2271
0
    uint8_t s;
2272
2273
0
    switch (j->fs_mcu_phase) {
2274
0
    case 1:
2275
0
      r = huff_decode(j, &j->fs_mcu_s, compDCTab ?
2276
0
           &j->huff_tab1 : &j->huff_tab0,
2277
0
               compDCTab ?
2278
0
           j->huff_val1 : j->huff_val0);
2279
0
      if (r)
2280
0
        return r;
2281
2282
0
      if (j->seen_eoi)
2283
0
        return LWS_SRET_OK;
2284
2285
0
      j->fs_mcu_phase++;
2286
      
2287
      /* fallthru */
2288
2289
0
    case 2:
2290
0
      xr = 0;
2291
0
      nexb = j->fs_mcu_s & 0xf;
2292
0
      if (nexb) {
2293
0
        if (nexb > 8)
2294
0
          r = get_bits16(j, &xr, nexb, 1);
2295
0
        else {
2296
0
          c = 0;
2297
0
          r = get_bits8(j, &c, nexb, 1);
2298
0
          xr = c;
2299
0
        }
2300
2301
0
        if (r)
2302
0
          return r;
2303
0
      }
2304
2305
0
      dc = (int16_t)(huff_extend(xr, j->fs_mcu_s) +
2306
0
                j->last_dc[id]);
2307
0
      j->last_dc[id] = (int16_t)dc;
2308
0
      j->coeffs[0] = (int16_t)(dc * pQ[0]);
2309
2310
0
      j->fs_mcu_k = 1;
2311
0
      j->fs_mcu_phase_loop = 0;
2312
0
      j->fs_mcu_phase++;
2313
2314
      /* fallthru */
2315
2316
0
    case 3:
2317
0
      compACTab = j->comp_ac[id];
2318
2319
      /* Decode and dequantize AC coefficients */
2320
0
      while (j->fs_mcu_k < 64) {
2321
0
        uint16_t exb;
2322
2323
0
        if (!j->fs_mcu_phase_loop) {
2324
0
          r = huff_decode(j, &j->fs_mcu_s,
2325
0
              compACTab ?
2326
0
            &j->huff_tab3 : &j->huff_tab2,
2327
0
              compACTab ?
2328
0
            j->huff_val3 : j->huff_val2);
2329
0
          if (j->seen_eoi)
2330
0
            return LWS_SRET_OK;
2331
0
          if (r)
2332
0
            return r;
2333
2334
0
          j->fs_mcu_phase_loop = 1;
2335
0
        }
2336
2337
0
        exb = 0;
2338
0
        nexb = j->fs_mcu_s & 0xf;
2339
0
        if (nexb) {
2340
0
          if (nexb > 8)
2341
0
            r = get_bits16(j, &exb, nexb, 1);
2342
0
          else {
2343
0
            c = 0;
2344
0
            r = get_bits8(j, &c, nexb, 1);
2345
0
            exb = (uint16_t)c;
2346
0
          }
2347
0
          if (r)
2348
0
            return r;
2349
0
        }
2350
2351
0
        xr = (j->fs_mcu_s >> 4) & 0xf;
2352
0
        s = j->fs_mcu_s & 15;
2353
2354
0
        if (s) {
2355
0
          if (xr) {
2356
0
            if ((j->fs_mcu_k + xr) > 63) {
2357
0
              lwsl_jpeg("%s: k oflow\n",
2358
0
                  __func__);
2359
2360
0
              return LWS_SRET_FATAL;
2361
0
            }
2362
2363
0
            while (xr--)
2364
0
              j->coeffs[(int)ZAG[
2365
0
                (unsigned int)
2366
0
                j->fs_mcu_k++]] = 0;
2367
0
          }
2368
2369
0
          j->coeffs[(int)ZAG[(unsigned int)
2370
0
                  j->fs_mcu_k]] = (int16_t)(
2371
0
            huff_extend(exb, s) *
2372
0
            pQ[(unsigned int)j->fs_mcu_k]);
2373
0
        } else {
2374
0
          if (xr != 15)
2375
0
            break; /* early loop exit */
2376
2377
0
          if (((unsigned int)j->fs_mcu_k + 16) > 64) {
2378
0
            lwsl_jpeg("%s: k > 64\n", __func__);
2379
0
            return LWS_SRET_FATAL;
2380
0
          }
2381
2382
0
          for (xr = 16; xr > 0; xr--)
2383
0
            j->coeffs[(int)ZAG[(unsigned int)
2384
0
                        j->fs_mcu_k++]] = 0;
2385
2386
0
          j->fs_mcu_k--;
2387
0
        }
2388
2389
0
        j->fs_mcu_phase_loop = 0;
2390
0
        j->fs_mcu_k++;
2391
0
      } /* while k < 64 */
2392
2393
0
      while (j->fs_mcu_k < 64)
2394
0
        j->coeffs[(int)ZAG[(unsigned int)
2395
0
                           j->fs_mcu_k++]] = 0;
2396
2397
0
      transform_block(j, j->fs_mcu_mb);
2398
2399
0
      break;
2400
0
    } /* switch */
2401
2402
0
    j->fs_mcu_phase = 1;
2403
0
    j->fs_mcu_mb++;
2404
0
  } /* while mb */
2405
2406
  /*
2407
   * Place the MCB into the allocated, MCU-height pixel buffer
2408
   */
2409
2410
0
   uint8_t *dr = j->lines + (j->mcu_ofs_x * j->mcu_max_size_x *
2411
0
           j->frame_comps);
2412
2413
0
         for (y = 0; y < j->mcu_max_size_y; y += 8) {
2414
0
    unsigned int by_limit = (unsigned int)((unsigned int)j->image_height -
2415
0
          (unsigned int)((unsigned int)j->mcu_ofs_y *
2416
0
          (unsigned int)j->mcu_max_size_y +
2417
0
              (unsigned int)y));
2418
2419
0
    if (by_limit > 8)
2420
0
      by_limit = 8;
2421
2422
0
    for (x = 0; x < j->mcu_max_size_x; x += 8) {
2423
0
      uint8_t *db = dr + (x * j->frame_comps);
2424
0
      uint8_t src_ofs = (uint8_t)((x * 8U) + (y * 16U));
2425
0
      const uint8_t *pSrcR = j->mcu_buf_R + src_ofs;
2426
0
      const uint8_t *pSrcG = j->mcu_buf_G + src_ofs;
2427
0
      const uint8_t *pSrcB = j->mcu_buf_B + src_ofs;
2428
0
      unsigned int bx_limit = (unsigned int)(
2429
0
        (unsigned int)j->image_width -
2430
0
        (unsigned int)((unsigned int)j->mcu_ofs_x *
2431
0
        (unsigned int)j->mcu_max_size_x +
2432
0
              (unsigned int)x));
2433
0
      unsigned int bx, by;
2434
2435
0
      if (bx_limit > 8)
2436
0
        bx_limit = 8;
2437
2438
0
      if (j->scan_type == PJPG_GRAYSCALE) {
2439
0
        for (by = 0; by < by_limit; by++) {
2440
0
          uint8_t *pDst = db;
2441
2442
0
          for (bx = 0; bx < bx_limit; bx++)
2443
0
            *pDst++ = *pSrcR++;
2444
2445
0
          pSrcR += (8 - bx_limit);
2446
2447
0
          db += row_pitch;
2448
0
        }
2449
0
      } else {
2450
0
        for (by = 0; by < by_limit; by++) {
2451
0
          uint8_t *pDst = db;
2452
2453
0
          for (bx = 0; bx < bx_limit; bx++) {
2454
0
            pDst[0] = *pSrcR++;
2455
0
            pDst[1] = *pSrcG++;
2456
0
            pDst[2] = *pSrcB++;
2457
0
            pDst += 3;
2458
0
          }
2459
2460
0
          pSrcR += (8 - bx_limit);
2461
0
          pSrcG += (8 - bx_limit);
2462
0
          pSrcB += (8 - bx_limit);
2463
2464
0
          db += row_pitch;
2465
0
        }
2466
0
      }
2467
0
    } /* x */
2468
2469
    /* keep it inside allocated MCU buffer area */
2470
2471
0
    dr += (row_pitch * 8);
2472
0
    if (dr >= j->lines + (row_pitch * j->mcu_max_size_y))
2473
0
      dr -= j->mcu_max_size_y * row_pitch;
2474
0
  } /* y */
2475
2476
0
  if (j->mcu_ofs_x++ == j->mcu_max_row - 1) {
2477
0
    j->mcu_ofs_x = 0;
2478
0
    j->mcu_ofs_y++;
2479
0
  }
2480
2481
0
  j->fs_mcu_phase = 0;
2482
2483
0
  return LWS_SRET_OK;
2484
0
}
2485
2486
lws_jpeg_t *
2487
lws_jpeg_new(void)
2488
0
{
2489
0
  lws_jpeg_t *j = lws_zalloc(sizeof(*j), __func__);
2490
2491
0
  if (!j)
2492
0
    return NULL;
2493
2494
0
  return j;
2495
0
}
2496
2497
void
2498
lws_jpeg_free(lws_jpeg_t **j)
2499
0
{
2500
0
  lws_free_set_NULL((*j)->lines);
2501
0
  lws_free_set_NULL(*j);
2502
0
}
2503
2504
lws_stateful_ret_t
2505
lws_jpeg_emit_next_line(lws_jpeg_t *j, const uint8_t **ppix,
2506
      const uint8_t **buf, size_t *size, char hold_at_metadata)
2507
0
{
2508
0
  lws_stateful_ret_t r = 0;
2509
0
  size_t mcu_buf_len;
2510
2511
0
  j->inbuf = *buf;
2512
0
  j->insize = *size;
2513
0
  j->hold_at_metadata = hold_at_metadata;
2514
2515
0
  do {
2516
0
    switch (j->dstate) {
2517
2518
0
    case LWSJDS_FIND_SOI_INIT1:
2519
0
      j->fs_emit_budget = 4096;
2520
0
      r = get_bits8(j, &j->fs_emit_lc, 8, 0);
2521
0
      if (r)
2522
0
        goto fin;
2523
0
      j->dstate++;
2524
2525
      /* fallthru */
2526
2527
0
    case LWSJDS_FIND_SOI_INIT2:
2528
0
      r = get_bits8(j, &j->fs_emit_tc, 8, 0);
2529
0
      if (r)
2530
0
        goto fin;
2531
      
2532
0
      if ((j->fs_emit_lc == 0xFF) &&
2533
0
          (j->fs_emit_tc == PJM_SOI)) {
2534
0
        j->dstate = LWSJDS_FIND_SOI;
2535
0
        break;
2536
0
      }
2537
      
2538
0
      j->dstate++;
2539
  
2540
      /* fallthru */
2541
2542
0
    case LWSJDS_FIND_SOI:
2543
  
2544
0
      for (;;) {
2545
  
2546
0
        j->fs_emit_lc = j->fs_emit_tc;
2547
0
        r = get_bits8(j, &j->fs_emit_tc, 8, 0);
2548
0
        if (r)
2549
0
          goto fin;
2550
        
2551
0
        if (--j->fs_emit_budget == 0) {
2552
0
          lwsl_jpeg("%s: SOI emit budget gone\n",
2553
0
                __func__);
2554
2555
0
          return LWS_SRET_FATAL + 28;
2556
0
        }
2557
  
2558
0
        if (j->fs_emit_lc == 0xFF) {
2559
0
          if (j->fs_emit_tc == PJM_SOI)
2560
0
            break;
2561
0
          if (j->fs_emit_tc == PJM_EOI) {
2562
0
            lwsl_jpeg("%s: SOI reached EOI\n",
2563
0
                __func__);
2564
2565
0
            return LWS_SRET_FATAL + 29;
2566
0
          }
2567
0
          lwsl_jpeg("%s: skipping 0x%02x\n", __func__, j->fs_emit_lc);
2568
0
        }
2569
0
      }
2570
  
2571
      /*
2572
       * Check the next character after marker:
2573
       * if it's not 0xFF, it can't be the start of the
2574
       * next marker, so the file is bad
2575
       */
2576
  
2577
0
      j->fs_emit_tc = (uint8_t)((j->bits >> 8) & 0xFF);
2578
  
2579
0
      if (j->fs_emit_tc != 0xFF) {
2580
0
        lwsl_jpeg("%s: not marker\n", __func__);
2581
2582
0
        return LWS_SRET_FATAL + 30;
2583
0
      }
2584
      
2585
0
      j->dstate = LWSJDS_FIND_SOF1;
2586
      
2587
      /* fallthru */
2588
      
2589
0
    case LWSJDS_FIND_SOF1:
2590
2591
0
      r = process_markers(j, &j->fs_emit_c);
2592
0
      if (r)
2593
0
        goto fin;
2594
      
2595
0
      if (j->fs_emit_c == PJM_SOF2) {
2596
0
        lwsl_warn("%s: progressive JPEG not supported\n", __func__);
2597
0
        return LWS_SRET_FATAL + 31;
2598
0
      }
2599
2600
0
      if (j->fs_emit_c != PJM_SOF0) {
2601
0
        lwsl_jpeg("%s: not SOF0 (%d)\n", __func__, (int)j->fs_emit_c);
2602
2603
0
        return LWS_SRET_FATAL + 31;
2604
0
      }
2605
      
2606
0
      j->dstate++;
2607
  
2608
      /* fallthru */
2609
2610
0
    case LWSJDS_FIND_SOF2:
2611
      
2612
0
      r = read_sof_marker(j);
2613
0
      if (r)
2614
0
        goto fin;
2615
2616
0
      j->dstate++;
2617
  
2618
      /* fallthru */
2619
      
2620
0
    case LWSJDS_INIT_FRAME:
2621
      
2622
0
      r = init_frame(j);
2623
0
      if (r)
2624
0
        goto fin;
2625
2626
0
      j->dstate++;
2627
  
2628
      /* fallthru */
2629
      
2630
0
    case LWSJDS_INIT_SCAN:
2631
      
2632
0
      r = init_scan(j);
2633
0
      if (r)
2634
0
        goto fin;
2635
2636
0
      if (j->hold_at_metadata)
2637
0
        return LWS_SRET_AWAIT_RETRY;
2638
2639
      /*
2640
       * 8, or 16 lines of 24-bpp according to MCU height
2641
       */
2642
2643
0
      mcu_buf_len = (size_t)(j->image_width * j->frame_comps *
2644
0
                 j->mcu_max_size_y);
2645
2646
0
      j->lines = lws_zalloc(mcu_buf_len, __func__);
2647
0
      if (!j->lines) {
2648
0
        lwsl_jpeg("%s: OOM\n", __func__);
2649
0
        return LWS_SRET_FATAL + 32;
2650
0
      }
2651
2652
0
      j->dstate++;
2653
  
2654
      /* fallthru */
2655
2656
0
    case LWSJDS_DECODE_MCU:
2657
2658
      /*
2659
       * Once we started dumping the line buffer, continue
2660
       * until we cleared the prepared MCU height
2661
       */
2662
0
      if (j->ringy & (j->mcu_max_size_y - 1))
2663
0
        goto intra;
2664
2665
0
      if (j->seen_eoi) {
2666
0
        r = LWS_SRET_OK;
2667
0
        goto intra;
2668
0
      }
2669
2670
0
      r = lws_jpeg_mcu_next(j);
2671
0
      if (j->seen_eoi) {
2672
0
        r = LWS_SRET_OK;
2673
0
        goto intra;
2674
0
      }
2675
0
      if (r)
2676
0
        goto fin;
2677
2678
0
      j->mcu_count_left_x--;
2679
0
      if (!j->mcu_count_left_x) {
2680
0
        j->mcu_count_left_y--;
2681
2682
0
        if (j->mcu_count_left_y > 0)
2683
0
          j->mcu_count_left_x = j->mcu_max_row;
2684
2685
0
        if (!j->mcu_count_left_x && !j->mcu_count_left_y) {
2686
0
          lwsl_notice("%s: seems finished2\n", __func__);
2687
0
          r = LWS_SRET_NO_FURTHER_IN;
2688
0
          goto intra;
2689
0
        }
2690
2691
0
        goto intra;
2692
0
      }
2693
0
      break;
2694
0
    }
2695
0
  } while (1);
2696
2697
0
intra:
2698
0
  *ppix = j->lines + (((j->ringy++) & (j->mcu_max_size_y - 1)) *
2699
0
        j->frame_comps * j->image_width);
2700
2701
0
  r |= LWS_SRET_WANT_OUTPUT;
2702
2703
0
fin:
2704
0
  *buf = j->inbuf;
2705
0
  *size = j->insize;
2706
2707
0
  return r;
2708
0
}
2709
2710
unsigned int
2711
lws_jpeg_get_width(const lws_jpeg_t *j)
2712
0
{
2713
0
  return j->image_width;
2714
0
}
2715
2716
unsigned int
2717
lws_jpeg_get_height(const lws_jpeg_t *j)
2718
0
{
2719
0
  return j->image_height;
2720
0
}
2721
2722
unsigned int
2723
lws_jpeg_get_bpp(const lws_jpeg_t *j)
2724
0
{
2725
0
  return j->scan_type == PJPG_GRAYSCALE ? 8 : 24;
2726
0
}
2727
2728
unsigned int
2729
lws_jpeg_get_bitdepth(const lws_jpeg_t *j)
2730
0
{
2731
0
  return 8;
2732
0
}
2733
2734
unsigned int
2735
lws_jpeg_get_components(const lws_jpeg_t *j)
2736
0
{
2737
0
  return j->scan_type == PJPG_GRAYSCALE ? 1 : 3;
2738
0
}
2739
2740
unsigned int
2741
lws_jpeg_get_pixelsize(const lws_jpeg_t *j)
2742
0
{
2743
0
  return j->scan_type == PJPG_GRAYSCALE ? 8 : 24;
2744
0
}