changeset 532:128a50feff07

Implement initial generic bitmap "encoding" function, that constructs generic bitmap formats as a "reverse" of the decoding process.
author Matti Hamalainen <ccr@tnsp.org>
date Thu, 22 Nov 2012 17:44:45 +0200
parents 2ac364d0ace9
children 91e2d0d74e2f
files lib64gfx.c
diffstat 1 files changed, 75 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/lib64gfx.c	Thu Nov 22 17:10:05 2012 +0200
+++ b/lib64gfx.c	Thu Nov 22 17:44:45 2012 +0200
@@ -602,6 +602,81 @@
 }
 
 
+int dmC64EncodeGenericBMP(Uint8 **pbuf, size_t *plen, const DMC64Image *img, const DMC64ImageFormat *fmt)
+{
+    int i, res = DMERR_OK;
+    Uint8 *buf;
+    size_t allocated;
+
+    if (pbuf == NULL || plen == NULL || img == NULL || fmt == NULL)
+        return DMERR_NULLPTR;
+
+    // Allocate the output buffer
+    *plen = 0;
+    if (fmt->size > 0)
+        *plen = allocated = fmt->size;
+    else
+        allocated = 8 * 1024;
+
+    if ((buf = dmMalloc(allocated)) == NULL)
+    {
+        dmError("Could not allocate %d bytes of memory for C64 image encoding buffer.\n",
+            allocated);
+        res = DMERR_MALLOC;
+        goto error;
+    }
+
+    // Perform encoding
+    for (i = 0; i < fmt->nencdecOps; i++)
+    {
+        const DMC64EncDecOp *op = &fmt->encdecOps[i];
+        Uint8 *dst = buf + op->offs;
+        size_t size;
+
+        if ((res = dmC64SanityCheckEncDecOp(i, op)) != DMERR_OK)
+            goto error;
+
+        size = (op->size == 0) ? dmC64DefaultSizes[op->type] : op->size;
+
+        if (op->offs + size > allocated)
+        {
+            if ((buf = dmRealloc(buf, allocated)) == NULL)
+            {
+                size_t diff = allocated - (op->offs + size),
+                       grow = (diff / (BUF_SIZE_GROW - 1)) * BUF_SIZE_GROW;
+                allocated = allocated + grow;
+                dmError("Could not re-allocate %d bytes of memory for C64 image encoding buffer.\n",
+                    allocated);
+                res = DMERR_MALLOC;
+                goto error;
+            }
+        }
+
+        if (fmt->size == 0 && op->offs + size > *plen)
+            *plen = op->offs + size;
+
+        switch (op->type)
+        {
+            case DT_COLOR_RAM:   memcpy(dst, img->color[op->bank], size); break;
+            case DT_BITMAP:      memcpy(dst, img->bitmap[op->bank], size); break;
+            case DT_SCREEN_RAM:  memcpy(dst, img->screen[op->bank], size); break;
+            case DT_BGCOLOR:     *dst = img->bgcolor; break;
+            case DT_EXTRADATA:   memcpy(dst, img->extradata, size); break;
+            case DT_ENC_FUNCTION:
+                break;
+        }
+    }
+
+    return DMERR_OK;
+
+error:
+    dmFree(*pbuf);
+    *pbuf = NULL;
+    *plen = 0;
+    return res;
+}
+
+
 static inline Uint8 dmC64GetMCColor(const DMC64Image *img, const int bits, const int cbank, const int vbank, const int scroffs)
 {
     switch (bits)