[libbluray-devel] Add rle_crop_object(). Improve rle functions.

hpi1 git at videolan.org
Fri Nov 8 11:29:48 CET 2013


libbluray | branch: master | hpi1 <hpi1 at anonymous.org> | 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 <phintuka at users.sourceforge.net>
+ *
+ * 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_ */



More information about the libbluray-devel mailing list