view tests/encbr1test.c @ 2298:b5abfff07ca9

Add new DMGrowBuf helper functions dmGrowBufCopyOffsSize() and dmGrowBufConstCopyOffsSize().
author Matti Hamalainen <ccr@tnsp.org>
date Thu, 04 Jul 2019 10:54:16 +0300
parents 8cd012260976
children 9807ae37ad69
line wrap: on
line source

#include "dmtool.h"
#include "dmlib.h"
#include "dmres.h"
#include "dmmutex.h"


#define BR_DEBUG 1
//#define BR_WRITE

enum
{
    DMODE_LIT,
    DMODE_RLE,
};


#if BR_DEBUG == 1
static int mcount = 0;
static int moffs = 0;

static void mprintbyte(const Uint8 data)
{
    if (mcount == 0) printf("%04x | ", moffs);
    printf("%02x ", data);
    if (mcount++ >= 15) { printf("\n"); mcount = 0; }
    moffs++;
}
#endif


BOOL dmIFFEncodeByteRun1LIT(DMResource *fp,
    const Uint8 *buf, const size_t offs,
    const size_t count)
{
    if (count <= 0)
        return TRUE;

    #if BR_DEBUG != 0 || defined(BR_WRITE)
    Uint8 tmp = count - 1;
    #endif

    #if BR_DEBUG == 2
    printf("L: %02x ", tmp);
    for (size_t n = 0; n < count; n++)
        printf("%02x ", buf[offs + n]);
    printf("[%" DM_PRIu_SIZE_T "]\n", count);
    #elif BR_DEBUG == 1
    mprintbyte(tmp);
    for (size_t n = 0; n < count; n++)
        mprintbyte(buf[offs + n]);
    #endif

    #ifdef BR_WRITE
    if (!dmf_write_byte(fp, tmp) ||
        !dmf_write_str(fp, buf + offs, count))
        return FALSE;
    #else
    (void) fp;
    #endif

    return TRUE;
}


BOOL dmIFFEncodeByteRun1RLE(DMResource *fp,
    const Uint8 *buf, const size_t offs,
    const size_t count)
{
    if (count <= 0)
        return TRUE;

    #if BR_DEBUG != 0 || defined(BR_WRITE)
    Uint8 tmp = ((Uint8) count - 2) ^ 0xff;
    Uint8 data = buf[offs];
    #endif

    #if BR_DEBUG == 2
    printf("R: %02x %02x [%" DM_PRIu_SIZE_T "]\n", tmp, data, count);
    #elif BR_DEBUG == 1
    mprintbyte(tmp);
    mprintbyte(data);
    #endif

    #ifdef BR_WRITE
    if (!dmf_write_byte(fp, tmp) ||
        !dmf_write_byte(fp, data))
        return FALSE;
    #else
    (void) fp;
    #endif

    return TRUE;
}


BOOL dmIFFEncodeByteRun1Row(DMResource *fp, const Uint8 *buf, const size_t bufLen)
{
    int prev = -1, mode = DMODE_LIT;
    size_t offs, l_offs, r_offs;
    BOOL ret = TRUE;

    #if BR_DEBUG == 1
    mcount = 0;
    #endif

    for (offs = l_offs = r_offs = 0; offs < bufLen; offs++)
    {
        Uint8 data = buf[offs];
        BOOL flush = FALSE;
        int pmode = mode;

        if (data == prev)
        {
            if (mode == DMODE_LIT &&
                offs - r_offs >= 2)
            {
                ret = dmIFFEncodeByteRun1LIT(fp, buf, l_offs, r_offs - l_offs);
                mode = DMODE_RLE;
            }
        }
        else
        {
            if (mode != DMODE_LIT)
            {
                ret = dmIFFEncodeByteRun1RLE(fp, buf, r_offs, offs - r_offs);
                mode = DMODE_LIT;
                l_offs = offs;
            }
            r_offs = offs;
        }

        if (!ret)
            goto out;

#if BR_DEBUG == 2
        printf("%04" DM_PRIx_SIZE_T ": %02x | r_count=%" DM_PRIu_SIZE_T ", l_count=%" DM_PRIu_SIZE_T ", mode=%s | [%04" DM_PRIx_SIZE_T ", %04" DM_PRIx_SIZE_T "]",
            offs, data, offs - r_offs, offs - l_offs,
            mode == DMODE_RLE ? "RLE" : "LIT",
            r_offs, l_offs);
#endif

        // NOTE! RLE max is 128, checked against DP2e
        // Not sure about LIT max yet
        if ((pmode == DMODE_RLE && offs - r_offs >= 128) ||
            (pmode == DMODE_LIT && offs - l_offs >= 128))
        {
            flush = TRUE;
#if BR_DEBUG == 2
            printf(" <LEN FLUSH>");
#endif
        }

        // Check for last byte of input
        if (offs == bufLen - 1)
        {
            offs++;
            flush = TRUE;
            pmode = mode;
#if BR_DEBUG == 2
            printf(" <FINAL FLUSH>");
#endif
        }

#if BR_DEBUG == 2
        printf("\n");
#endif

        if (flush)
        {
            if (pmode == DMODE_RLE)
                ret = dmIFFEncodeByteRun1RLE(fp, buf, r_offs, offs - r_offs);
            else
                ret = dmIFFEncodeByteRun1LIT(fp, buf, l_offs, offs - l_offs);

            r_offs = l_offs = offs;
            mode = DMODE_LIT;

            if (!ret)
                goto out;
        }

        prev = data;
    }

out:
    return ret;
}



int main(int argc, char *argv[])
{
    DMResource *fp = NULL;
    (void) argc;
    (void) argv;

#ifdef BR_WRITE
    dmf_open_stdio_stream(stderr, &fp);
#endif

#if 1
    static const Uint8 test[] =
    {
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

        0,
        1,

        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

        2, 2, 3, 4, 5, 5, 5, 6,

        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

        1, 3,

        0, 0, 0, 1,
    };

    {
        int cnt = 0;
        for (size_t xc = 0; xc < sizeof(test); xc++)
        {
            if (cnt == 0) printf("%04" DM_PRIx_SIZE_T " | ", xc);
            printf("%02x ", *(test + xc));
            if (cnt++ >= 15) { printf("\n"); cnt = 0; }
        }
        printf("\n\n");

        dmIFFEncodeByteRun1Row(fp, test, sizeof(test));
        printf("\n--\n");
    }

#else

#if 1
#    include "TEST03.cdump"
#else
#    include "BABYFACE.cdump"
#    undef SET_WIDTH
#    define SET_WIDTH 80
#endif

    printf("DATA = %" DM_PRIu_SIZE_T "\n", sizeof(img_data));
    for (int yc = 0; yc < sizeof(img_data) / SET_WIDTH; yc++)
    {
        Uint8 *nptr = img_data + (yc * SET_WIDTH);
        int cnt = 0;

        printf("#%03d\n", yc);
        for (int xc = 0; xc < SET_WIDTH; xc++)
        {
            if (cnt == 0) printf("%04x | ", xc);
            printf("%02x ", *(nptr + xc));
            if (cnt++ >= 15) { printf("\n"); cnt = 0; }
        }
        printf("\n\n");

        dmIFFEncodeByteRun1Row(fp, nptr, SET_WIDTH);
        printf("\n--\n");
    }
#endif

#ifdef BR_WRITE
    dmf_close(fp);
#endif

    return 0;
}