Mercurial > hg > dmlib
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 |