aboutsummaryrefslogtreecommitdiff
path: root/lpg/libqr/qr-bitmap.c
blob: 1a5ca52ca7f62bf856b95b4f5ab4d364a27064d7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include <assert.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include "qr-bitmap.h"

struct qr_bitmap * qr_bitmap_create(int width, int height, int masked)
{
        struct qr_bitmap * out;
        size_t size;

        out = malloc(sizeof(*out));
        if (!out)
                goto fail;

        out->width = width;
        out->height = height;
        out->stride = (width / CHAR_BIT) + (width % CHAR_BIT ? 1 : 0);

        size = out->stride * height;

        out->mask = 0;
        out->bits = malloc(size);
        if (!out->bits)
                goto fail;
        memset(out->bits, 0, size);

        if (masked) {
                out->mask = malloc(out->stride * width);
                if (!out->mask)
                        goto fail;
                memset(out->bits, 0xFF, size);
        }

        return out;

fail:
        qr_bitmap_destroy(out);
        return 0;
}

void qr_bitmap_destroy(struct qr_bitmap * bmp)
{
        if (bmp) {
                free(bmp->bits);
                free(bmp->mask);
                free(bmp);
        }
}

struct qr_bitmap * qr_bitmap_clone(const struct qr_bitmap * src)
{
        struct qr_bitmap * bmp;
        size_t size;

        bmp = qr_bitmap_create(src->width, src->height, !!src->mask);
        if (!bmp)
                return 0;

        assert(bmp->stride == src->stride);

        size = bmp->width * bmp->stride;
        memcpy(bmp->bits, src->bits, size);
        if (bmp->mask)
                memcpy(bmp->mask, src->mask, size);

        return bmp;
}

void qr_bitmap_merge(struct qr_bitmap * dest, const struct qr_bitmap * src)
{
        unsigned char * d, * s, * m;
        size_t n;

        assert(dest->stride == src->stride);
        assert(dest->height == src->height);
        assert(src->mask);

        n = dest->stride * dest->height;
        d = dest->bits;
        s = src->bits;
        m = src->mask;

        while (n--) {
                *d   &= ~*m;
                *d++ |= *s++ & *m++;
        }
}