воскресенье, 2 февраля 2014 г.
Dithering algorithm implemented for IMSH
Today I implemented Dithering algorithms for IMSH (IMage SHell) - see Project WiKi - Dithering. They are: general purpose (see matrixes in imsh.scm library) and special purpose: Atkinson, Floyd-Steinberg, Ordered, Random, General Sierra, General Sierra Two Rows, General Sierra Low, General Floyd-Steinberg, General False Floyd-Steinberg, General Jarvis, General Stucki, General Atkinson, General Burkes.
суббота, 21 декабря 2013 г.
Thread-Safe Circular Queue
Often in data processing applications are needed circular queue implemented in thread-safe way. This is the such implementation without any mutex, locks and so on:
/**
* @file cqueue.h
* @defgroup cqueue Circular queue support
* @{
* @brief Fast circular queue support
*/
#ifndef _CQUEUE_H
#define _CQUEUE_H
/** It's possible to use another (wrapper) structure or structure with another
name for cqueue implementation. CQUEUE_STRUCT_IMPL should be defined as name
of such structure in this case before to include cqueue.h. This structure
must have members:
- unsigned integer "size"
- integer "rpos"
- integer "wpos"
- integer "rwrap"
- integer "wwrap"
- any other custom fields
*/
#ifdef CQUEUE_STRUCT_IMPL
typedef CQUEUE_STRUCT_IMPL cqueue_t;
#else
/// Circular queue
typedef struct cqueue_t {
/// Capacity of queue
unsigned int size;
/// Reader position
int rpos;
/// Writer position
int wpos;
/// Reader wrapping flag
unsigned char rwrap;
/// Writer wrapping flag
unsigned char wwrap;
} cqueue_t;
#endif
/** Initializer for circular queue structure instance. Additional args are
needs if separate implementation struct is used */
#define CQUEUE_INITIALIZER(SIZE, ...) { \
.size = (SIZE), \
.rpos = 0, \
.wpos = 0, \
.wwrap = 0, \
.rwrap = 0, \
__VA_ARGS__ }
/// Init. function for queue structure instance
#define CQUEUE_INIT(Q, SIZE) do { \
(Q)->size = (SIZE); \
(Q)->rpos = (Q)->wpos = 0; \
(Q)->wwrap = (Q)->rwrap = 0; \
} while (0)
/// Reset circular queue into initial state
#define CQUEUE_RESET(Q) CQUEUE_INIT(Q, (Q)->size)
/// General position incrementing
#define CQUEUE_INCR(Q, PPOS, PWRAP) do { \
*(PPOS) = *(PPOS) +1; \
if (*(PPOS) == (Q)->size) { \
*(PWRAP) ^= 1; \
*(PPOS) = 0; \
} \
} while (0)
/// Reader position (for user-side)
#define CQUEUE_RPOS(Q) ((Q)->rpos)
/// Writer position (for user-side)
#define CQUEUE_WPOS(Q) ((Q)->wpos)
/// Reader position incrementing
#define CQUEUE_INCR_R(Q) do { \
CQUEUE_INCR(Q, &((Q)->rpos), &((Q)->rwrap)); \
} while (0)
/// Writer position incrementing
#define CQUEUE_INCR_W(Q) do { \
CQUEUE_INCR(Q, &((Q)->wpos), &((Q)->wwrap)); \
} while (0)
/// Test of circular queue fullness
#define CQUEUE_IS_FULL(Q) \
((Q)->wpos == (Q)->rpos && (Q)->rwrap != (Q)->wwrap)
/// Test of circular queue emptiness
#define CQUEUE_IS_EMPTY(Q) \
((Q)->wpos == (Q)->rpos && (Q)->rwrap == (Q)->wwrap)
/// Number of free slots in circular queue
#define CQUEUE_NFREE(Q) \
((Q)->rwrap == (Q)->wwrap ? \
((Q)->size - (Q)->wpos + (Q)->rpos) : \
((Q)->rpos - (Q)->wpos))
/// Number of used slots in circular queue
#define CQUEUE_LEN(Q) \
((Q)->rwrap != (Q)->wwrap ? \
((Q)->size - (Q)->rpos + (Q)->wpos) : \
((Q)->wpos - (Q)->rpos))
#endif
/// @}
USe doxygen to gen documentation of this module (it's only one .h-file).
суббота, 2 ноября 2013 г.
Portable effective C bit fields
As you know bit's fields in C are not portable when we're talking about external world (network/different architecture/file transmission): order of the fields is unspecified, also as real wrapper struct...
Often bitwise operations are used instead of bitfield struct syntax but result code may be less readable opposite to original idea: bitfields. But there is simple solution to workaround weird syntax. Here you are:
But note the *_IMPL macros, using they, you can customize behavior of SET/GET implementation, for example to use some DSP core what can improve program performance dramatically! What you need is only to define own GET/SET helpers-implementators (BITSTRUCT_GETBITS_IMPL/BITSTRUCT_SETBITS_IMPL).
Often bitwise operations are used instead of bitfield struct syntax but result code may be less readable opposite to original idea: bitfields. But there is simple solution to workaround weird syntax. Here you are:
#define __BITSTRUCT_MASK(LEN) ((1<<(LEN))-1)
#ifndef BITSTRUCT_GETBITS_IMPL
# define BITSTRUCT_GETBITS_IMPL(BS, OFFSET, LEN) \
(((BS)>>(OFFSET)) & __BITSTRUCT_MASK(LEN))
#endif
#ifndef BITSTRUCT_SETBITS_IMPL
# define BITSTRUCT_SETBITS_IMPL(BS, OFFSET, LEN, VALUE) \
((BS) & ~(__BITSTRUCT_MASK(LEN)<<(OFFSET)) | \
(((VALUE) & __BITSTRUCT_MASK(LEN))<<(OFFSET)))
#endif
#define BITSTRUCT enum
#define BITFIELD(NAME, OFFSET, LEN) NAME##_OFF = (OFFSET), NAME##_LEN=(LEN)
#define BITFIELD_MASK(NAME) __BITSTRUCT_MASK(NAME##_LEN)
#define BITFIELD_GET(NAME, BS) \
BITSTRUCT_GETBITS_IMPL(BS, NAME##_OFF, NAME##_LEN)
#define BITFIELD_SET(NAME, BS, VALUE) \
BITSTRUCT_SETBITS_IMPL(BS, NAME##_OFF, NAME##_LEN, VALUE)
So now it's possible to write something like this to describe register X:
|15.....8|7....4|3.....0| | ENABLE | FLAG | COUNT |
BITSTRUCT RegisterX {
// BITFIELD(NAME, OFFSET, LENGTH)
BITFIELD(RX_COUNT, 0, 4),
BITFIELD(RX_FLAG, 4, 4),
BITFIELD(RX_ENABLE, 8, 8)
};
int main(void)
{
int x = 0x1234; // raw value of register
// example of get/set field of bits' struct
x = BITFIELD_SET(RX_ENABLE, x, 0x98);
printf("%0X", BITFIELD_GET(RX_ENABLE, x));
return (0);
}
As you can see code is readable as in usual bitfield's struct, but instead of struct BITSTRUCT should be used,
and BITFIELD() descriptor instead of type NAME:len form. To set or to get field value, use BITFIELD_SET/GET() macros. BITFIELD_MASK() returns mask of field but from zero bit.But note the *_IMPL macros, using they, you can customize behavior of SET/GET implementation, for example to use some DSP core what can improve program performance dramatically! What you need is only to define own GET/SET helpers-implementators (BITSTRUCT_GETBITS_IMPL/BITSTRUCT_SETBITS_IMPL).
суббота, 19 октября 2013 г.
Scala joke :)
See the Scala joke:
scala> 5 plus 5 I don't know... this possible with implicits, sure:
scala> implicit class Joke(x:Int) {
| def plus(y:Int) = { println("I don't know") }
| }
defined class Joke
But why Scala is so sexy? :)
Подписаться на:
Сообщения (Atom)