1 /*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
22
23
24 #define HEADER(name) do { \
25 ff_cbs_trace_header(ctx, name); \
26 } while (0)
27
28 #define CHECK(call) do { \
29 err = (call); \
30 if (err < 0) \
31 return err; \
32 } while (0)
33
34 #define SUBSCRIPTS(subs, ...) (subs > 0 ? ((int[subs + 1]){ subs, __VA_ARGS__ }) : NULL)
35
36 #define u(width, name, range_min, range_max) \
37 xu(width, name, range_min, range_max, 0, )
38 #define us(width, name, sub, range_min, range_max) \
39 xu(width, name, range_min, range_max, 1, sub)
40
41
43 #define READWRITE read
44 #define RWContext GetBitContext
45 #define FUNC(name) cbs_jpeg_read_ ## name
46
47 #define xu(width, name, range_min, range_max, subs, ...) do { \
48 uint32_t value; \
49 CHECK(ff_cbs_read_unsigned(ctx, rw, width, #name, \
50 SUBSCRIPTS(subs, __VA_ARGS__), \
51 &value, range_min, range_max)); \
52 current->name = value; \
53 } while (0)
54
56
57 #undef READ
58 #undef READWRITE
59 #undef RWContext
60 #undef FUNC
61 #undef xu
62
64 #define READWRITE write
65 #define RWContext PutBitContext
66 #define FUNC(name) cbs_jpeg_write_ ## name
67
68 #define xu(width, name, range_min, range_max, subs, ...) do { \
69 uint32_t value = current->name; \
70 CHECK(ff_cbs_write_unsigned(ctx, rw, width, #name, \
71 SUBSCRIPTS(subs, __VA_ARGS__), \
72 value, range_min, range_max)); \
73 } while (0)
74
75
77
78 #undef WRITE
79 #undef READWRITE
80 #undef RWContext
81 #undef FUNC
82 #undef xu
83
84
88 {
91 size_t data_size;
92 int start, end, marker, next_start, next_marker;
93 int err,
i, j, length;
94
96 // Definitely too short to be meaningful.
98 }
99
103 "beginning of image.\n",
i);
104 }
108 "no SOI marker found.\n");
110 }
111 marker = frag->
data[
i];
114 "marker is %02x, should be SOI.\n", marker);
116 }
120 "no image content found.\n");
122 }
123 marker = frag->
data[
i];
125
126 do {
128 break;
130 next_marker = -1;
131 end = start;
133 if (frag->
data[
i] != 0xff)
134 continue;
137 frag->
data[
i] == 0xff;
i++);
139 if (frag->
data[
i] == 0x00)
140 continue;
141 next_marker = frag->
data[
i];
143 }
144 break;
145 }
146 } else {
150 "truncated at %02x marker.\n", marker);
152 }
156 "truncated at %02x marker segment.\n", marker);
158 }
159 end = start + length;
160
162 if (frag->
data[
i] != 0xff) {
163 next_marker = -1;
164 } else {
166 frag->
data[
i] == 0xff;
i++);
168 next_marker = -1;
169 } else {
170 next_marker = frag->
data[
i];
172 }
173 }
174 }
175
178
179 if (length > end - start)
181
187
188 memcpy(
data, frag->
data + start, length);
189 for (
i = start + length, j = length;
i < end;
i++, j++) {
190 if (frag->
data[
i] == 0xff) {
191 while (frag->
data[
i] == 0xff)
194 } else {
196 }
197 }
198 data_size = j;
199
201
202 } else {
204 data_size = end - start;
206 }
207
209 data, data_size, data_ref);
210 if (err < 0)
211 return err;
212
213 marker = next_marker;
214 start = next_start;
215 } while (next_marker != -1);
216
217 return 0;
218 }
219
222 {
224 int err;
225
227 if (err < 0)
228 return err;
229
231 if (err < 0)
232 return err;
233
236 err = cbs_jpeg_read_frame_header(
ctx, &gbc, unit->
content);
237 if (err < 0)
238 return err;
239
242 err = cbs_jpeg_read_application_data(
ctx, &gbc, unit->
content);
243 if (err < 0)
244 return err;
245
249
250 err = cbs_jpeg_read_scan_header(
ctx, &gbc, &scan->
header);
251 if (err < 0)
252 return err;
253
262 }
263
264 } else {
265 switch (unit->
type) {
266 #define SEGMENT(marker, func) \
267 case JPEG_MARKER_ ## marker: \
268 { \
269 err = cbs_jpeg_read_ ## func(ctx, &gbc, unit->content); \
270 if (err < 0) \
271 return err; \
272 } \
273 break
277 #undef SEGMENT
278 default:
280 }
281 }
282
283 return 0;
284 }
285
289 {
291 int err;
292
293 err = cbs_jpeg_write_scan_header(
ctx, pbc, &scan->
header);
294 if (err < 0)
295 return err;
296
300
302
304
307 }
308
309 return 0;
310 }
311
315 {
316 int err;
317
320 err = cbs_jpeg_write_frame_header(
ctx, pbc, unit->
content);
323 err = cbs_jpeg_write_application_data(
ctx, pbc, unit->
content);
324 } else {
325 switch (unit->
type) {
326 #define SEGMENT(marker, func) \
327 case JPEG_MARKER_ ## marker: \
328 err = cbs_jpeg_write_ ## func(ctx, pbc, unit->content); \
329 break;
333 default:
335 }
336 }
337
338 return err;
339 }
340
344 {
347 else
349 }
350
353 {
358
359 size = 4;
// SOI + EOI.
365 if (unit->
data[
sp] == 0xff)
367 }
368 }
369 }
370
375
376 dp = 0;
377
380
383
386
390 } else {
395
397 if (unit->
data[
sp] == 0xff) {
400 } else {
402 }
403 }
404 }
405 }
406
409
411
415
416 return 0;
417 }
418
421
424
426
429
431
433 };
434
437
439
444 };