24 #include "libavutil/avassert.h"
25 #include "libavutil/bprint.h"
26 #include "libavutil/imgutils.h"
29 uint32_t global_palette[16];
33 #define PUTNIBBLE(val)\
36 *q++ = bitbuf | ((val) & 0x0f);\
42 const uint8_t *bitmap,
int linesize,
47 unsigned int bitbuf = 0;
53 for (y = 0; y < h; ++
y) {
55 for(x = 0; x < w; x +=
len) {
57 for (len=1; x+len < w; ++
len)
58 if (bitmap[x+len] != color)
64 }
else if (len < 0x10) {
67 }
else if (len < 0x40) {
71 }
else if (x+len == w) {
97 int alpha_a = 8, alpha_b = 8;
99 for (i = 24; i >= 0; i -= 8) {
100 d = alpha_a * (int)((a >> i) & 0xFF) -
101 alpha_b * (
int)((b >> i) & 0xFF);
117 unsigned count[256] = { 0 };
120 int x,
y, i, j, match, d, best_d,
av_uninit(best_j);
123 for (
y = 0;
y < r->
h;
y++) {
124 for (x = 0; x < r->
w; x++)
128 for (i = 0; i < 256; i++) {
133 match =
color < 0x33000000 ? 0 :
color < 0xCC000000 ? 1 : 17;
136 for (j = 0; j < 16; j++) {
146 hits[match] += count[i];
151 int out_alpha[4],
unsigned hits[33])
154 int i, j, bright,
mult;
156 int selected[4] = { 0 };
157 uint32_t pseudopal[33] = { 0 };
158 uint32_t refcolor[3] = { 0x00000000, 0xFFFFFFFF, 0xFF000000 };
164 for (i = 0; i < 16; i++) {
165 if (!(hits[1 + i] + hits[17 + i]))
169 for (j = 0; j < 3; j++, color >>= 8)
170 bright += (color & 0xFF) < 0x40 || (color & 0xFF) >= 0xC0;
171 mult = 2 +
FFMIN(bright, 2);
172 hits[ 1 + i] *=
mult;
173 hits[17 + i] *=
mult;
177 for (i = 0; i < 4; i++) {
178 for (j = 0; j < 33; j++)
179 if (hits[j] > hits[selected[i]])
181 hits[selected[i]] = 0;
186 for (i = 0; i < 16; i++) {
190 for (i = 0; i < 3; i++) {
192 for (j = i + 1; j < 4; j++) {
195 FFSWAP(
int, selected[i], selected[j]);
202 for (i = 0; i < 4; i++) {
203 out_palette[i] = selected[i] ? (selected[i] - 1) & 0xF : 0;
204 out_alpha [i] = !selected[i] ? 0 : selected[i] < 17 ? 0x80 : 0xFF;
210 const int out_palette[],
unsigned int const out_alpha[])
214 uint32_t pseudopal[4];
216 for (i = 0; i < 4; i++)
217 pseudopal[i] = (out_alpha[i] << 24) |
219 for (i = 0; i < 256; i++) {
221 for (j = 0; j < 4; j++) {
239 for (y = 0; y < src->
h; y++) {
240 for (x = 0; x < src->
w; x++)
241 *(q++) = cmap[*(p++)];
248 uint8_t *outbuf,
int outbuf_size,
253 int offset1, offset2;
255 unsigned global_palette_hits[33] = { 0 };
263 if (rects == 0 || h->
rects == NULL)
265 for (i = 0; i < rects; i++)
270 vrect = *h->
rects[0];
277 int xmin = h->
rects[0]->
x, xmax = xmin + h->
rects[0]->
w;
278 int ymin = h->
rects[0]->
y, ymax = ymin + h->
rects[0]->
h;
279 for (i = 1; i < rects; i++) {
287 vrect.
w = xmax - xmin;
288 vrect.
h = ymax - ymin;
293 global_palette_hits[0] = vrect.
w * vrect.
h;
294 for (i = 0; i < rects; i++)
295 global_palette_hits[0] -= h->
rects[i]->
w * h->
rects[i]->
h;
298 for (i = 0; i < rects; i++)
300 select_palette(avctx, out_palette, out_alpha, global_palette_hits);
307 for (i = 0; i < rects; i++) {
309 out_palette, out_alpha);
312 for (i = 0; i < 4; i++)
316 out_palette, out_alpha);
320 for (i = 0; i < 4; i++)
323 out_palette[i], out_alpha[i] >> 4);
328 offset1 = q - outbuf;
330 if ((q - outbuf) + vrect.
w * vrect.
h / 2 + 17 + 21 > outbuf_size) {
336 vrect.
w, (vrect.
h + 1) >> 1, cmap);
337 offset2 = q - outbuf;
339 vrect.
w, vrect.
h >> 1, cmap);
343 bytestream_put_be16(&qq, q - outbuf);
347 bytestream_put_be16(&q, (q - outbuf) + 8 + 12 + 2);
349 *q++ = (out_palette[3] << 4) | out_palette[2];
350 *q++ = (out_palette[1] << 4) | out_palette[0];
352 *q++ = (out_alpha[3] & 0xF0) | (out_alpha[2] >> 4);
353 *q++ = (out_alpha[1] & 0xF0) | (out_alpha[0] >> 4);
356 x2 = vrect.
x + vrect.
w - 1;
357 y2 = vrect.
y + vrect.
h - 1;
362 *q++ = (vrect.
x << 4) | ((x2 >> 8) & 0xf);
366 *q++ = (vrect.
y << 4) | ((y2 >> 8) & 0xf);
371 bytestream_put_be16(&q, offset1);
372 bytestream_put_be16(&q, offset2);
379 bytestream_put_be16(&q, (q - outbuf) - 2 );
384 bytestream_put_be16(&qq, q - outbuf);
397 static const uint32_t default_palette[16] = {
398 0x000000, 0x0000FF, 0x00FF00, 0xFF0000,
399 0xFFFF00, 0xFF00FF, 0x00FFFF, 0xFFFFFF,
400 0x808000, 0x8080FF, 0x800080, 0x80FF80,
401 0x008080, 0xFF8080, 0x555555, 0xAAAAAA,
413 for (i = 0; i < 16; i++)
425 unsigned char *
buf,
int buf_size,
void * av_calloc(size_t nmemb, size_t size) av_malloc_attrib
Allocate a block of nmemb * size bytes with alignment suitable for all memory accesses (including vec...
int x
top left corner of pict, undefined when pict is not set
#define AVERROR_BUFFER_TOO_SMALL
int linesize[AV_NUM_DATA_POINTERS]
number of bytes per line
void av_log(void *avcl, int level, const char *fmt,...) av_printf_format(3
Send the specified message to the log if the level is less than or equal to the current av_log_level...
static int color_distance(uint32_t a, uint32_t b)
static void copy_rectangle(AVSubtitleRect *dst, AVSubtitleRect *src, int cmap[])
int w
width of pict, undefined when pict is not set
static const uint32_t color[16+AV_CLASS_CATEGORY_NB]
static void dvd_encode_rle(uint8_t **pq, const uint8_t *bitmap, int linesize, int w, int h, const int cmap[256])
const char * name
Name of the codec implementation.
int h
height of pict, undefined when pict is not set
#define FFSWAP(type, a, b)
uint8_t * data[AV_NUM_DATA_POINTERS]
pointers to the image data planes
int avpriv_bprint_to_extradata(AVCodecContext *avctx, struct AVBPrint *buf)
Finalize buf into extradata and set its size appropriately.
static int dvdsub_encode(AVCodecContext *avctx, unsigned char *buf, int buf_size, const AVSubtitle *sub)
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
void av_free(void *ptr)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc(). ...
int y
top left corner of pict, undefined when pict is not set
AVCodec ff_dvdsub_encoder
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Libavcodec external API header.
uint32_t end_display_time
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Init a print buffer.
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...
A bitmap, pict will be set.
Buffer to print data progressively.
AVPicture pict
data+linesize for the bitmap of this subtitle.
int width
picture width / height.
static void build_color_map(AVCodecContext *avctx, int cmap[], const uint32_t palette[], const int out_palette[], unsigned int const out_alpha[])
main external API structure.
static int16_t mult(Float11 *f1, Float11 *f2)
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 int encode_dvd_subtitles(AVCodecContext *avctx, uint8_t *outbuf, int outbuf_size, const AVSubtitle *h)
common internal api header.
uint32_t start_display_time
void av_bprintf(AVBPrint *buf, const char *fmt,...) av_printf_format(2
Append a formatted string to a print buffer.
#define av_assert0(cond)
assert() equivalent, that is always enabled.
uint32_t global_palette[16]
static int dvdsub_init(AVCodecContext *avctx)