libbluray | branch: master | hpi1 <[email protected]> | Fri Nov 8 11:53:27 2013 +0200| [2a1e9216bc8eb844abe6c03d00d9784c704fadb1] | committer: hpi1
Add rle_crop_object(). Improve rle functions. > http://git.videolan.org/gitweb.cgi/libbluray.git/?a=commit;h=2a1e9216bc8eb844abe6c03d00d9784c704fadb1 --- src/Makefile.am | 1 + src/libbluray/decoders/graphics_controller.c | 2 +- src/libbluray/decoders/rle.c | 164 ++++++++++++++++++++++++++ src/libbluray/decoders/rle.h | 71 ++++------- 4 files changed, 188 insertions(+), 50 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index aa964a7..8fd3a8c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -52,6 +52,7 @@ libbluray_la_SOURCES = \ libbluray/decoders/ig_decode.h \ libbluray/decoders/ig_decode.c \ libbluray/decoders/rle.h \ + libbluray/decoders/rle.c \ libbluray/decoders/textst.h \ libbluray/decoders/textst_decode.h \ libbluray/decoders/textst_decode.c \ diff --git a/src/libbluray/decoders/graphics_controller.c b/src/libbluray/decoders/graphics_controller.c index 8e3cf93..69ac2a3 100644 --- a/src/libbluray/decoders/graphics_controller.c +++ b/src/libbluray/decoders/graphics_controller.c @@ -925,7 +925,7 @@ static int _render_textst_region(GRAPHICS_CONTROLLER *p, int64_t pts, BD_TEXTST_ rle_add_eol(&rle); } - _render_rle(p, pts, rle.start, + _render_rle(p, pts, rle_get(&rle), style->region_info.region.xpos, style->region_info.region.ypos, style->region_info.region.width, style->region_info.region.height, palette); diff --git a/src/libbluray/decoders/rle.c b/src/libbluray/decoders/rle.c new file mode 100644 index 0000000..2d90979 --- /dev/null +++ b/src/libbluray/decoders/rle.c @@ -0,0 +1,164 @@ +/* + * This file is part of libbluray + * Copyright (C) 2013 Petri Hintukainen <[email protected]> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <http://www.gnu.org/licenses/>. + */ + +#include "rle.h" + +#include "util/logging.h" + +/* + * util + */ + +static void _rle_ensure_size(RLE_ENC *p) +{ + if (BD_UNLIKELY(!p->free_elem)) { + BD_PG_RLE_ELEM *start = rle_get(p); + /* realloc to 2x */ + p->free_elem = p->num_elem; + start = refcnt_realloc(start, p->num_elem * 2 * sizeof(BD_PG_RLE_ELEM)); + p->elem = start + p->num_elem; + p->num_elem *= 2; + } +} + +/* + * encoding + */ + +static void _enc_elem(RLE_ENC *p, uint16_t color, uint16_t len) +{ + _rle_ensure_size(p); + + p->elem->color = color; + p->elem->len = len; + + p->free_elem--; + p->elem++; +} + +static void _enc_eol(RLE_ENC *p) +{ + _enc_elem(p, 0, 0); +} + +BD_PG_RLE_ELEM *rle_crop_object(const BD_PG_RLE_ELEM *orig, int width, + int crop_x, int crop_y, int crop_w, int crop_h) +{ + RLE_ENC rle; + int x0 = crop_x; + int x1 = crop_x + crop_w; /* first pixel outside of cropped region */ + int x, y; + + rle_begin(&rle); + + /* skip crop_y */ + for (y = 0; y < crop_y; y++) { + for (x = 0; x < width; x += orig->len, orig++) ; + } + + /* crop lines */ + + for (y = 0; y < crop_h; y++) { + for (x = 0; x < width; ) { + BD_PG_RLE_ELEM bite = *(orig++); + + if (BD_UNLIKELY(bite.len < 1)) { + BD_DEBUG(DBG_GC | DBG_CRIT, "rle eol marker in middle of line (x=%d/%d)\n", x, width); + continue; + } + + /* starts outside, ends outside */ + if (x + bite.len < x0 || x >= x1) { + x += bite.len; + continue; + } + + /* starts before ? */ + if (BD_UNLIKELY(x < x0)) { + bite.len -= x0 - x; + x = x0; + } + + x += bite.len; + + /* ends after ? */ + if (BD_UNLIKELY(x >= x1)) { + bite.len -= x - x1; + } + + _enc_elem(&rle, bite.color, bite.len); + } + + if (BD_LIKELY(!orig->len)) { + /* skip eol marker */ + orig++; + } else { + BD_DEBUG(DBG_GC | DBG_CRIT, "rle eol marker missing\n"); + } + + _enc_eol(&rle); + } + + return rle_get(&rle); +} + +/* + * compression + */ + +static void _rle_grow(RLE_ENC *p) +{ + _rle_ensure_size(p); + + p->free_elem--; + p->elem++; + p->elem->len = 0; +} + +void rle_add_eol(RLE_ENC *p) +{ + if (BD_LIKELY(p->elem->len)) { + _rle_grow(p); + } + p->elem->color = 0; + + _rle_grow(p); + p->elem->color = 0xffff; +} + +void rle_add_bite(RLE_ENC *p, uint8_t color, int len) +{ + if (BD_LIKELY(color == p->elem->color)) { + p->elem->len += len; + } else { + if (BD_LIKELY(p->elem->len)) { + _rle_grow(p); + } + p->elem->color = color; + p->elem->len = len; + } +} + +void rle_compress_chunk(RLE_ENC *p, const uint8_t *mem, unsigned width) +{ + unsigned ii; + for (ii = 0; ii < width; ii++) { + rle_add_bite(p, mem[ii], 1); + } +} diff --git a/src/libbluray/decoders/rle.h b/src/libbluray/decoders/rle.h index 824a344..bb27d3d 100644 --- a/src/libbluray/decoders/rle.h +++ b/src/libbluray/decoders/rle.h @@ -27,13 +27,13 @@ #include <stdint.h> /* - * + * encode state */ typedef struct { - BD_PG_RLE_ELEM *start; /* first element */ BD_PG_RLE_ELEM *elem; /* current element */ - int num_elem; /* allocated element count */ + unsigned int free_elem;/* unused element count */ + unsigned int num_elem; /* allocated element count */ } RLE_ENC; /* @@ -43,65 +43,38 @@ typedef struct { #include "util/refcnt.h" #include "util/macro.h" -static void rle_begin(RLE_ENC *p) +BD_PRIVATE BD_PG_RLE_ELEM *rle_crop_object(const BD_PG_RLE_ELEM *orig, int width, + int crop_x, int crop_y, int crop_w, int crop_h); + +static inline void rle_begin(RLE_ENC *p) { p->num_elem = 1024; - p->start = refcnt_realloc(NULL, p->num_elem * sizeof(BD_PG_RLE_ELEM)); + p->free_elem = 1024; + p->elem = refcnt_realloc(NULL, p->num_elem * sizeof(BD_PG_RLE_ELEM)); - p->elem = p->start; p->elem->len = 0; p->elem->color = 0xffff; } -static void rle_end(RLE_ENC *p) +static inline BD_PG_RLE_ELEM *rle_get(RLE_ENC *p) { - bd_refcnt_dec(p->start); - p->start = NULL; + BD_PG_RLE_ELEM *start = (p->elem ? p->elem - (p->num_elem - p->free_elem) : NULL); + return start; } -static void _rle_grow(RLE_ENC *p) +static inline void rle_end(RLE_ENC *p) { - int count = (int)(p->elem - p->start) + 1; - if (count >= p->num_elem) { - /* realloc */ - p->num_elem = p->num_elem * 2; - p->start = refcnt_realloc(p->start, p->num_elem * sizeof(BD_PG_RLE_ELEM)); - } - - p->elem = p->start + count; - p->elem->len = 0; -} - -static void rle_add_eol(RLE_ENC *p) -{ - if (p->elem->len) { - _rle_grow(p); - } - p->elem->color = 0; - - _rle_grow(p); - p->elem->color = 0xffff; + BD_PG_RLE_ELEM *start = rle_get(p); + bd_refcnt_dec(start); + p->elem = NULL; } -static void rle_add_bite(RLE_ENC *p, uint8_t color, int len) -{ - if (color == p->elem->color) { - p->elem->len += len; - } else { - if (p->elem->len) { - _rle_grow(p); - } - p->elem->color = color; - p->elem->len = len; - } -} +/* + * compression + */ -static void rle_compress_chunk(RLE_ENC *p, const uint8_t *mem, unsigned width) -{ - unsigned ii; - for (ii = 0; ii < width; ii++) { - rle_add_bite(p, mem[ii], 1); - } -} +BD_PRIVATE void rle_add_eol(RLE_ENC *p); +BD_PRIVATE void rle_add_bite(RLE_ENC *p, uint8_t color, int len); +BD_PRIVATE void rle_compress_chunk(RLE_ENC *p, const uint8_t *mem, unsigned width); #endif /* _BD_RLE_H_ */ _______________________________________________ libbluray-devel mailing list [email protected] https://mailman.videolan.org/listinfo/libbluray-devel
