CvLoadImage function and lists - c

I am using CvLoadImage (in C programming language).
Instead of passing the path or the name of my, let's say, .jpg file as the argument of the function, can I use a list (dynamic structure) which has every path of every .jpg image I want to open?
For example, I have thought the code to be like this:
CvLoadImage(list->name)
having a list declared with all the paths of the names.
instead of being like this: CvLoadImage("name.jpg")
In every manual I read, it just specified the function receives the name or the path of one image, but I want to recursively open one image after the other with those paths coming from a list, and I don't know how to do it.
This is what I could do (some things are in spanish, because we speak spanish, and some other things are mixed with files)
struct fotos
{
char nom[30];
struct fotos *sig;
};
//....
struct fotos *lini;
//....
while(lini->sig!=0)
{
image=cvLoadImage(lini->nom,1);
cvNamedWindow("ejemplo", 0);
cvMoveWindow("ejemplo", 100, 100);
cvShowImage("ejemplo", image);
cvWaitKey(0);
lini=lini->sig;
}
image=cvLoadImage(lini->nom,1);
cvNamedWindow("ejemplo", 0);
cvMoveWindow("ejemplo", 100, 100);
cvShowImage("ejemplo", image);
cvWaitKey(0);
cvReleaseImage(&image);
But it won't work either. It creates a new window, but no image is loaded.

I've not used CvLoadImage() myself, but a quick google search shows that it has a prototype of the form:
IplImage* cvLoadImage( const char* filename, int iscolor=CV_LOAD_IMAGE_COLOR );
The function is clearly designed to take one, and only one filename. It loads the file into memory and returns a pointer to the location into which it loaded it, or NULL for error.
If you want to load multiple files, you'll need to call the function repeatedly, one for each file. One thing you might consider is to set up an array of pointers to char:
void load_images(void)
{
int i; /* Used for looping */
/* Array of filenames */
char *filenames[4] = {
"/path/to/image0.jpg",
"/path/to/image1.jpg",
"/path/to/image2.jpg",
"/path/to/image3.jpg",
};
/* Array to store the addresses of the loaded files */
IplImage *file_addresses[4];
for (i = 0; i < 4; i++) {
file_addresses[i] = cvLoadImage(filenames[i], CV_LOAD_IMAGE_COLOR);
}
/* The address of image number N, where N starts at zero
is now in file_addresses[N]. Don't forget to check that
any given address is not NULL before you use it, in case
there was a loading error */
}
You can easily substitute the arrays for a linked list or any other data structure you like. You can also modify the function to receive a pointer to a list to populate, or return a pointer to a new list it created, etc.

What you basically have should be of the form
class list
{
element* begin;
} MyList;
class element
{
char name[200];
element* next;
};
// and you can iterate through the list like that:
for (element* it = MyList->begin; it != NULL; it = it->next)
{
IplImage* img = cvLoadImage(it->name);
doSomethingElseOn(img);
}

Related

Reading structure tags from a header file?

So I wanted to configure different structures for which I have a header file such as:
header.h
typedef struct
{
uint32_t hola;
uint32_t adios;
}Signal_t;
typedef struct
{
bool goodbye;
uint32_t hello;
} FrameTx_t;
In order to do so, at some point, within my source code, I will need to detect which kind of structure is to be configured by the received text.
id. est: If I have a JSON file that goes somewhere along:
JSON_File.txt
{"Signal_t" :
{
"hola" : 1024,
"adios" : 555555
}
}
I need to recognize that the to-be-configured structure is of type Signal_t.
For now I have developed a simple code in which, after parsing the text, I can obtain the name of the structure in a string format, and then I created the following function to determine which structure is to be configured:
Code.c
int structure_Select(char* structName, int sizeOfStructName) {
char Signal_tName[] = "Signal_t";
char FrameTx_tName[] = "FrameTx_t";
int idx=0;
if ((sizeof(Signal_tName) - 1) == sizeOfStructName) {
for (idx = 0;idx < sizeOfStructName;idx++) {
if (Signal_tName[idx] != structName[idx]) {
break;
}
}
if (idx == sizeOfStructName) {
printf("%s", Signal_tName);
return 0;
}
}
if ((sizeof(FrameTx_tName) - 1) == sizeOfStructName) {
for (idx = 0;idx < sizeOfStructName;idx++) {
if (FrameTx_tName[idx] != structName[idx]) {
break;
}
}
if (idx == sizeOfStructName) {
printf("%s", FrameTx_tName);
return 1;
}
}
}
I can assure you it works; it just does not go as "automatic" as I would like it to be...
I would like for the program to be able to read the header file and automatically recognize: "Oh okay, so I'm dealing with a Signal_t data type, I'm gonna then read two different data from the stream and assign data1 to Signal_t.hola and data2 to Signal_t.adios"
The assignation is clearly not a problem; only determining from an existing structure within a file the name of it or a way to differentiate between structs.
So far I've thought about the following possibilities outside of what I already have, but I'm cycled within it:
o Create a mini "C-structure parser" function
o Is there ANY way to get the name of a structure tag within C that I don't know of?
I'm open to suggestions, whether it's just ideas that I could work on and I'm not seeing or if any of you has dealed with a similar issue in the past and instead of using a list of char variables, actually reads the header file for the structure names... thanks in advance!
.
.
.
TL;DR: Is there any way to read structures' tags from a header file as a string?
Edit: This is what I mean with structure tag/type alias:
//structure to get a rectangle
typedef struct {
int left;
int bottom;
int right;
int top;
} rect_t; //this rect_t is what I mean by structure tag...
//I checked the name and it should be type alias***

