Coverage Report

Created: 2026-08-13 06:38

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