31 uint32_t global_palette[16];
36 #define PUTNIBBLE(val)\
39 *q++ = bitbuf | ((val) & 0x0f);\
45 const uint8_t *bitmap,
int linesize,
50 unsigned int bitbuf = 0;
56 for (y = 0; y <
h; ++y) {
58 for(x = 0; x <
w; x +=
len) {
67 }
else if (
len < 0x10) {
70 }
else if (
len < 0x40) {
74 }
else if (x+
len ==
w) {
100 int alpha_a = 8, alpha_b = 8;
102 for (
i = 24;
i >= 0;
i -= 8) {
103 d = alpha_a * (
int)((
a >>
i) & 0xFF) -
104 alpha_b * (
int)((
b >>
i) & 0xFF);
120 unsigned count[256] = { 0 };
121 uint32_t *palette = (uint32_t *)
r->data[1];
123 int x, y,
i, j, match, d, best_d,
av_uninit(best_j);
126 for (y = 0; y <
r->h; y++) {
127 for (x = 0; x <
r->w; x++)
129 p +=
r->linesize[0] -
r->w;
131 for (
i = 0;
i < 256;
i++) {
136 match =
color < 0x33000000 ? 0 :
color < 0xCC000000 ? 1 : 17;
139 for (j = 0; j < 16; j++) {
154 int out_alpha[4],
unsigned hits[33])
157 int i, j, bright,
mult;
159 int selected[4] = { 0 };
160 uint32_t pseudopal[33] = { 0 };
161 uint32_t refcolor[3] = { 0x00000000, 0xFFFFFFFF, 0xFF000000 };
167 for (
i = 0;
i < 16;
i++) {
168 if (!(hits[1 +
i] + hits[17 +
i]))
172 for (j = 0; j < 3; j++, color >>= 8)
173 bright += (
color & 0xFF) < 0x40 || (
color & 0xFF) >= 0xC0;
175 hits[ 1 +
i] *=
mult;
176 hits[17 +
i] *=
mult;
180 for (
i = 0;
i < 4;
i++) {
181 for (j = 0; j < 33; j++)
182 if (hits[j] > hits[selected[
i]])
184 hits[selected[
i]] = 0;
189 for (
i = 0;
i < 16;
i++) {
193 for (
i = 0;
i < 3;
i++) {
195 for (j =
i + 1; j < 4; j++) {
198 FFSWAP(
int, selected[
i], selected[j]);
205 for (
i = 0;
i < 4;
i++) {
206 out_palette[
i] = selected[
i] ? (selected[
i] - 1) & 0xF : 0;
207 out_alpha [
i] = !selected[
i] ? 0 : selected[
i] < 17 ? 0x80 : 0xFF;
212 const uint32_t palette[],
213 const int out_palette[],
unsigned int const out_alpha[])
217 uint32_t pseudopal[4];
219 for (
i = 0;
i < 4;
i++)
220 pseudopal[
i] = (out_alpha[
i] << 24) |
222 for (
i = 0;
i < 256;
i++) {
224 for (j = 0; j < 4; j++) {
240 q = dst->
data[0] + (
src->x - dst->
x) +
242 for (y = 0; y <
src->h; y++) {
243 for (x = 0; x <
src->w; x++)
244 *(q++) = cmap[*(p++)];
245 p +=
src->linesize[0] -
src->w;
251 uint8_t *outbuf,
int outbuf_size,
256 int offset1, offset2;
257 int i, rects =
h->num_rects,
ret;
258 unsigned global_palette_hits[33] = { 0 };
267 if (rects == 0 || !
h->rects)
269 for (
i = 0;
i < rects;
i++)
275 for (
i = 0;
i < rects;
i++)
283 for (
i = 0;
i < rects;
i++)
284 if (!
h->rects[
i]->data[0]) {
287 for (j = 0; j < 4; j++) {
289 rect->linesize[j] =
rect->pict.linesize[j];
295 vrect = *
h->rects[0];
302 int xmin =
h->rects[0]->x, xmax = xmin +
h->rects[0]->w;
303 int ymin =
h->rects[0]->y, ymax = ymin +
h->rects[0]->h;
304 for (
i = 1;
i < rects;
i++) {
305 xmin =
FFMIN(xmin,
h->rects[
i]->x);
306 ymin =
FFMIN(ymin,
h->rects[
i]->y);
307 xmax =
FFMAX(xmax,
h->rects[
i]->x +
h->rects[
i]->w);
308 ymax =
FFMAX(ymax,
h->rects[
i]->y +
h->rects[
i]->h);
312 vrect.w = xmax - xmin;
313 vrect.h = ymax - ymin;
318 global_palette_hits[0] = vrect.w * vrect.h;
319 for (
i = 0;
i < rects;
i++)
320 global_palette_hits[0] -=
h->rects[
i]->w *
h->rects[
i]->h;
323 for (
i = 0;
i < rects;
i++)
325 select_palette(avctx, out_palette, out_alpha, global_palette_hits);
328 if (!(vrect_data =
av_calloc(vrect.w, vrect.h)))
330 vrect.data [0] = vrect_data;
331 vrect.linesize[0] = vrect.w;
332 for (
i = 0;
i < rects;
i++) {
334 out_palette, out_alpha);
337 for (
i = 0;
i < 4;
i++)
341 out_palette, out_alpha);
345 for (
i = 0;
i < 4;
i++)
348 out_palette[
i], out_alpha[
i] >> 4);
353 offset1 = q - outbuf;
355 if ((q - outbuf) + vrect.w * vrect.h / 2 + 17 + 21 > outbuf_size) {
361 vrect.w, (vrect.h + 1) >> 1, cmap);
362 offset2 = q - outbuf;
364 vrect.w, vrect.h >> 1, cmap);
375 bytestream_put_be16(&qq, q - outbuf);
378 bytestream_put_be16(&q, (
h->start_display_time*90) >> 10);
379 bytestream_put_be16(&q, (q - outbuf) + 8 + 12 + 2);
381 *q++ = (out_palette[3] << 4) | out_palette[2];
382 *q++ = (out_palette[1] << 4) | out_palette[0];
384 *q++ = (out_alpha[3] & 0xF0) | (out_alpha[2] >> 4);
385 *q++ = (out_alpha[1] & 0xF0) | (out_alpha[0] >> 4);
388 x2 = vrect.x + vrect.w - 1;
389 y2 = vrect.y + vrect.h - 1;
394 *q++ = (vrect.x << 4) | ((x2 >> 8) & 0xf);
398 *q++ = (vrect.y << 4) | ((y2 >> 8) & 0xf);
403 bytestream_put_be16(&q, offset1);
404 bytestream_put_be16(&q, offset2);
406 *q++ = forced ? 0x00 : 0x01;
410 bytestream_put_be16(&q, (
h->end_display_time*90) >> 10);
411 bytestream_put_be16(&q, (q - outbuf) - 2 );
416 bytestream_put_be16(&qq, q - outbuf);
429 static const uint32_t default_palette[16] = {
430 0x000000, 0x0000FF, 0x00FF00, 0xFF0000,
431 0xFFFF00, 0xFF00FF, 0x00FFFF, 0xFFFFFF,
432 0x808000, 0x8080FF, 0x800080, 0x80FF80,
433 0x008080, 0xFF8080, 0x555555, 0xAAAAAA,
445 for (
i = 0;
i < 16;
i++)
457 unsigned char *
buf,
int buf_size,
467 #define OFFSET(x) offsetof(DVDSubtitleContext, x)
468 #define SE AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_ENCODING_PARAM
470 {
"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},