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;
121 for (i = 0; i + 1 < frag->
data_size && frag->
data[
i] != 0xff; i++);
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++) {
153 for (i = start; i + 1 < frag->
data_size; i++) {
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)
216 data[j] = frag->
data[
i];
224 data = frag->
data + start;
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(ctx, 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); \ 402 for (i = 0; i < frag->
nb_units; i++) {
406 for (sp = 0; sp < unit->
data_size; sp++) {
407 if (unit->
data[sp] == 0xff)
423 for (i = 0; i < frag->
nb_units; i++) {
427 data[dp++] = unit->
type;
435 memcpy(data + dp, unit->
data, sp);
439 if (unit->
data[sp] == 0xff) {
443 data[dp++] = unit->
data[
sp];
int nb_units
Number of units in this fragment.
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it...
static int FUNC() dqt(CodedBitstreamContext *ctx, RWContext *rw, JPEGRawQuantisationTableSpecification *current)
static void cbs_jpeg_free_scan(void *opaque, uint8_t *content)
#define AV_LOG_WARNING
Something somehow does not look correct.
CodedBitstreamUnitType type
Codec-specific type of this unit.
int ff_cbs_alloc_unit_content(CodedBitstreamContext *ctx, CodedBitstreamUnit *unit, size_t size, void(*free)(void *opaque, uint8_t *data))
static int cbs_jpeg_read_unit(CodedBitstreamContext *ctx, CodedBitstreamUnit *unit)
#define av_assert0(cond)
assert() equivalent, that is always enabled.
static int cbs_jpeg_write_unit(CodedBitstreamContext *ctx, CodedBitstreamUnit *unit, PutBitContext *pbc)
static av_cold int end(AVCodecContext *avctx)
const CodedBitstreamType ff_cbs_type_jpeg
static int get_bits_count(const GetBitContext *s)
static int FUNC() dht(CodedBitstreamContext *ctx, RWContext *rw, JPEGRawHuffmanTableSpecification *current)
Coded bitstream unit structure.
void * content
Pointer to the decomposed form of this unit.
static const uint8_t header[24]
CodedBitstreamUnit * units
Pointer to an array of units of length nb_units_allocated.
#define SEGMENT(marker, type, func, free)
uint8_t * data
Pointer to the directly-parsable bitstream form of this unit.
int ff_cbs_insert_unit_data(CodedBitstreamContext *ctx, 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.
static int FUNC() comment(CodedBitstreamContext *ctx, RWContext *rw, JPEGRawComment *current)
size_t data_size
The number of bytes in the bitstream.
#define i(width, name, range_min, range_max)
#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_left(PutBitContext *s)
static int put_bits_count(PutBitContext *s)
void * log_ctx
Logging context to be passed to all av_log() calls associated with this context.
static void skip_put_bytes(PutBitContext *s, int n)
Skip the given number of bytes.
uint8_t * data
Pointer to the bitstream form of this fragment.
static int cbs_jpeg_write_segment(CodedBitstreamContext *ctx, CodedBitstreamUnit *unit, PutBitContext *pbc)
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
AVBufferRef * av_buffer_alloc(int size)
Allocate an AVBuffer of the given size using av_malloc().
Coded bitstream fragment structure, combining one or more units.
uint8_t * data
The data buffer.
Context structure for coded bitstream operations.
static int cbs_jpeg_assemble_fragment(CodedBitstreamContext *ctx, CodedBitstreamFragment *frag)
static void cbs_jpeg_free_application_data(void *opaque, uint8_t *content)
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
A reference to a data buffer.
static void flush_put_bits(PutBitContext *s)
Pad the end of the output stream with zeros.
AVBufferRef * data_ref
A reference to the buffer containing data.
AVBufferRef * av_buffer_ref(AVBufferRef *buf)
Create a new reference to an AVBuffer.
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding...
AVBufferRef * data_ref
A reference to the buffer containing data.
static int cbs_jpeg_split_fragment(CodedBitstreamContext *ctx, CodedBitstreamFragment *frag, int header)
static void cbs_jpeg_free_comment(void *opaque, uint8_t *content)
static int cbs_jpeg_write_scan(CodedBitstreamContext *ctx, CodedBitstreamUnit *unit, PutBitContext *pbc)
size_t data_size
The number of bytes in the bitstream (including any padding bits in the final byte).