comparison tools/libgfx.c @ 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 3b3acb6b4ba0
comparison
equal deleted inserted replaced
2085:b31bb3dc1310 2086:aedadff9e116
17 17
18 void dmInitBitStreamContext(DMBitStreamContext *ctx) 18 void dmInitBitStreamContext(DMBitStreamContext *ctx)
19 { 19 {
20 ctx->outBuf = 0; 20 ctx->outBuf = 0;
21 ctx->outByteCount = 0; 21 ctx->outByteCount = 0;
22 ctx->outBitCount = 8; 22 ctx->outBitCount = 0;
23 } 23
24 24 ctx->inBuf = 0;
25 25 ctx->inByteCount = 0;
26 BOOL dmPutBits(DMBitStreamContext *ctx, const int val, const int n) 26 ctx->inBitCount = 0;
27 { 27 }
28 unsigned int mask = 1 << (n - 1); 28
29 29
30 for (int i = 0; i < n; i++) 30 int dmPutBits(DMBitStreamContext *ctx, const unsigned int val, const unsigned int n)
31 {
32 for (unsigned int i = 0; i < n; i++)
31 { 33 {
32 ctx->outBuf <<= 1; 34 ctx->outBuf <<= 1;
33 35
34 if (val & mask) 36 if (val & (1 << (n - 1 - i)))
35 ctx->outBuf |= 1; 37 ctx->outBuf |= 1;
36 38
37 mask >>= 1; 39 ctx->outBitCount++;
38 ctx->outBitCount--; 40 if (ctx->outBitCount == 8)
39 41 {
40 if (ctx->outBitCount == 0) 42 int ret;
41 { 43 if ((ret = ctx->putByte(ctx)) != DMERR_OK)
42 if (!ctx->putByte(ctx, ctx->outBuf & 0xff)) 44 return ret;
43 return FALSE; 45
44 46 ctx->outBitCount = 0;
45 ctx->outBitCount = 8;
46 ctx->outByteCount++; 47 ctx->outByteCount++;
47 } 48 }
48 } 49 }
49 50
50 return TRUE; 51 return DMERR_OK;
52 }
53
54
55 int dmGetBits(DMBitStreamContext *ctx, unsigned int *val, const unsigned int n)
56 {
57 *val = 0;
58
59 for (unsigned int i = 0; i < n; i++)
60 {
61 if (ctx->inBitCount == 0)
62 {
63 int ret;
64 if ((ret = ctx->getByte(ctx)) != DMERR_OK)
65 return ret;
66
67 ctx->inBitCount = 8;
68 ctx->inByteCount++;
69 }
70
71 *val <<= 1;
72 *val |= ctx->inBuf >> 7 & 1;
73
74 ctx->inBuf <<= 1;
75 ctx->inBitCount--;
76 }
77
78 return DMERR_OK;
51 } 79 }
52 80
53 81
54 int dmFlushBitStream(DMBitStreamContext *ctx) 82 int dmFlushBitStream(DMBitStreamContext *ctx)
55 { 83 {
56 if (ctx == NULL) 84 if (ctx == NULL)
57 return DMERR_NULLPTR; 85 return DMERR_NULLPTR;
58 86
59 if (ctx->outBitCount != 8) 87 if (ctx->outBitCount > 0)
60 dmPutBits(ctx, 0, ctx->outBitCount); 88 return dmPutBits(ctx, 0, 8 - ctx->outBitCount);
61 89
62 return DMERR_OK; 90 return DMERR_OK;
63 }
64
65
66 static BOOL dmPutByteFILE(DMBitStreamContext *ctx, const Uint8 val)
67 {
68 return dmf_write_byte((DMResource *) ctx->handle, val);
69 }
70
71
72 int dmInitBitStreamFILE(DMBitStreamContext *ctx, DMResource *fp)
73 {
74 if (ctx == NULL || fp == NULL)
75 return DMERR_NULLPTR;
76
77 ctx->putByte = dmPutByteFILE;
78 ctx->handle = (void *) fp;
79
80 dmInitBitStreamContext(ctx);
81
82 return DMERR_OK;
83 } 91 }
84 92
85 93
86 BOOL dmCompareColor(const DMColor *c1, const DMColor *c2, BOOL alpha) 94 BOOL dmCompareColor(const DMColor *c1, const DMColor *c2, BOOL alpha)
87 { 95 {
349 357
350 return DMERR_OK; 358 return DMERR_OK;
351 } 359 }
352 360
353 361
354 static BOOL dmWriteRAWRow(DMBitStreamContext *bs, const DMImage *img, 362 static int dmWriteRAWRow(DMBitStreamContext *bs, const DMImage *img,
355 const DMImageConvSpec *spec, const int yc, const int plane) 363 const DMImageConvSpec *spec, const int yc, const int plane)
356 { 364 {
357 const Uint8 *sp = img->data + (yc * img->pitch); 365 const Uint8 *sp = img->data + (yc * img->pitch);
358 for (int xc = 0; xc < img->width; xc++) 366 for (int xc = 0; xc < img->width; xc++)
359 { 367 {
368 int res;
360 for (int xscale = 0; xscale < spec->scaleX; xscale++) 369 for (int xscale = 0; xscale < spec->scaleX; xscale++)
361 if (!dmPutBits(bs, (sp[xc] >> plane) & 1, 1)) 370 if ((res = dmPutBits(bs, (sp[xc] >> plane) & 1, 1)) != DMERR_OK)
362 return FALSE; 371 return res;
363 } 372 }
364 return TRUE; 373 return DMERR_OK;
374 }
375
376
377 static int dmPutByteRes(DMBitStreamContext *ctx)
378 {
379 DMResource *fp = (DMResource *) ctx->handle;
380
381 if (!dmf_write_byte(fp, ctx->outBuf & 0xff))
382 return dmferror(fp);
383 else
384 return DMERR_OK;
365 } 385 }
366 386
367 387
368 int dmWriteRAWImage(DMResource *fp, const DMImage *img, const DMImageConvSpec *spec) 388 int dmWriteRAWImage(DMResource *fp, const DMImage *img, const DMImageConvSpec *spec)
369 { 389 {
370 int res; 390 int res;
371 DMBitStreamContext bs; 391 DMBitStreamContext ctx;
372 392
373 if ((res = dmInitBitStreamFILE(&bs, fp)) != DMERR_OK) 393 dmInitBitStreamContext(&ctx);
374 return res; 394 ctx.putByte = dmPutByteRes;
395 ctx.handle = (void *) fp;
375 396
376 if (spec->planar) 397 if (spec->planar)
377 { 398 {
378 // Output bitplanes in planar format 399 // Output bitplanes in planar format
379 // (each plane of line sequentially) 400 // (each plane of line sequentially)
380 for (int yc = 0; yc < img->height; yc++) 401 for (int yc = 0; yc < img->height; yc++)
381 for (int yscale = 0; yscale < spec->scaleY; yscale++) 402 for (int yscale = 0; yscale < spec->scaleY; yscale++)
382 for (int plane = 0; plane < spec->nplanes; plane++) 403 for (int plane = 0; plane < spec->nplanes; plane++)
383 { 404 {
384 if (!dmWriteRAWRow(&bs, img, spec, yc, plane)) 405 if ((res = dmWriteRAWRow(&ctx, img, spec, yc, plane)) != DMERR_OK)
385 return DMERR_FWRITE; 406 return res;
386 } 407 }
387 } 408 }
388 else 409 else
389 { 410 {
390 // Output each bitplane in sequence 411 // Output each bitplane in sequence
391 for (int plane = 0; plane < spec->nplanes; plane++) 412 for (int plane = 0; plane < spec->nplanes; plane++)
392 for (int yc = 0; yc < img->height; yc++) 413 for (int yc = 0; yc < img->height; yc++)
393 for (int yscale = 0; yscale < spec->scaleY; yscale++) 414 for (int yscale = 0; yscale < spec->scaleY; yscale++)
394 { 415 {
395 if (!dmWriteRAWRow(&bs, img, spec, yc, plane)) 416 if ((res = dmWriteRAWRow(&ctx, img, spec, yc, plane)) != DMERR_OK)
396 return DMERR_FWRITE; 417 return res;
397 } 418 }
398 } 419 }
399 420
400 return dmFlushBitStream(&bs); 421 return dmFlushBitStream(&ctx);
401 } 422 }
402 423
403 424
404 static BOOL dmPutByteCDump(DMBitStreamContext *ctx, const Uint8 val) 425 static int dmPutByteCDump(DMBitStreamContext *ctx)
405 { 426 {
406 return dmfprintf((DMResource *) ctx->handle, "0x%02x, ", val) > 0; 427 DMResource *fp = (DMResource *) ctx->handle;
428
429 if (dmfprintf(fp, "0x%02x, ", ctx->outBuf & 0xff) < 2)
430 return dmferror(fp);
431 else
432 return DMERR_OK;
407 } 433 }
408 434
409 435
410 int dmWriteCDumpImage(DMResource *fp, const DMImage *img, const DMImageConvSpec *spec) 436 int dmWriteCDumpImage(DMResource *fp, const DMImage *img, const DMImageConvSpec *spec)
411 { 437 {
412 int res; 438 int res;
413 DMBitStreamContext bs; 439 DMBitStreamContext ctx;
414 440
415 if (dmfprintf(fp, 441 if (dmfprintf(fp,
416 "#define SET_WIDTH %d\n" 442 "#define SET_WIDTH %d\n"
417 "#define SET_HEIGHT %d\n" 443 "#define SET_HEIGHT %d\n"
418 "\n" 444 "\n"
419 "Uint8 img_data[] = {\n", 445 "Uint8 img_data[] = {\n",
420 img->width * spec->scaleX, 446 img->width * spec->scaleX,
421 img->height * spec->scaleY) < 0) 447 img->height * spec->scaleY) < 0)
422 return dmferror(fp); 448 return dmferror(fp);
423 449
424 dmInitBitStreamContext(&bs); 450 dmInitBitStreamContext(&ctx);
425 bs.putByte = dmPutByteCDump; 451 ctx.putByte = dmPutByteCDump;
426 bs.handle = (void *) fp; 452 ctx.handle = (void *) fp;
427 453
428 if (spec->planar) 454 if (spec->planar)
429 { 455 {
430 // Output bitplanes in planar format 456 // Output bitplanes in planar format
431 // (each plane of line sequentially) 457 // (each plane of line sequentially)
432 for (int yc = 0; yc < img->height; yc++) 458 for (int yc = 0; yc < img->height; yc++)
433 for (int yscale = 0; yscale < spec->scaleY; yscale++) 459 for (int yscale = 0; yscale < spec->scaleY; yscale++)
434 for (int plane = 0; plane < spec->nplanes; plane++) 460 for (int plane = 0; plane < spec->nplanes; plane++)
435 { 461 {
436 if (!dmWriteRAWRow(&bs, img, spec, yc, plane)) 462 if ((res = dmWriteRAWRow(&ctx, img, spec, yc, plane)) != DMERR_OK)
437 return DMERR_FWRITE; 463 return res;
438 464
439 if (dmfprintf(fp, "\n") < 0) 465 if (dmfprintf(fp, "\n") < 0)
440 return dmferror(fp); 466 return dmferror(fp);
441 } 467 }
442 } 468 }
445 // Output each bitplane in sequence 471 // Output each bitplane in sequence
446 for (int plane = 0; plane < spec->nplanes; plane++) 472 for (int plane = 0; plane < spec->nplanes; plane++)
447 for (int yc = 0; yc < img->height; yc++) 473 for (int yc = 0; yc < img->height; yc++)
448 for (int yscale = 0; yscale < spec->scaleY; yscale++) 474 for (int yscale = 0; yscale < spec->scaleY; yscale++)
449 { 475 {
450 if (!dmWriteRAWRow(&bs, img, spec, yc, plane)) 476 if ((res = dmWriteRAWRow(&ctx, img, spec, yc, plane)) != DMERR_OK)
451 return DMERR_FWRITE; 477 return res;
452 478
453 if (dmfprintf(fp, "\n") < 0) 479 if (dmfprintf(fp, "\n") < 0)
454 return dmferror(fp); 480 return dmferror(fp);
455 } 481 }
456 } 482 }
457 483
458 res = dmFlushBitStream(&bs); 484 res = dmFlushBitStream(&ctx);
459 485
460 if (res == DMERR_OK && 486 if (res == DMERR_OK &&
461 dmfprintf(fp, "};\n") < 0) 487 dmfprintf(fp, "};\n") < 0)
462 res = dmferror(fp); 488 res = dmferror(fp);
463 489