39#define PUTNIBBLE(val)\
42 *q++ = bitbuf | ((val) & 0x0f);\
48 const uint8_t *bitmap,
int linesize,
53 unsigned int bitbuf = 0;
59 for (y = 0; y <
h; ++y) {
61 for(x = 0; x <
w; x +=
len) {
70 }
else if (
len < 0x10) {
73 }
else if (
len < 0x40) {
77 }
else if (x+
len ==
w) {
103 int alpha_a = 8, alpha_b = 8;
105 for (
i = 24;
i >= 0;
i -= 8) {
106 d = alpha_a * (int)((
a >>
i) & 0xFF) -
107 alpha_b * (int)((
b >>
i) & 0xFF);
123 unsigned count[256] = { 0 };
124 uint32_t *palette = (uint32_t *)
r->data[1];
126 int x, y,
i, j, match, d, best_d,
av_uninit(best_j);
127 uint8_t *p =
r->data[0];
129 for (y = 0; y <
r->h; y++) {
130 for (x = 0; x <
r->w; x++)
132 p +=
r->linesize[0] -
r->w;
134 for (
i = 0;
i < 256;
i++) {
139 match =
color < 0x33000000 ? 0 :
color < 0xCC000000 ? 1 : 17;
142 for (j = 0; j < 16; j++) {
152 hits[match] += count[
i];
157 int out_alpha[4],
unsigned hits[33])
160 int i, j, bright,
mult;
162 int selected[4] = { 0 };
163 uint32_t pseudopal[33] = { 0 };
164 uint32_t refcolor[3] = { 0x00000000, 0xFFFFFFFF, 0xFF000000 };
170 for (
i = 0;
i < 16;
i++) {
171 if (!(hits[1 +
i] + hits[17 +
i]))
175 for (j = 0; j < 3; j++, color >>= 8)
176 bright += (
color & 0xFF) < 0x40 || (
color & 0xFF) >= 0xC0;
178 hits[ 1 +
i] *=
mult;
179 hits[17 +
i] *=
mult;
183 for (
i = 0;
i < 4;
i++) {
184 for (j = 0; j < 33; j++)
185 if (hits[j] > hits[selected[
i]])
187 hits[selected[
i]] = 0;
192 for (
i = 0;
i < 16;
i++) {
196 for (
i = 0;
i < 3;
i++) {
198 for (j =
i + 1; j < 4; j++) {
201 FFSWAP(
int, selected[
i], selected[j]);
208 for (
i = 0;
i < 4;
i++) {
209 out_palette[
i] = selected[
i] ? (selected[
i] - 1) & 0xF : 0;
210 out_alpha [
i] = !selected[
i] ? 0 : selected[
i] < 17 ? 0x80 : 0xFF;
215 const uint32_t palette[],
216 const int out_palette[],
unsigned int const out_alpha[])
220 uint32_t pseudopal[4];
222 for (
i = 0;
i < 4;
i++)
223 pseudopal[
i] = (out_alpha[
i] << 24) |
225 for (
i = 0;
i < 256;
i++) {
227 for (j = 0; j < 4; j++) {
245 for (y = 0; y <
src->h; y++) {
246 for (x = 0; x <
src->w; x++)
247 *(q++) = cmap[*(p++)];
248 p +=
src->linesize[0] -
src->w;
249 q +=
dst->linesize[0] -
src->w;
254 uint8_t *outbuf,
int outbuf_size,
259 int offset1, offset2;
260 int i, rects =
h->num_rects, ret;
261 unsigned global_palette_hits[33] = { 0 };
266 uint8_t *vrect_data =
NULL;
270 if (rects == 0 || !
h->rects)
272 for (
i = 0;
i < rects;
i++)
278 for (
i = 0;
i < rects;
i++)
284 vrect = *
h->rects[0];
291 int xmin =
h->rects[0]->x, xmax = xmin +
h->rects[0]->w;
292 int ymin =
h->rects[0]->y, ymax = ymin +
h->rects[0]->h;
293 for (
i = 1;
i < rects;
i++) {
294 xmin =
FFMIN(xmin,
h->rects[
i]->x);
295 ymin =
FFMIN(ymin,
h->rects[
i]->y);
296 xmax =
FFMAX(xmax,
h->rects[
i]->x +
h->rects[
i]->w);
297 ymax =
FFMAX(ymax,
h->rects[
i]->y +
h->rects[
i]->h);
301 vrect.
w = xmax - xmin;
302 vrect.
h = ymax - ymin;
307 global_palette_hits[0] = vrect.
w * vrect.
h;
308 for (
i = 0;
i < rects;
i++)
309 global_palette_hits[0] -=
h->rects[
i]->w *
h->rects[
i]->h;
312 for (
i = 0;
i < rects;
i++)
314 select_palette(avctx, out_palette, out_alpha, global_palette_hits);
319 vrect.
data [0] = vrect_data;
321 for (
i = 0;
i < rects;
i++) {
323 out_palette, out_alpha);
326 for (
i = 0;
i < 4;
i++)
330 out_palette, out_alpha);
334 for (
i = 0;
i < 4;
i++)
337 out_palette[
i], out_alpha[
i] >> 4);
342 offset1 = q - outbuf;
344 if ((q - outbuf) + vrect.
h * ((vrect.
w + 1) / 2) + 17 + 21 > outbuf_size) {
350 vrect.
w, (vrect.
h + 1) >> 1, cmap);
351 offset2 = q - outbuf;
353 vrect.
w, vrect.
h >> 1, cmap);
364 bytestream_put_be16(&qq, q - outbuf);
367 bytestream_put_be16(&q, (
h->start_display_time*90) >> 10);
368 bytestream_put_be16(&q, (q - outbuf) + 8 + 12 + 2);
370 *q++ = (out_palette[3] << 4) | out_palette[2];
371 *q++ = (out_palette[1] << 4) | out_palette[0];
373 *q++ = (out_alpha[3] & 0xF0) | (out_alpha[2] >> 4);
374 *q++ = (out_alpha[1] & 0xF0) | (out_alpha[0] >> 4);
377 x2 = vrect.
x + vrect.
w - 1;
378 y2 = vrect.
y + vrect.
h - 1;
380 if ((avctx->
width > 0 && x2 > avctx->
width) ||
390 *q++ = (vrect.
x << 4) | ((x2 >> 8) & 0xf);
394 *q++ = (vrect.
y << 4) | ((y2 >> 8) & 0xf);
399 bytestream_put_be16(&q, offset1);
400 bytestream_put_be16(&q, offset2);
402 *q++ = forced ? 0x00 : 0x01;
406 bytestream_put_be16(&q, (
h->end_display_time*90) >> 10);
407 bytestream_put_be16(&q, (q - outbuf) - 2 );
412 bytestream_put_be16(&qq, q - outbuf);
448 static const uint32_t default_palette[16] = {
449 0x000000, 0x0000FF, 0x00FF00, 0xFF0000,
450 0xFFFF00, 0xFF00FF, 0x00FFFF, 0xFFFFFF,
451 0x808000, 0x8080FF, 0x800080, 0x80FF80,
452 0x008080, 0xFF8080, 0x555555, 0xAAAAAA,
468 for (
i = 0;
i < 16;
i++)
479#define OFFSET(x) offsetof(DVDSubtitleContext, x)
480#define SE AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_ENCODING_PARAM
483 {
"even_rows_fix",
"Make number of rows even (workaround for some players)",
OFFSET(even_rows_fix),
AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1,
SE},
488 .class_name =
"VOBSUB subtitle encoder",
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
const FFCodec ff_dvdsub_encoder
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Libavcodec external API header.
void av_bprintf(AVBPrint *buf, const char *fmt,...)
#define i(width, name, range_min, range_max)
#define FF_CODEC_ENCODE_SUB_CB(func)
#define CODEC_LONG_NAME(str)
void ff_dvdsub_parse_palette(uint32_t *palette, const char *p)
static av_cold int dvdsub_init(AVCodecContext *avctx)
static av_cold int dvdsub_init(AVCodecContext *avctx)
static int dvdsub_encode(AVCodecContext *avctx, uint8_t *outbuf, int outbuf_size, const AVSubtitle *h)
static int bprint_to_extradata(AVCodecContext *avctx, struct AVBPrint *buf)
static const AVClass dvdsubenc_class
static int color_distance(uint32_t a, uint32_t b)
static void select_palette(AVCodecContext *avctx, int out_palette[4], int out_alpha[4], unsigned hits[33])
static void count_colors(AVCodecContext *avctx, unsigned hits[33], const AVSubtitleRect *r)
Count colors used in a rectangle, quantizing alpha and grouping by nearest global palette entry.
static void dvd_encode_rle(uint8_t **pq, const uint8_t *bitmap, int linesize, int w, int h, const int cmap[256])
static void build_color_map(AVCodecContext *avctx, int cmap[], const uint32_t palette[], const int out_palette[], unsigned int const out_alpha[])
static void copy_rectangle(AVSubtitleRect *dst, AVSubtitleRect *src, int cmap[])
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
@ AV_OPT_TYPE_STRING
Underlying C type is a uint8_t* that is either NULL or points to a C string allocated with the av_mal...
#define AV_SUBTITLE_FLAG_FORCED
@ SUBTITLE_BITMAP
A bitmap, pict will be set.
@ AV_CODEC_ID_DVD_SUBTITLE
static int av_bprint_is_complete(const AVBPrint *buf)
Test if the print buffer is complete (not truncated).
#define AV_BPRINT_SIZE_AUTOMATIC
Use the exact size available in the AVBPrint structure itself.
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Init a print buffer.
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
#define AVERROR_BUFFER_TOO_SMALL
Buffer too small.
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
const char * av_default_item_name(void *ptr)
Return the context name.
void * av_calloc(size_t nmemb, size_t size)
Allocate a memory block for an array with av_mallocz().
int av_image_check_size(unsigned int w, unsigned int h, int log_offset, void *log_ctx)
Check if the given dimension of an image is valid, meaning that all bytes of the image can be address...
#define LIBAVUTIL_VERSION_INT
static int16_t mult(Float11 *f1, Float11 *f2)
#define FFSWAP(type, a, b)
Memory handling functions.
Buffer to print data progressively.
unsigned len
length so far
Describe the class of an AVClass context structure.
main external API structure.
int width
picture width / height.
uint8_t * extradata
Out-of-band global headers that may be used by some codecs.
int x
top left corner of pict, undefined when pict is not set
int w
width of pict, undefined when pict is not set
uint8_t * data[4]
data+linesize for the bitmap of this subtitle.
int y
top left corner of pict, undefined when pict is not set
int h
height of pict, undefined when pict is not set
uint32_t global_palette[16]