# HG changeset patch # User Matti Hamalainen # Date 1544709249 -7200 # Node ID aedadff9e1162849422c6a8e8f6115c7fac19767 # Parent b31bb3dc13105670bb4c09ca369313f597d93864 Implement dmGetBits() to the DMBitStreamContext API. Also improve error handling. diff -r b31bb3dc1310 -r aedadff9e116 tools/libgfx.c --- 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) diff -r b31bb3dc1310 -r aedadff9e116 tools/libgfx.h --- 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