source: trunk/core/bitvector.c @ 928

Revision 928, 4.5 KB checked in by fe50, 3 years ago (diff)

New edge overlay, rewritten zebra, SX20 stuff

Note:

  • some of this (edge overlay, zebra) affects ALL cameras !
  • since there are changes in the CHDK configuration, it's recommended to use a new config file (i.e. to rename/delete the cchdk.cfg file)

The SX20 1.02D now is enabled in the main makefile for the autobuild server

RevLine 
[928]1#include "bitvector.h"
2#include <stddef.h>
3#include <stdlib.h>
4
5bit_vector_t* bv_create(int len, int nbits)
6{
7    bit_vector_t* bm = (bit_vector_t*)malloc(sizeof(bit_vector_t));
8    if (bm == NULL)
9        return NULL;
10
11    bm->ptrLen = len * nbits / 8 + 1;
12    bm->nElem = len;
13    bm->nBits = nbits;
14    bm->ptr = malloc(bm->ptrLen);
15    if (bm->ptr == NULL)
16    {
17        free(bm);
18        return NULL;
19    }
20
21    return bm;
22}
23
24// Utility function. Use bv_set instead.
25static inline void bv_setbit(bit_vector_t* bm, int pos, int val)
26{
27    int bp = pos - ((pos >> 3) << 3);
28    if (val == 0)
29        bm->ptr[pos >> 3] &= ~(1 << bp);
30    else
31        bm->ptr[pos >> 3] |=  (1 << bp);
32
33// Following ASM code is bad. It crashes the camera, but why?
34// It'd be very nice to replace this function with an inline
35// assembly macro in the future (the same for bv_getbit()).
36// The compiler seems to generate suboptimal ASM for me,
37// but this is performance critical code.
38//
39//    char t = bm->ptr[pos >> 3];
40//    asm volatile (
41//                 ".syntax unified\n"
42//                 "MOV     %[pos], %[pos], lsr #3\n"           // r1 = pos >> 3
43//                 "SUB     %[pos], %[pos], %[pos], lsl #3\n"        // pos -= pos<<3
44//                 "MOV     r2, #1\n"                    // r2 = 1
45//                 "MOV     r2, r2, lsl %[pos]\n"         // r2 <<= pos
46//                 "CMP     %[val], #0\n"                    // val == 0
47//                 "ITE     EQ\n"                             // if
48//                 "BICEQ     %[t], %[t], r2\n"        // &= ~(1 << bp)
49//                 "ORRNE     %[t], %[t], r2\n"      // |=  (1 << bp)
50//                 ".syntax divided"
51//                 : [t]"+r"(t)
52//                 : [val]"r"(val), [pos]"r"(pos)
53//                 : "r2", "cc"
54//                 );
55//    bm->ptr[pos >> 3] = t;
56
57}
58
59// Utility function. Use bv_get instead.
60static inline int bv_getbit(bit_vector_t* bm, int pos)
61{
62    // Note: bv_get() and other code rely on this
63    // method returning '1' if the bit is set.
64    // If you are interested only in the truth value,
65    // you can use bv_testbit().
66
67    int bp = pos - ((pos >> 3) << 3);
68    return ((bm->ptr[pos >> 3] & (1 << bp)) > 0) ? 1 : 0;
69}
70
71void bv_set(bit_vector_t* bm, int pos, int val)
72{
73    int i;
74    int bitpos = pos * bm->nBits;
75    for (i = 0; i < bm->nBits; ++i)
76    {
77        bv_setbit(bm, bitpos + i, val & (1<<i));
78    }
79}
80
81// Same as bv_set, but sets val to two consecutive elements
82// instead of just one.
83void bv_set2(bit_vector_t* bm, int pos, int val)
84{
85    int i;
86    int bitpos = pos * bm->nBits;
87    for (i = 0; i < bm->nBits; ++i)
88    {
89        int t = val & (1<<i);
90        bv_setbit(bm, bitpos + i, t);
91        bv_setbit(bm, bitpos + i + bm->nBits, t);
92    }
93}
94
95// Same as bv_set, but sets val to four consecutive elements
96// instead of just one.
97void bv_set4(bit_vector_t* bm, int pos, int val)
98{
99    int i;
100    int bitpos = pos * bm->nBits;
101    for (i = 0; i < bm->nBits; ++i)
102    {
103        int t = val & (1 << i);
104        bv_setbit(bm, bitpos + i, t);
105        bv_setbit(bm, bitpos + i + bm->nBits, t);
106        bv_setbit(bm, bitpos + i + bm->nBits * 2, t);
107        bv_setbit(bm, bitpos + i + bm->nBits * 3, t);
108    }
109}
110
111int bv_get(bit_vector_t* bm, int pos)
112{
113    int i;
114    int ret = 0;
115    int bitpos = pos * bm->nBits;
116    for (i = 0; i < bm->nBits; ++i)
117    {
118        ret |= (bv_getbit(bm, bitpos + i) << i);
119    }
120
121    return ret;
122}
123
124
125void bv_free(bit_vector_t* bm)
126{
127    if (bm)
128    {
129        if (bm->ptr)
130        {
131            free(bm->ptr);
132            bm->ptr = NULL;
133        }
134
135        free(bm);
136    }
137}
138
139/*
140// Utility function. Not sure what for, but might
141// be useful in the future.
142static int bv_testbit(bit_vector_t* bm, int pos)
143{
144    int bp = pos - ((pos >> 3) << 3);
145    return bm->ptr[pos >> 3] & (1 << bp);
146}
147
148
149// This method is designed to be used for blitting the contents of the
150// bit_vector into the framebuffer. The value of each element is used to
151// look up a color value based on the lookup-table (last parameter).
152// Not used currently. Never will be probably.
153static void bv_expand(bit_vector_t* bm, unsigned char* dst, int len, color* lookup)
154{
155    int i;
156    int k;
157
158    for (i = 0; i < len; ++i)
159    {
160        int elem = 0;
161        int bitpos = i * bm->nBits;
162        for (k = 0; k < bm->nBits; ++k)
163        {
164            int pos = bitpos + k;
165            int bp = pos - ((pos >> 3) << 3);
166            if (bm->ptr[pos >> 3] & (1 << bp))
167                elem |= (1 << k);
168        }
169        dst[i] = lookup[elem];
170        dst[i+screen_buffer_size] = lookup[elem];
171    }
172}
173*/
Note: See TracBrowser for help on using the repository browser.