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.
w * vrect.
h / 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,...)
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
#define AV_BPRINT_SIZE_AUTOMATIC
#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).
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.
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)
void * av_calloc(size_t nmemb, size_t size)
Memory handling functions.
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]