Skip to content

Commit e7fdf5f

Browse files
committed
Adding code and UF2 for the qualia ornament
Code and files for the Qualia S3 ornament
1 parent c5c5503 commit e7fdf5f

File tree

4 files changed

+454
-0
lines changed

4 files changed

+454
-0
lines changed

Qualia/Qualia_S3_OrnamentVideoPlayer/.none.test.only

Whitespace-only changes.
Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
// SPDX-FileCopyrightText: 2023 Limor Fried for Adafruit Industries
2+
//
3+
// SPDX-License-Identifier: MIT
4+
5+
/*******************************************************************************
6+
* ESP32_JPEG Wrapper Class
7+
*
8+
* Dependent libraries:
9+
* ESP32_JPEG: https://github.com/esp-arduino-libs/ESP32_JPEG.git
10+
******************************************************************************/
11+
#pragma once
12+
13+
#if defined(ESP32)
14+
15+
#define READ_BUFFER_SIZE 1024
16+
#define MAXOUTPUTSIZE (MAX_BUFFERED_PIXELS / 16 / 16)
17+
18+
#include <FS.h>
19+
20+
#include <ESP32_JPEG_Library.h>
21+
22+
class MjpegClass
23+
{
24+
public:
25+
bool setup(
26+
Stream *input, uint8_t *mjpeg_buf,
27+
uint16_t *output_buf, size_t output_buf_size, bool useBigEndian)
28+
{
29+
_input = input;
30+
_mjpeg_buf = mjpeg_buf;
31+
_output_buf = (uint8_t *)output_buf;
32+
_output_buf_size = output_buf_size;
33+
_useBigEndian = useBigEndian;
34+
_inputindex = 0;
35+
36+
if (!_read_buf)
37+
{
38+
_read_buf = (uint8_t *)malloc(READ_BUFFER_SIZE);
39+
}
40+
41+
if (!_read_buf)
42+
{
43+
return false;
44+
}
45+
46+
return true;
47+
}
48+
49+
bool readMjpegBuf()
50+
{
51+
if (_inputindex == 0)
52+
{
53+
_buf_read = _input->readBytes(_read_buf, READ_BUFFER_SIZE);
54+
_inputindex += _buf_read;
55+
}
56+
_mjpeg_buf_offset = 0;
57+
int i = 0;
58+
bool found_FFD8 = false;
59+
while ((_buf_read > 0) && (!found_FFD8))
60+
{
61+
i = 0;
62+
while ((i < _buf_read) && (!found_FFD8))
63+
{
64+
if ((_read_buf[i] == 0xFF) && (_read_buf[i + 1] == 0xD8)) // JPEG header
65+
{
66+
// Serial.printf("Found FFD8 at: %d.\n", i);
67+
found_FFD8 = true;
68+
}
69+
++i;
70+
}
71+
if (found_FFD8)
72+
{
73+
--i;
74+
}
75+
else
76+
{
77+
_buf_read = _input->readBytes(_read_buf, READ_BUFFER_SIZE);
78+
}
79+
}
80+
uint8_t *_p = _read_buf + i;
81+
_buf_read -= i;
82+
bool found_FFD9 = false;
83+
if (_buf_read > 0)
84+
{
85+
i = 3;
86+
while ((_buf_read > 0) && (!found_FFD9))
87+
{
88+
if ((_mjpeg_buf_offset > 0) && (_mjpeg_buf[_mjpeg_buf_offset - 1] == 0xFF) && (_p[0] == 0xD9)) // JPEG trailer
89+
{
90+
// Serial.printf("Found FFD9 at: %d.\n", i);
91+
found_FFD9 = true;
92+
}
93+
else
94+
{
95+
while ((i < _buf_read) && (!found_FFD9))
96+
{
97+
if ((_p[i] == 0xFF) && (_p[i + 1] == 0xD9)) // JPEG trailer
98+
{
99+
found_FFD9 = true;
100+
++i;
101+
}
102+
++i;
103+
}
104+
}
105+
106+
// Serial.printf("i: %d\n", i);
107+
memcpy(_mjpeg_buf + _mjpeg_buf_offset, _p, i);
108+
_mjpeg_buf_offset += i;
109+
size_t o = _buf_read - i;
110+
if (o > 0)
111+
{
112+
// Serial.printf("o: %d\n", o);
113+
memcpy(_read_buf, _p + i, o);
114+
_buf_read = _input->readBytes(_read_buf + o, READ_BUFFER_SIZE - o);
115+
_p = _read_buf;
116+
_inputindex += _buf_read;
117+
_buf_read += o;
118+
// Serial.printf("_buf_read: %d\n", _buf_read);
119+
}
120+
else
121+
{
122+
_buf_read = _input->readBytes(_read_buf, READ_BUFFER_SIZE);
123+
_p = _read_buf;
124+
_inputindex += _buf_read;
125+
}
126+
i = 0;
127+
}
128+
if (found_FFD9)
129+
{
130+
return true;
131+
}
132+
}
133+
134+
return false;
135+
}
136+
137+
bool decodeJpg()
138+
{
139+
_remain = _mjpeg_buf_offset;
140+
141+
// Generate default configuration
142+
jpeg_dec_config_t config = {
143+
.output_type = JPEG_RAW_TYPE_RGB565_BE,
144+
.rotate = JPEG_ROTATE_0D,
145+
};
146+
// Create jpeg_dec
147+
_jpeg_dec = jpeg_dec_open(&config);
148+
149+
// Create io_callback handle
150+
_jpeg_io = (jpeg_dec_io_t *)calloc(1, sizeof(jpeg_dec_io_t));
151+
152+
// Create out_info handle
153+
_out_info = (jpeg_dec_header_info_t *)calloc(1, sizeof(jpeg_dec_header_info_t));
154+
155+
// Set input buffer and buffer len to io_callback
156+
_jpeg_io->inbuf = _mjpeg_buf;
157+
_jpeg_io->inbuf_len = _remain;
158+
159+
jpeg_dec_parse_header(_jpeg_dec, _jpeg_io, _out_info);
160+
161+
_w = _out_info->width;
162+
_h = _out_info->height;
163+
164+
if ((_w * _h * 2) > _output_buf_size)
165+
{
166+
return false;
167+
}
168+
_jpeg_io->outbuf = _output_buf;
169+
170+
jpeg_dec_process(_jpeg_dec, _jpeg_io);
171+
jpeg_dec_close(_jpeg_dec);
172+
173+
free(_jpeg_io);
174+
free(_out_info);
175+
176+
return true;
177+
}
178+
179+
int16_t getWidth()
180+
{
181+
return _w;
182+
}
183+
184+
int16_t getHeight()
185+
{
186+
return _h;
187+
}
188+
189+
private:
190+
Stream *_input;
191+
uint8_t *_mjpeg_buf;
192+
uint8_t *_output_buf;
193+
size_t _output_buf_size;
194+
bool _useBigEndian;
195+
196+
uint8_t *_read_buf;
197+
int32_t _mjpeg_buf_offset = 0;
198+
199+
jpeg_dec_handle_t *_jpeg_dec;
200+
jpeg_dec_io_t *_jpeg_io;
201+
jpeg_dec_header_info_t *_out_info;
202+
203+
int16_t _w = 0, _h = 0;
204+
205+
int32_t _inputindex = 0;
206+
int32_t _buf_read;
207+
int32_t _remain = 0;
208+
};
209+
210+
#endif // defined(ESP32)

0 commit comments

Comments
 (0)