changeset 2086:aedadff9e116

Implement dmGetBits() to the DMBitStreamContext API. Also improve error handling.
author Matti Hamalainen <ccr@tnsp.org>
date Thu, 13 Dec 2018 15:54:09 +0200
parents b31bb3dc1310
children 05532d716f50
files tools/libgfx.c tools/libgfx.h
diffstat 2 files changed, 98 insertions(+), 67 deletions(-) [+]
line wrap: on
line diff
--- a/tools/libgfx.c	Tue Dec 11 15:17:40 2018 +0200
+++ b/tools/libgfx.c	Thu Dec 13 15:54:09 2018 +0200
@@ -19,35 +19,63 @@
 {
     ctx->outBuf       = 0;
     ctx->outByteCount = 0;
-    ctx->outBitCount  = 8;
+    ctx->outBitCount  = 0;
+
+    ctx->inBuf        = 0;
+    ctx->inByteCount  = 0;
+    ctx->inBitCount   = 0;
 }
 
 
-BOOL dmPutBits(DMBitStreamContext *ctx, const int val, const int n)
+int dmPutBits(DMBitStreamContext *ctx, const unsigned int val, const unsigned int n)
 {
-    unsigned int mask = 1 << (n - 1);
-
-    for (int i = 0; i < n; i++)
+    for (unsigned int i = 0; i < n; i++)
     {
         ctx->outBuf <<= 1;
 
-        if (val & mask)
-          ctx->outBuf |= 1;
-
-        mask >>= 1;
-        ctx->outBitCount--;
-
-        if (ctx->outBitCount == 0)
+        if (val & (1 << (n - 1 - i)))
+            ctx->outBuf |= 1;
+
+        ctx->outBitCount++;
+        if (ctx->outBitCount == 8)
         {
-            if (!ctx->putByte(ctx, ctx->outBuf & 0xff))
-                return FALSE;
-
-            ctx->outBitCount = 8;
+            int ret;
+            if ((ret = ctx->putByte(ctx)) != DMERR_OK)
+                return ret;
+
+            ctx->outBitCount = 0;
             ctx->outByteCount++;
         }
     }
 
-    return TRUE;
+    return DMERR_OK;
+}
+
+
+int dmGetBits(DMBitStreamContext *ctx, unsigned int *val, const unsigned int n)
+{
+    *val = 0;
+
+    for (unsigned int i = 0; i < n; i++)
+    {
+        if (ctx->inBitCount == 0)
+        {
+            int ret;
+            if ((ret = ctx->getByte(ctx)) != DMERR_OK)
+                return ret;
+
+            ctx->inBitCount = 8;
+            ctx->inByteCount++;
+        }
+
+        *val <<= 1;
+        *val |= ctx->inBuf >> 7 & 1;
+
+        ctx->inBuf <<= 1;
+        ctx->inBitCount--;
+    }
+
+    return DMERR_OK;
 }
 
 
@@ -56,33 +84,13 @@
   if (ctx == NULL)
       return DMERR_NULLPTR;
 
-  if (ctx->outBitCount != 8)
-      dmPutBits(ctx, 0, ctx->outBitCount);
+  if (ctx->outBitCount > 0)
+      return dmPutBits(ctx, 0, 8 - ctx->outBitCount);
 
   return DMERR_OK;
 }
 
 
