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
23
24
25 #define HEADER(name) do { \
26 ff_cbs_trace_header(ctx, name); \
27 } while (0)
28
29 #define CHECK(call) do { \
30 err = (call); \
31 if (err < 0) \
32 return err; \
33 } while (0)
34
35 #define SUBSCRIPTS(subs, ...) (subs > 0 ? ((int[subs + 1]){ subs, __VA_ARGS__ }) : NULL)
36
37 #define u(width, name, range_min, range_max) \
38 xu(width, name, range_min, range_max, 0, )
39 #define us(width, name, sub, range_min, range_max) \
40 xu(width, name, range_min, range_max, 1, sub)
41
42
44 #define READWRITE read
45 #define RWContext GetBitContext
46 #define FUNC(name) cbs_jpeg_read_ ## name
47
48 #define xu(width, name, range_min, range_max, subs, ...) do { \
49 uint32_t value; \
50 CHECK(ff_cbs_read_unsigned(ctx, rw, width, #name, \
51 SUBSCRIPTS(subs, __VA_ARGS__), \
52 &value, range_min, range_max)); \
53 current->name = value; \
54 } while (0)
55
57
58 #undef READ
59 #undef READWRITE
60 #undef RWContext
61 #undef FUNC
62 #undef xu
63
65 #define READWRITE write
66 #define RWContext PutBitContext
67 #define FUNC(name) cbs_jpeg_write_ ## name
68
69 #define xu(width, name, range_min, range_max, subs, ...) do { \
70 uint32_t value = current->name; \
71 CHECK(ff_cbs_write_unsigned(ctx, rw, width, #name, \
72 SUBSCRIPTS(subs, __VA_ARGS__), \
73 value, range_min, range_max)); \
74 } while (0)
75
76
78
79 #undef WRITE
80 #undef READWRITE
81 #undef RWContext
82 #undef FUNC
83 #undef xu
84
85
89 {
92 size_t data_size;
93 int start, end, marker, next_start, next_marker;
94 int err,
i, j, length;
95
97 // Definitely too short to be meaningful.
99 }
100
104 "beginning of image.\n",
i);
105 }
109 "no SOI marker found.\n");
111 }
112 marker = frag->
data[
i];
115 "marker is %02x, should be SOI.\n", marker);
117 }
121 "no image content found.\n");
123 }
124 marker = frag->
data[
i];
126
127 do {
129 break;
131 next_marker = -1;
132 end = start;
134 if (frag->
data[
i] != 0xff)
135 continue;
138 frag->
data[
i] == 0xff;
i++);
140 if (frag->
data[
i] == 0x00)
141 continue;
142 next_marker = frag->
data[
i];
144 }
145 break;
146 }
147 } else {
151 "truncated at %02x marker.\n", marker);
153 }
157 "truncated at %02x marker segment.\n", marker);
159 }
160 end = start + length;
161
163 if (frag->
data[
i] != 0xff) {
164 next_marker = -1;
165 } else {
167 frag->
data[
i] == 0xff;
i++);
169 next_marker = -1;
170 } else {
171 next_marker = frag->
data[
i];
173 }
174 }
175 }
176
179
180 if (length > end - start)
182
188
189 memcpy(
data, frag->
data + start, length);
190 for (
i = start + length, j = length;
i < end;
i++, j++) {
191 if (frag->
data[
i] == 0xff) {
192 while (frag->
data[
i] == 0xff)
195 } else {
197 }
198 }
199 data_size = j;
200
202
203 } else {
205 data_size = end - start;
207 }
208
210 data, data_size, data_ref);
211 if (err < 0)
212 return err;
213
214 marker = next_marker;
215 start = next_start;
216 } while (next_marker != -1);
217
218 return 0;
219 }
220
223 {
225 int err;
226
228 if (err < 0)
229 return err;
230
232 if (err < 0)
233 return err;
234
237 err = cbs_jpeg_read_frame_header(
ctx, &gbc, unit->
content);
238 if (err < 0)
239 return err;
240
243 err = cbs_jpeg_read_application_data(
ctx, &gbc, unit->
content);
244 if (err < 0)
245 return err;
246
250
251 err = cbs_jpeg_read_scan_header(
ctx, &gbc, &scan->
header);
252 if (err < 0)
253 return err;
254
263 }
264
265 } else {
266 switch (unit->
type) {
267 #define SEGMENT(marker, func) \
268 case JPEG_MARKER_ ## marker: \
269 { \
270 err = cbs_jpeg_read_ ## func(ctx, &gbc, unit->content); \
271 if (err < 0) \
272 return err; \
273 } \
274 break
278 #undef SEGMENT
279 default:
281 }
282 }
283
284 return 0;
285 }
286
290 {
292 int err;
293
294 err = cbs_jpeg_write_scan_header(
ctx, pbc, &scan->
header);
295 if (err < 0)
296 return err;
297
301
303
305
308 }
309
310 return 0;
311 }
312
316 {
317 int err;
318
321 err = cbs_jpeg_write_frame_header(
ctx, pbc, unit->
content);
324 err = cbs_jpeg_write_application_data(
ctx, pbc, unit->
content);
325 } else {
326 switch (unit->
type) {
327 #define SEGMENT(marker, func) \
328 case JPEG_MARKER_ ## marker: \
329 err = cbs_jpeg_write_ ## func(ctx, pbc, unit->content); \
330 break;
334 default:
336 }
337 }
338
339 return err;
340 }
341
345 {
348 else
350 }
351
354 {
359
360 size = 4;
// SOI + EOI.
365 for (sp = 0; sp < unit->
data_size; sp++) {
366 if (unit->
data[sp] == 0xff)
368 }
369 }
370 }
371
376
377 dp = 0;
378
381
384
387
391 } else {
395 dp += sp;
396
398 if (unit->
data[sp] == 0xff) {
401 } else {
403 }
404 }
405 }
406 }
407
410
412
416
417 return 0;
418 }
419
422
425
427
430
432
434 };
435
438
440
445 };