24 #define HEADER(name) do { \
25 ff_cbs_trace_header(ctx, name); \
28 #define CHECK(call) do { \
34 #define SUBSCRIPTS(subs, ...) (subs > 0 ? ((int[subs + 1]){ subs, __VA_ARGS__ }) : NULL)
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)
43 #define READWRITE read
44 #define RWContext GetBitContext
45 #define FUNC(name) cbs_jpeg_read_ ## name
47 #define xu(width, name, range_min, range_max, subs, ...) do { \
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; \
64 #define READWRITE write
65 #define RWContext PutBitContext
66 #define FUNC(name) cbs_jpeg_write_ ## name
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)); \
113 int unit, start, end, marker, next_start, next_marker;
114 int err,
i, j, length;
124 "beginning of image.\n",
i);
129 "no SOI marker found.\n");
132 marker = frag->
data[
i];
135 "marker is %02x, should be SOI.\n", marker);
141 "no image content found.\n");
144 marker = frag->
data[
i];
147 for (unit = 0;; unit++) {
154 if (frag->
data[
i] != 0xff)
158 frag->
data[
i] == 0xff;
i++);
160 if (frag->
data[
i] == 0x00)
162 next_marker = frag->
data[
i];
171 "truncated at %02x marker.\n", marker);
177 "truncated at %02x marker segment.\n", marker);
180 end = start + length;
183 if (frag->
data[
i] != 0xff) {
187 frag->
data[
i] == 0xff;
i++);
191 next_marker = frag->
data[
i];
200 if (length > end - start)
209 memcpy(
data, frag->
data + start, length);
210 for (
i = start + length, j = length;
i < end;
i++, j++) {
211 if (frag->
data[
i] == 0xff) {
212 while (frag->
data[
i] == 0xff)
225 data_size = end - start;
230 data, data_size, data_ref);
234 if (next_marker == -1)
236 marker = next_marker;
261 err = cbs_jpeg_read_frame_header(
ctx, &gbc, unit->
content);
273 err = cbs_jpeg_read_application_data(
ctx, &gbc, unit->
content);
288 err = cbs_jpeg_read_scan_header(
ctx, &gbc, &scan->
header);
303 switch (unit->
type) {
304 #define SEGMENT(marker, type, func, free) \
305 case JPEG_MARKER_ ## marker: \
307 err = ff_cbs_alloc_unit_content(unit, \
308 sizeof(type), free); \
311 err = cbs_jpeg_read_ ## func(ctx, &gbc, unit->content); \
335 err = cbs_jpeg_write_scan_header(
ctx, pbc, &scan->
header);
362 err = cbs_jpeg_write_frame_header(
ctx, pbc, unit->
content);
365 err = cbs_jpeg_write_application_data(
ctx, pbc, unit->
content);
367 switch (unit->
type) {
368 #define SEGMENT(marker, func) \
369 case JPEG_MARKER_ ## marker: \
370 err = cbs_jpeg_write_ ## func(ctx, pbc, unit->content); \
407 if (unit->
data[
sp] == 0xff)
439 if (unit->
data[
sp] == 0xff) {
#define av_assert0(cond)
assert() equivalent, that is always enabled.
int ff_cbs_alloc_unit_content(CodedBitstreamUnit *unit, size_t size, void(*free)(void *opaque, uint8_t *data))
int ff_cbs_insert_unit_data(CodedBitstreamFragment *frag, int position, CodedBitstreamUnitType type, uint8_t *data, size_t data_size, AVBufferRef *data_buf)
Insert a new unit into a fragment with the given data bitstream.
const CodedBitstreamType ff_cbs_type_jpeg
static int cbs_jpeg_read_unit(CodedBitstreamContext *ctx, CodedBitstreamUnit *unit)
static int cbs_jpeg_write_segment(CodedBitstreamContext *ctx, CodedBitstreamUnit *unit, PutBitContext *pbc)
static void cbs_jpeg_free_scan(void *opaque, uint8_t *content)
static void cbs_jpeg_free_application_data(void *opaque, uint8_t *content)
static int cbs_jpeg_assemble_fragment(CodedBitstreamContext *ctx, CodedBitstreamFragment *frag)
static int cbs_jpeg_write_scan(CodedBitstreamContext *ctx, CodedBitstreamUnit *unit, PutBitContext *pbc)
#define SEGMENT(marker, type, func, free)
static int cbs_jpeg_write_unit(CodedBitstreamContext *ctx, CodedBitstreamUnit *unit, PutBitContext *pbc)
static void cbs_jpeg_free_comment(void *opaque, uint8_t *content)
static int cbs_jpeg_split_fragment(CodedBitstreamContext *ctx, CodedBitstreamFragment *frag, int header)
static int FUNC() comment(CodedBitstreamContext *ctx, RWContext *rw, JPEGRawComment *current)
static int FUNC() dqt(CodedBitstreamContext *ctx, RWContext *rw, JPEGRawQuantisationTableSpecification *current)
static int FUNC() dht(CodedBitstreamContext *ctx, RWContext *rw, JPEGRawHuffmanTableSpecification *current)
static int get_bits_count(const GetBitContext *s)
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding.
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
AVBufferRef * av_buffer_alloc(buffer_size_t size)
Allocate an AVBuffer of the given size using av_malloc().
AVBufferRef * av_buffer_ref(AVBufferRef *buf)
Create a new reference to an AVBuffer.
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
#define AV_LOG_WARNING
Something somehow does not look correct.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
static uint8_t * put_bits_ptr(PutBitContext *s)
Return the pointer to the byte where the bitstream writer will put the next bit.
static int put_bits_count(PutBitContext *s)
static int put_bits_left(PutBitContext *s)
static void flush_put_bits(PutBitContext *s)
Pad the end of the output stream with zeros.
static void skip_put_bytes(PutBitContext *s, int n)
Skip the given number of bytes.
static const uint8_t header[24]
A reference to a data buffer.
uint8_t * data
The data buffer.
Context structure for coded bitstream operations.
Coded bitstream fragment structure, combining one or more units.
CodedBitstreamUnit * units
Pointer to an array of units of length nb_units_allocated.
int nb_units
Number of units in this fragment.
size_t data_size
The number of bytes in the bitstream.
uint8_t * data
Pointer to the bitstream form of this fragment.
AVBufferRef * data_ref
A reference to the buffer containing data.
Coded bitstream unit structure.
void * content
Pointer to the decomposed form of this unit.
uint8_t * data
Pointer to the directly-parsable bitstream form of this unit.
CodedBitstreamUnitType type
Codec-specific type of this unit.
size_t data_size
The number of bytes in the bitstream (including any padding bits in the final byte).
AVBufferRef * data_ref
A reference to the buffer containing data.