Changeset f13f1495 in mainline


Ignore:
Timestamp:
2020-09-29T14:58:57Z (4 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
efe0881
Parents:
a81d480
git-author:
Jiri Svoboda <jiri@…> (2020-09-28 19:58:39)
git-committer:
Jiri Svoboda <jiri@…> (2020-09-29 14:58:57)
Message:

Bit pack font bitmap to 1 bit per pixel when saving to TPF file

Location:
uspace/lib/gfxfont
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/gfxfont/private/font.h

    ra81d480 rf13f1495  
    4040#include <adt/list.h>
    4141#include <errno.h>
     42#include <stdint.h>
    4243#include <types/gfx/bitmap.h>
    4344#include <types/gfx/context.h>
     
    9192    gfx_rect_t *);
    9293extern errno_t gfx_font_info_load(gfx_typeface_t *, riff_rchunk_t *);
     94extern errno_t gfx_font_bitmap_pack(gfx_coord_t, gfx_coord_t, uint32_t *,
     95    void **, size_t *);
     96extern errno_t gfx_font_bitmap_unpack(gfx_coord_t, gfx_coord_t, void *, size_t,
     97    uint32_t *);
    9398extern errno_t gfx_font_load(gfx_font_info_t *);
    9499extern errno_t gfx_font_save(gfx_font_info_t *, riffw_t *);
  • uspace/lib/gfxfont/src/font.c

    ra81d480 rf13f1495  
    519519}
    520520
     521/** Bit pack font bitmap into 1 bits/pixel format.
     522 *
     523 * @param width Bitmap width
     524 * @param height Bitmap height
     525 * @param pixels Bitmap pixels
     526 * @param rdata Place to store pointer to packed data
     527 * @param rsize Place to store size of packed data
     528 * @return EOK on sucess, ENOMEM if out of memory
     529 */
     530errno_t gfx_font_bitmap_pack(gfx_coord_t width, gfx_coord_t height,
     531    uint32_t *pixels, void **rdata, size_t *rsize)
     532{
     533        void *data;
     534        size_t size;
     535        size_t bytes_line;
     536        gfx_coord_t x, y;
     537        uint8_t b;
     538        uint8_t *dp;
     539        uint32_t *sp;
     540        uint32_t pix;
     541
     542        bytes_line = (width + 7) / 8;
     543        size = height * bytes_line;
     544
     545        data = malloc(size);
     546        if (data == NULL)
     547                return ENOMEM;
     548
     549        sp = pixels;
     550        dp = data;
     551        for (y = 0; y < height; y++) {
     552                b = 0;
     553                for (x = 0; x < width; x++) {
     554                        pix = *sp++;
     555                        b = (b << 1) | (pix & 1);
     556                        /* Write eight bits */
     557                        if ((x & 7) == 7) {
     558                                *dp++ = b;
     559                                b = 0;
     560                        }
     561                }
     562
     563                /* Write remaining bits */
     564                if ((x & 7) != 0) {
     565                        b = b << (8 - (x & 7));
     566                        *dp++ = b;
     567                }
     568        }
     569
     570        *rdata = data;
     571        *rsize = size;
     572        return EOK;
     573}
     574
     575/** Unpack font bitmap from 1 bits/pixel format.
     576 *
     577 * @param width Bitmap width
     578 * @param height Bitmap height
     579 * @param data Packed data
     580 * @param dsize Size of packed data
     581 * @param pixels Bitmap pixels
     582 * @return EOK on success, EINVAL if data size is invalid
     583 */
     584errno_t gfx_font_bitmap_unpack(gfx_coord_t width, gfx_coord_t height,
     585    void *data, size_t dsize, uint32_t *pixels)
     586{
     587        size_t size;
     588        size_t bytes_line;
     589        gfx_coord_t x, y;
     590        uint8_t b;
     591        uint8_t *sp;
     592        uint32_t *dp;
     593
     594        bytes_line = (width + 7) / 8;
     595        size = height * bytes_line;
     596
     597        if (dsize != size)
     598                return EINVAL;
     599
     600        sp = data;
     601        dp = pixels;
     602        for (y = 0; y < height; y++) {
     603                b = 0;
     604                for (x = 0; x < width; x++) {
     605                        if ((x & 7) == 0)
     606                                b = *sp++;
     607                        *dp++ = (b >> 7) ? PIXEL(255, 255, 255, 255) :
     608                            PIXEL(0, 0, 0, 0);
     609                        b = b << 1;
     610                }
     611        }
     612
     613        return EOK;
     614}
     615
    521616/** Load font bitmap from RIFF TPF file.
    522617 *
     
    537632        uint16_t fmt;
    538633        uint16_t depth;
     634        size_t bytes_line;
     635        void *data = NULL;
     636        size_t size;
    539637        size_t nread;
    540638
     
    552650        depth = uint16_t_le2host(thdr.depth);
    553651
    554         if (fmt != 0 || depth != 8 * sizeof(uint32_t)) {
     652        if (fmt != 0 || depth != 1) {
    555653                rc = ENOTSUP;
     654                goto error;
     655        }
     656
     657        bytes_line = (width + 7) / 8;
     658        size = height * bytes_line;
     659
     660        data = malloc(size);
     661        if (data == NULL) {
     662                rc = ENOMEM;
    556663                goto error;
    557664        }
     
    571678                goto error;
    572679
    573         rc = riff_read(&bmpck, (void *) alloc.pixels,
    574             width * height * sizeof(uint32_t), &nread);
    575         if (rc != EOK)
    576                 goto error;
    577 
    578         if (nread != width * height * sizeof(uint32_t)) {
     680        rc = riff_read(&bmpck, data, size, &nread);
     681        if (rc != EOK)
     682                goto error;
     683
     684        if (nread != size) {
    579685                rc = EIO;
    580686                goto error;
     
    585691                goto error;
    586692
     693        rc = gfx_font_bitmap_unpack(width, height, data, size, alloc.pixels);
     694        if (rc != EOK)
     695                goto error;
     696
     697        free(data);
    587698        gfx_bitmap_destroy(font->bitmap);
    588699        font->bitmap = bitmap;
     
    590701        return EOK;
    591702error:
     703        if (data != NULL)
     704                free(data);
    592705        if (bitmap != NULL)
    593706                gfx_bitmap_destroy(bitmap);
     
    607720        riff_wchunk_t bmpck;
    608721        gfx_bitmap_alloc_t alloc;
     722        void *data = NULL;
     723        size_t dsize;
     724
     725        rc = gfx_bitmap_get_alloc(font->bitmap, &alloc);
     726        if (rc != EOK)
     727                return rc;
     728
     729        rc = gfx_font_bitmap_pack(font->rect.p1.x, font->rect.p1.y,
     730            alloc.pixels, &data, &dsize);
     731        if (rc != EOK)
     732                return rc;
    609733
    610734        thdr.width = host2uint32_t_le(font->rect.p1.x);
    611735        thdr.height = host2uint32_t_le(font->rect.p1.y);
    612736        thdr.fmt = 0;
    613         thdr.depth = host2uint16_t_le(8 * sizeof(uint32_t));
    614 
    615         rc = gfx_bitmap_get_alloc(font->bitmap, &alloc);
    616         if (rc != EOK)
    617                 return rc;
     737        thdr.depth = host2uint16_t_le(1);
    618738
    619739        rc = riff_wchunk_start(riffw, CKID_fbmp, &bmpck);
    620740        if (rc != EOK)
    621                 return rc;
     741                goto error;
    622742
    623743        rc = riff_write(riffw, &thdr, sizeof(thdr));
    624744        if (rc != EOK)
    625                 return rc;
    626 
    627         rc = riff_write(riffw, (void *) alloc.pixels,
    628             font->rect.p1.x * font->rect.p1.y * sizeof(uint32_t));
    629         if (rc != EOK)
    630                 return rc;
     745                goto error;
     746
     747        rc = riff_write(riffw, data, dsize);
     748        if (rc != EOK)
     749                goto error;
    631750
    632751        rc = riff_wchunk_end(riffw, &bmpck);
    633752        if (rc != EOK)
    634                 return rc;
    635 
    636         return EOK;
     753                goto error;
     754
     755        free(data);
     756        return EOK;
     757error:
     758        if (data != NULL)
     759                free(data);
     760        return rc;
    637761}
    638762
  • uspace/lib/gfxfont/test/font.c

    ra81d480 rf13f1495  
    366366}
    367367
     368/** Test gfx_font_bitmap_pack() properly packs bitmap */
     369PCUT_TEST(bitmap_pack)
     370{
     371        errno_t rc;
     372        gfx_coord_t width, height;
     373        gfx_coord_t i;
     374        uint32_t *pixels;
     375        void *data;
     376        size_t size;
     377        uint8_t *dp;
     378
     379        width = 10;
     380        height = 10;
     381
     382        pixels = calloc(sizeof(uint32_t), width * height);
     383        PCUT_ASSERT_NOT_NULL(pixels);
     384
     385        for (i = 0; i < 10; i++)
     386                pixels[i * width + i] = PIXEL(255, 255, 255, 255);
     387
     388        rc = gfx_font_bitmap_pack(width, height, pixels, &data, &size);
     389        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     390        PCUT_ASSERT_NOT_NULL(data);
     391        PCUT_ASSERT_INT_EQUALS(20, size);
     392
     393        dp = data;
     394
     395        for (i = 0; i < 8; i++) {
     396                PCUT_ASSERT_INT_EQUALS(0x80 >> i, dp[2 * i]);
     397                PCUT_ASSERT_INT_EQUALS(0, dp[2 * i + 1]);
     398        }
     399
     400        for (i = 8; i < 10; i++) {
     401                PCUT_ASSERT_INT_EQUALS(0, dp[2 * i]);
     402                PCUT_ASSERT_INT_EQUALS(0x80 >> (i - 8), dp[2 * i + 1]);
     403        }
     404}
     405
     406/** Test gfx_font_bitmap_unpack() properly unpacks bitmap */
     407PCUT_TEST(bitmap_unpack)
     408{
     409        errno_t rc;
     410        gfx_coord_t width, height;
     411        gfx_coord_t i, j;
     412        uint32_t epix;
     413        uint32_t *pixels;
     414        uint8_t data[20];
     415
     416        width = 10;
     417        height = 10;
     418
     419        for (i = 0; i < 8; i++) {
     420                data[2 * i] = 0x80 >> i;
     421                data[2 * i + 1] = 0;
     422        }
     423
     424        for (i = 8; i < 10; i++) {
     425                data[2 * i] = 0;
     426                data[2 * i + 1] = 0x80 >> (i - 8);
     427        }
     428
     429        pixels = calloc(sizeof(uint32_t), width * height);
     430        PCUT_ASSERT_NOT_NULL(pixels);
     431
     432        rc = gfx_font_bitmap_unpack(width, height, data, sizeof(data),
     433            pixels);
     434        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     435
     436        for (j = 0; j < 10; j++) {
     437                for (i = 0; i < 10; i++) {
     438                        epix = (i == j) ? PIXEL(255, 255, 255, 255) :
     439                            PIXEL(0, 0, 0, 0);
     440                        PCUT_ASSERT_INT_EQUALS(epix, pixels[j * width + i]);
     441                }
     442        }
     443}
     444
    368445static errno_t testgc_set_color(void *arg, gfx_color_t *color)
    369446{
Note: See TracChangeset for help on using the changeset viewer.