Problems iterating through AddressOfNames member of IMAGE_EXPORT_DIRECTORY structure

I'm having problems enumerating function names in kernel32.dll. I retrieved its IMAGE_EXPORT_DIRECTORY structure and stored an array of pointers to char arrays of each function name: char** name_table = (char**)(image+pExp_dir->AddressOfNames); //pExp_dir is a pointer to the IMAGE_EXPORT_DIRECTORY structure. I'm now trying to iterate through the function names and match them to a string containing the name of the function whom's RVA I need.
for(int i=0;i<pExp_dir->NumberOfNames;i++) //until i is 1 less than how many names there are to iterate through elements
{
printf("%s ", (char*)(image+(DWORD)(uintptr_t)name_table[i])); //print the name of each function iterated through, I went back and read through these names and didn't see GetProcAddress anywhere
if(proc_name == image+(DWORD)(uintptr_t)name_table[i]) //if(strcmp(proc_name, (const char*)image+(DWORD)(intptr_t)name_table[i]) == 0) //Is it the function we're looking for?
{
address = (DWORD)(uintptr_t)func_table[ord_table[i]];//If so convert the address of the function into a DWORD(hexadecimal)
system("pause");
system("CLS"); //Clear the screen
return address; //return the address of the function
}
But if it doesn't find the function then the program crashes. And after looking in the memory dump in the DBG debugger I can see that name_tables contains all of the function names including the function I'm looking for but my program seems to skip several elements even though I'm iterating through its elements one at a time. User stijn suggested that I shouldn't use intptr_t to cast char* to DWORD to use for pointer arithmetic. So my question is really about the correct way to iterate through name_table because it seems as if this is a pointer arithmetic problem. Here's the function to get the file image and the function that actually gets the RVA:
void* GetFileImage(char path[]) //Get maps the image of the file into memory and returns the beginning virtual address of the file in memory
{
HANDLE hFile = CreateFile(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);//Get a handle to the dll with read rights
if(hFile == INVALID_HANDLE_VALUE){printf("Error getting file handle: %d", (int)GetLastError());return NULL;} //Check whether or not CreateFile succeeded
HANDLE file_map = CreateFileMapping(hFile, NULL, PAGE_READONLY|SEC_IMAGE, 0, 0, "KernelMap"); //Create file map
if(file_map == INVALID_HANDLE_VALUE){printf("Error mapping file: %d", (int)GetLastError());return NULL;} //Did it succeed
LPVOID file_image = MapViewOfFile(file_map, FILE_MAP_READ, 0, 0, 0); //Map it into the virtual address space of my program
if(file_image == 0){printf("Error getting mapped view: %d", (int)GetLastError());return NULL;} //Did it succeed
return file_image; //return the base address of the image
}
DWORD RVAddress(char* image, const char* proc_name) //Gets the relative virtual address of the function and returns a DWORD to be cast to void*.
{
DWORD address = 0xFFFFFFFF;
PIMAGE_DOS_HEADER pDos_hdr = (PIMAGE_DOS_HEADER)image; //Get dos header
PIMAGE_NT_HEADERS pNt_hdr = (PIMAGE_NT_HEADERS)(image+pDos_hdr->e_lfanew); //Get PE header by using the offset in dos header + the base address of the file image
IMAGE_OPTIONAL_HEADER opt_hdr = pNt_hdr->OptionalHeader; //Get the optional header
IMAGE_DATA_DIRECTORY exp_entry = opt_hdr.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
PIMAGE_EXPORT_DIRECTORY pExp_dir = (PIMAGE_EXPORT_DIRECTORY)(image+exp_entry.VirtualAddress); //Get a pointer to the export directory
void** func_table = (void**)(image+pExp_dir->AddressOfFunctions); //Get an array of pointers to the functions
WORD* ord_table = (WORD*)(image+pExp_dir->AddressOfNameOrdinals); //Get an array of ordinals
char** name_table = (char**)(image+pExp_dir->AddressOfNames); //Get an array of function names
for(int i=0;i<pExp_dir->NumberOfNames;i++) //until i is 1 less than how many names there are to iterate through elements
{
printf("%s ", (char*)(image+(DWORD)(uintptr_t)name_table[i])); //print the name of each function iterated through, I went back and read through these names and didn't see GetProcAddress anywhere
if(proc_name == image+(DWORD)(uintptr_t)name_table[i]) //if(strcmp(proc_name, (const char*)image+(DWORD)(intptr_t)name_table[i]) == 0) //Is it the function we're looking for?
{
address = (DWORD)(uintptr_t)func_table[ord_table[i]];//If so convert the address of the function into a DWORD(hexadecimal)
system("pause");
system("CLS"); //Clear the screen
return address; //return the address of the function
}
}
return (DWORD)0; //Other wise return 0
}
Any help would be much appreciated!
Docs (Section 6.3) say next about AddressOfNames table
The Export Name Pointer Table is an array of addresses (RVAs) into the
Export Name Table. The pointers are 32 bits each and are relative to
the Image Base. The pointers are ordered lexically to allow binary
searches.
And about AddressOfFunctions:
Each entry in the Export Address Table is a field that uses one of two
formats, ... If the address specified is not within the export section
(as defined by the address and length indicated in the Optional
Header), the field is an Export RVA: an actual address in code or
data. Otherwise, the field is a Forwarder RVA, which names a symbol in
another DLL.
Your variables is not void** and char**, but actually all are DWORD* because these tables hold RVA. Try next code:
DWORD* func_table = (DWORD*)(image+pExp_dir->AddressOfFunctions); //Get an array of pointers to the functions
WORD* ord_table = (WORD*)(image+pExp_dir->AddressOfNameOrdinals); //Get an array of ordinals
DWORD* name_table = (DWORD*)(image+pExp_dir->AddressOfNames); //Get an array of function names
for(int i=0;i<pExp_dir->NumberOfNames;i++) //until i is 1 less than how many names there are to iterate through elements
{
printf("%s ", (char*)(image+name_table[i])); //print the name of each function iterated through, I went back and read through these names and didn't see GetProcAddress anywhere
if(strcmp(proc_name, (const char*)(image+name_table[i])) == 0) //Is it the function we're looking for?
{
// TODO should we distinguish between normal and forwarded exports?
WORD ordinal_base = 1; // TODO read it from export directory
address = func_table[ord_table[i] - ordinal_base];//If so convert the address of the function into a DWORD(hexadecimal)
system("pause");
system("CLS"); //Clear the screen
return address; //return the address of the function
}
}
So when your code runs on 32-bit machine it should work regardless of the incorrect var types, but if you are on 64-bit - pointers are twice longer than DWORD and it will skip odd entries in tables and goes out of array bound, that may cause crash.
P.S. Name table is ordered, so you can use binary search.

C Programming - fprintf and printf in while cicle doesn't work

I'm getting a strange problem with a while cicle inside of a function.
I have to look for the extreme vertices of a .ply model. All the data is stored in a linked list. When I'm done creating the list, I call the findExtremeVertex function, that modifies 6 global variables (leftVertex, rightVertex, downwardVertex, upwardVertex, backVertex and frontVertex).
To see if the values are right (the models I use are a bit too big to control every single line to find the maximum of every vertex) I decided to print every change in the max-min values but, when I try to print them in a file, the file is empty. Why is that? Also, when I saw that the file was empty, I tried to print something directly in the console but that didn't work either.
Here's the code of the funcion:
void findExtremeVertex(Vertex *vertex){
FILE *modelInfoFile;
int i = 0;
///Giving data to direction-vertices pointers
leftVertex = malloc(sizeof(Vertex));
rightVertex = malloc(sizeof(Vertex));
upwardVertex = malloc(sizeof(Vertex));
downwardVertex = malloc(sizeof(Vertex));
frontVertex = malloc(sizeof(Vertex));
backVertex = malloc(sizeof(Vertex));
///Giving the direction-vertices the values of the parameter
leftVertex = vertex;
rightVertex = vertex;
upwardVertex = vertex;
downwardVertex = vertex;
frontVertex = vertex;
backVertex = vertex;
///Opening file
modelInfoFile = fopen(us2, "w");
if(modelInfoFile == NULL){
printf("Error in file opening. Exiting.");
exit(EXIT_FAILURE);
}
///Scrolling the list
while(vertex->prev != NULL){
vertex = vertex->prev;
///If the given element of the list is more to the right than the global variable,
///I assign the values of the element to the global variable
if(vertex->vertexCoordinates.x > rightVertex->vertexCoordinates.x){
rightVertex = vertex;
}
/**
I'm omitting the other if constructs because are basically
the same, but the syntax is correct
**/
///Printing in file the cycle information
fprintf(modelInfoFile, "********** CYCLE %d **********\n\n", i);
fprintf(modelInfoFile, "Vertex sx\n");
fprintf(modelInfoFile, "%1.4f %1.4f %1.4f %1.4f %1.4f %1.4f\n\n", leftVertex->vertexCoordinates.x,
leftVertex->vertexCoordinates.y,
leftVertex->vertexCoordinates.z,
leftVertex->vertexNormals.x,
leftVertex->vertexNormals.y,
leftVertex->vertexNormals.z);
/**
Again, I'm omitting some repetitions but the syntax is correct
**/
}
}
I call this function in another function, but there's no segmentation fault signal, the compiler doesn't tell me anything, the program doesn't crash. I have no clue of the error, except from the fact that the file where I print the infos about the cycles is empty. What am I doing wrong?
There are many problems in your code.
You malloc() 6 variables and never use any of them, and you don't check if malloc() succeeded.
You never call fclose() or fflush() so maybe you are seeing the file before the data is flushed to the disk.
You reassign all the *Vertex (except for rightVertex) variables after they are malloc()ed to the same pointer vertex which means
You are causing a memory leak.
You are using 6 variables for a single pointer.
All the *Vertex variables are not declared inside the function which means that they are in the global scope, that is very likely a bad design choice. Given the code you posted it's not possible to tell whether or not global variables are the right choice, but 99% of the time they are a bad choice and there is a much more elegant and safe way to do things.
The bold point above is likely the reason why your program is behaving as it is.
The code
leftVertex = vertex;
rightVertex = vertex;
upwardVertex = vertex;
downwardVertex = vertex;
frontVertex = vertex;
backVertex = vertex;
sets the pointer value but not the actual value. You malloc space, get a pointer to that space, and then throw that pointer away setting it to the pointer of virtex.
Do you mean to use
*leftVertex = *vertex;
*rightVertex = *vertex;
*upwardVertex = *vertex;
*downwardVertex = *vertex;
*frontVertex = *vertex;
*backVertex = *vertex;
///Scrolling the list
while(vertex->prev != NULL){
vertex = vertex->prev;
And what happens if vertex is NULL after this?
You're checking if it's NULL, then changing it's value such that it can become NULL.
///Opening file
if(modelInfoFile == NULL){
printf("Error in file opening. Exiting.");
exit(EXIT_FAILURE);
}
I don't see you opening file.
if((modelInfoFile=fopen(filename,"w")) == NULL){
Should work.
EDIT
In you while loop you change -
vertex = vertex->prev;
But in fprintf you store in file in value of leftVertex->vertexCoordinates.x
So how do you expect to print inside file correctly.

GTK2 C - how to pass 2D array of structures to callback function and change this array's values?

I'm writing an app (Battleships puzzle) in GTK+ in C. I have a structure shippart:
typedef enum {
water, single, top, bot, mid, left, right, waterU, shipU, unknown
} shiptype;
typedef struct {
GtkWidget *img;
shiptype type; //shiptype is typedef enum
shiptype hiddenType;
} shippart;
The whole map is two-dimensional array of shippart (shippart battlemap[10][10]) and I have it declared in my main(). I fill all these 3 fields, user clicks on a single part (1 of 100) of the map to mark it as water or as a ship part. When he wants to check if his guesses are correct, he should be able to click 'Check' which, if his guesses were correct, will change his water-marked parts as water, ship-marked parts as (more specified) ship parts and if he did something wrong, it will unmark it.
Everything is fine until the point of checking. It just doesn't work and I assume it's caused by something with passing this map array.
void buttonCheckHandler(GtkWidget *widget, gpointer user_data) {
//this is most likely wrong, I found it somewhere in the other question here
//but honestly I tried everything and it just doesn't work
shippart * (*map)[MAP_SIZE] = (shippart *(*)[MAP_SIZE])user_data;
//this part might be unnecessary
int i, j;
for(i = 0; i<MAP_SIZE; i++) {
for(j = 0; j<MAP_SIZE; j++) {
if(map[i][j]->type == waterU) {
if(map[i][j]->hiddenType == water) {
gtk_image_set_from_pixbuf(GTK_IMAGE(map[i][j]->img), shiptypes[0]);
map[i][j]->type = water;
}
else {
gtk_image_set_from_pixbuf(GTK_IMAGE(map[i][j]->img), shiptypes[9]);
map[i][j]->type = unknown;
}
continue;
}
//... very similar lines to these 11 above
}
}
}
void makeOverlay(shippart map[][MAP_SIZE], (...)) {
//...
g_signal_connect(G_OBJECT(btnCheck), "clicked", G_CALLBACK(buttonCheckHandler), &map);
//...
}
int main(int argc, char *argv[]) {
shippart battlemap[MAP_SIZE][MAP_SIZE];
fillMap(battlemap); //fills hiddenType's
makeUserMap(battlemap); //fills type's with 'unknown' and 2-4 fields with those from hiddenType
makeOverlay(battlemap, (...)); //almost everything with gtk
}
So my question is: how to correctly pass this map from makeOverlay() to buttonCheckHandler()? Is it even possible? I used to have shippart map[10][10] as global variable and it worked (my buttonCheckHandler was like this:)
void buttonCheckHandler(GtkWidget *widget, gpointer user_data) {
checkMap(); //without parameteres, because it changed global variable
//I tried same thing with checkMap(user_data); earlier but it didn't work
}
but my code was pretty horrible to read and undestand and now I messed it up. Can you help me?
There's a difference between a 2D array and an array of pointers (aka ragged 2D array).
When passing a 2D array, it decays to a pointer to the first element. You can access the data through the pointer by treating it as a 1D array, but you must calculate the index.
shippart * map = user_data;
...
map[i*MAP_SIZE+j].type;
//or
(map+i*MAP_SIZE+j)->type;
As for messing up your source when making big changes, you should use a version control system. One of the most widely available (and primitive) is RCS, which can work with single files, too. Whenever you make a change and get it to compile and run correctly, check-in the source. With RCS, it's
ci -l filename.c
The -l immediately extracts a new editable file after checking it in. Then if you make bad changes, you can revert to the previous checked-in version with
ls filename.c,v # <-- before deleting, make sure you actually have a checked-in file
rm filename.c
co -l filename.c

Need to write algorithm in state-machine style, but it becomes very hard to read

I work on embedded device's firmware (write in C), I need to take a screenshot from the display and save it as a bmp file. Currently I work on the module that generates bmp file data. The easiest way to do that is to write some function that takes the following arguments:
(for simplicity, only images with indexed colors are supported in my example)
color_depth
image size (width, height)
pointer to function to get palette color for color_index (i)
pointer to function to get color_index of the pixel with given coords (x, y)
pointer to function to write image data
And then user of this function should call it like that:
/*
* Assume we have the following functions:
* int_least32_t palette_color_get (int color_index);
* int pix_color_idx_get (int x, int y);
* void data_write (const char *p_data, size_t len);
*/
bmp_file_generate(
1, //-- color_depth
x, y, //-- size
palette_color_get,
pic_color_idx_get,
data_write
);
And that's it: this functions does all the job, and returns only when job is done (i.e. bmp file generated and "written" by given user callback function data_write().
BUT, I need to make bmp_writer module to be usable in cooperative RTOS, and data_write() might be a function that actually transmits data via some protocol (say, UART) to another device), so, this function needs to be called only from Task context. This approach doesn't work then, I need to make it in OO-style, and its usage should look like this:
/*
* create instance of bmp_writer with needed params
* (we don't need "data_write" pointer anymore)
*/
T_BmpWriter *p_bmp_writer = new_bmp_writer(
1, //-- color_depth
x, y, //-- size
palette_color_get,
pic_color_idx_get
);
/*
* Now, byte-by-byte get all the data!
*/
while (bmp_writer__data_available(p_bmp_writer) > 0){
char cur_char = bmp_writer__get_next_char(p_bmp_writer);
//-- do something useful with current byte (i.e. cur_char).
// maybe transmit to another device, or save to flash, or anything.
}
/*
* Done! Free memory now.
*/
delete_bmp_writer(p_bmp_writer);
As you see, user can call bmp_writer__get_next_char(p_bmp_writer) when he need that, and handle received data as he wants.
Actually I already implemented this, but, with that approach, all the algorithm becomes turned inside out, and this code is extremely non-readable.
I'll show you a part of old code that generates palette data (from the function that does all the job, and returns only when job is done), and appropriate part of new code (in state-machine style).
Old code:
void bmp_file_generate(/*....args....*/)
{
//-- ... write headers
//-- write palette (if needed)
if (palette_colors_cnt > 0){
size_t i;
int_least32_t cur_color;
for (i = 0; i < palette_colors_cnt; i++){
cur_color = callback_palette_color_get(i);
callback_data_write((const char *)&cur_color, sizeof(cur_color));
}
}
//-- ...... write image data ..........
}
As you see, very short and easy-readable code.
Now, new code.
It looks like state-machine, because it's actually splitted by stages (HEADER_WRITE, PALETTE_WRITE, IMG_DATA_WRITE), each stage has its own context. In the old code, context was saved in local variables, but now we need to make the structure and allocate it from heap.
So:
/*
* Palette stage context
*/
typedef struct {
size_t i;
size_t cur_color_idx;
int_least32_t cur_color;
} T_StageContext_Palette;
/*
* Function that switches stage.
* T_BmpWriter is an object context, and pointer *me is analogue of "this" in OO-languages.
* bool_start is 1 if stage is just started, and 0 if it is finished.
*/
static void _stage_start_end(T_BmpWriter *me, U08 bool_start)
{
switch (me->stage){
//-- ...........other stages.........
case BMP_WR_STAGE__PALETTE:
if (bool_start){
//-- palette stage is just started. Allocate stage context and initialize it.
me->p_stage_context = malloc(sizeof(T_StageContext_Palette));
memset(me->p_stage_context, 0x00, sizeof(T_StageContext_Palette));
//-- we need to get first color, so, set index of byte in cur_color to maximum
((T_StageContext_Palette *)me->p_stage_context)->i = sizeof(int_least32_t);
} else {
free(me->p_stage_context);
me->p_stage_context = NULL;
}
break;
//-- ...........other stages.........
}
}
/*
* Function that turns to the next stage
*/
static void _next_stage(T_BmpWriter *me)
{
_stage_start_end(me, 0);
me->stage++;
_stage_start_end(me, 1);
}
/*
* Function that actually does the job and returns next byte
*/
U08 bmp_writer__get_next_char(T_BmpWriter *me)
{
U08 ret = 0; //-- resulting byte to return
U08 bool_ready = 0; //-- flag if byte is ready
while (!bool_ready){
switch (me->stage){
//-- ...........other stages.........
case BMP_WR_STAGE__PALETTE:
{
T_StageContext_Palette *p_stage_context =
(T_StageContext_Palette *)me->p_stage_context;
if (p_stage_context->i < sizeof(int_least32_t)){
//-- return byte of cur_color
ret = *( (U08 *)&p_stage_context->cur_color + p_stage_context->i );
p_stage_context->i++;
bool_ready = 1;
} else {
//-- need to get next color (or even go to next stage)
if (p_stage_context->cur_color_idx < me->bmp_details.palette_colors_cnt){
//-- next color
p_stage_context->cur_color = me->callback.p_palette_color_get(
me->callback.user_data,
p_stage_context->cur_color_idx
);
p_stage_context->cur_color_idx++;
p_stage_context->i = 0;
} else {
//-- next stage!
_next_stage(me);
}
}
}
break;
//-- ...........other stages.........
}
}
return ret;
}
So huge code, and it's so hard to understand it!
But I really have no idea how to make it in some different way, to be able to get information byte-by-byte.
Does anyone know how to achieve this, and keep code readability?
Any help is appreciated.
You can try protothread, which is useful to transform a state-machine based program into thread-style program. I'm not 100% sure that it can solve your problem elegantly, you can give it a try. The paper is a good starting point: Protothreads: simplifying event-driven programming of memory-constrained embedded systems
Here is its source code: http://code.google.com/p/protothread/
By the way, protothread is also used in the Contiki embedded OS, for implementing process in Contiki.

Resources