-static BOOL dmPutByteFILE(DMBitStreamContext *ctx, const Uint8 val)
-{
-    return dmf_write_byte((DMResource *) ctx->handle, val);
-}
-
-
-int dmInitBitStreamFILE(DMBitStreamContext *ctx, DMResource *fp)
-{
-    if (ctx == NULL || fp == NULL)
-        return DMERR_NULLPTR;
-
-    ctx->putByte = dmPutByteFILE;
-    ctx->handle  = (void *) fp;
-
-    dmInitBitStreamContext(ctx);
-
-    return DMERR_OK;
-}
-
-
 BOOL dmCompareColor(const DMColor *c1, const DMColor *c2, BOOL alpha)
 {
     if (c1->r == c2->r &&
@@ -351,27 +359,40 @@
 }
 
 
-static BOOL dmWriteRAWRow(DMBitStreamContext *bs, const DMImage *img,
+static int dmWriteRAWRow(DMBitStreamContext *bs, const DMImage *img,
     const DMImageConvSpec *spec, const int yc, const int plane)
 {
     const Uint8 *sp = img->data + (yc * img->pitch);
     for (int xc = 0; xc < img->width; xc++)
     {
+        int res;
         for (int xscale = 0; xscale < spec->scaleX; xscale++)
-        if (!dmPutBits(bs, (sp[xc] >> plane) & 1, 1))
-            return FALSE;
+        if ((res = dmPutBits(bs, (sp[xc] >> plane) & 1, 1)) != DMERR_OK)
+            return res;
     }
-    return TRUE;
+    return DMERR_OK;
+}
+
+
+static int dmPutByteRes(DMBitStreamContext *ctx)
+{
+    DMResource *fp = (DMResource *) ctx->handle;
+
+    if (!dmf_write_byte(fp, ctx->outBuf & 0xff))
+        return dmferror(fp);
+    else
+        return DMERR_OK;
 }
 
 
 int dmWriteRAWImage(DMResource *fp, const DMImage *img, const DMImageConvSpec *spec)
 {
     int res;
-    DMBitStreamContext bs;
-
-    if ((res = dmInitBitStreamFILE(&bs, fp)) != DMERR_OK)
-        return res;
+    DMBitStreamContext ctx;
+
+    dmInitBitStreamContext(&ctx);
+    ctx.putByte = dmPutByteRes;
+    ctx.handle  = (void *) fp;
 
     if (spec->planar)
     {
@@ -381,8 +402,8 @@
         for (int yscale = 0; yscale < spec->scaleY; yscale++)
         for (int plane = 0; plane < spec->nplanes; plane++)
         {
-            if (!dmWriteRAWRow(&bs, img, spec, yc, plane))
-                return DMERR_FWRITE;
+            if ((res = dmWriteRAWRow(&ctx, img, spec, yc, plane)) != DMERR_OK)
+                return res;
         }
     }
     else
@@ -392,25 +413,30 @@
         for (int yc = 0; yc < img->height; yc++)
         for (int yscale = 0; yscale < spec->scaleY; yscale++)
         {
-            if (!dmWriteRAWRow(&bs, img, spec, yc, plane))
-                return DMERR_FWRITE;
+            if ((res = dmWriteRAWRow(&ctx, img, spec, yc, plane)) != DMERR_OK)
+                return res;
         }
     }
 
-    return dmFlushBitStream(&bs);
+    return dmFlushBitStream(&ctx);
 }
 
 
-static BOOL dmPutByteCDump(DMBitStreamContext *ctx, const Uint8 val)
+static int dmPutByteCDump(DMBitStreamContext *ctx)
 {
-    return dmfprintf((DMResource *) ctx->handle, "0x%02x, ", val) > 0;
+    DMResource *fp = (DMResource *) ctx->handle;
+
+    if (dmfprintf(fp, "0x%02x, ", ctx->outBuf & 0xff) < 2)
+        return dmferror(fp);
+    else
+        return DMERR_OK;
 }
 
 
 int dmWriteCDumpImage(DMResource *fp, const DMImage *img, const DMImageConvSpec *spec)
 {
     int res;
-    DMBitStreamContext bs;
+    DMBitStreamContext ctx;
 
     if (dmfprintf(fp,
         "#define SET_WIDTH %d\n"
@@ -421,9 +447,9 @@
         img->height * spec->scaleY) < 0)
         return dmferror(fp);
 
-    dmInitBitStreamContext(&bs);
-    bs.putByte = dmPutByteCDump;
-    bs.handle = (void *) fp;
+    dmInitBitStreamContext(&ctx);
+    ctx.putByte = dmPutByteCDump;
+    ctx.handle = (void *) fp;
 
     if (spec->planar)
     {
@@ -433,8 +459,8 @@
         for (int yscale = 0; yscale < spec->scaleY; yscale++)
         for (int plane = 0; plane < spec->nplanes; plane++)
         {
-            if (!dmWriteRAWRow(&bs, img, spec, yc, plane))
-                return DMERR_FWRITE;
+            if ((res = dmWriteRAWRow(&ctx, img, spec, yc, plane)) != DMERR_OK)
+                return res;
 
             if (dmfprintf(fp, "\n") < 0)
                 return dmferror(fp);
@@ -447,15 +473,15 @@
         for (int yc = 0; yc < img->height; yc++)
         for (int yscale = 0; yscale < spec->scaleY; yscale++)
         {
-            if (!dmWriteRAWRow(&bs, img, spec, yc, plane))
-                return DMERR_FWRITE;
+            if ((res = dmWriteRAWRow(&ctx, img, spec, yc, plane)) != DMERR_OK)
+                return res;
 
             if (dmfprintf(fp, "\n") < 0)
                 return dmferror(fp);
         }
     }
 
-    res = dmFlushBitStream(&bs);
+    res = dmFlushBitStream(&ctx);
 
     if (res == DMERR_OK &&
         dmfprintf(fp, "};\n") < 0)
--- a/tools/libgfx.h	Tue Dec 11 15:17:40 2018 +0200
+++ b/tools/libgfx.h	Thu Dec 13 15:54:09 2018 +0200
@@ -152,16 +152,21 @@
 {
     void *handle;
 
-    BOOL (*putByte)(struct _DMBitStreamContext *ctx, Uint8 val);
+    int (*putByte)(struct _DMBitStreamContext *ctx);
+    int (*getByte)(struct _DMBitStreamContext *ctx);
 
-    int outBuf, outBitCount, outByteCount;
+    unsigned int
+        outBuf, outBitCount, outByteCount,
+        inBuf, inBitCount, inByteCount;
 } DMBitStreamContext;
 
 
 void  dmInitBitStreamContext(DMBitStreamContext *ctx);
 int   dmFlushBitStream(DMBitStreamContext *ctx);
-BOOL  dmPutBits(DMBitStreamContext *ctx, const int val, const int n);
-int   dmInitBitStreamFILE(DMBitStreamContext *ctx, DMResource *fp);
+int   dmInitBitStreamRes(DMBitStreamContext *ctx, DMResource *fp);
+
+int   dmPutBits(DMBitStreamContext *ctx, const unsigned int val, const unsigned int n);
+int   dmGetBits(DMBitStreamContext *ctx, unsigned int *val, const unsigned int n);
 
 
 #ifdef __cplusplus