How to use MagickGetImageHistogram of ImageMagick C API - c

I have been using ImageMagick's C API using LuaJIT and FFI library and magick lua module for this. Now I want to use MagickGetImageHistogram method. So when it comes to pass an argument check my below code.
***image.lua***
local len = ffi.new("size_t[?]", 5)
local t = handle_result(self, lib.MagickGetImageHistogram(self.wand, len))
***lib.lua***
local ffi = require("ffi")
local lib
ffi.cdef([[ typedef void MagickWand;
typedef void PixelWand;
typedef int MagickBooleanType;
typedef int ExceptionType;
typedef int ssize_t;
typedef int CompositeOperator;
typedef int GravityType;
typedef int OrientationType;
typedef int InterlaceType;
typedef char DistortMethod[];
void MagickWandGenesis();
MagickWand* NewMagickWand();
PixelWand **MagickGetImageHistogram(MagickWand *wand, size_t *number_colors);
So I'm sure that my first argument is correct but not sure about second one.
And it returns the image histogram as an array of PixelWand wands. So how do I convert it to LuaJIT structure?

I'm not sure about the lua parts of the question, but the expected behavior MagickGetImageHistogram is as follows.
Method will return an array of pixel pointers.
Argument size_t *number_colors will be updated with the count of pixels in array.
Each pixel in array will need to invoke method PixelGetColorCount to retrieve the sum of pixels used by image.
Here's a quick example in C.
#include <stdio.h>
#include <wand/MagickWand.h>
int main(int argc, const char * argv[]) {
// Prototype vars
MagickWand * wand;
PixelWand ** histogram;
size_t histogram_count = 0;
// Boot environment.
MagickWandGenesis();
// Allocate & read image
wand = NewMagickWand();
MagickReadImage(wand, "rose:");
// Get Histogram as array of pixels
histogram = MagickGetImageHistogram(wand, &histogram_count);
// Iterate over each pixel & dump info.
for (int i = 0; i < histogram_count; ++i)
{
printf("%s => %zu\n",
PixelGetColorAsString(histogram[i]),
PixelGetColorCount(histogram[i]));
}
// Clean-up
histogram = DestroyPixelWands(histogram, histogram_count);
wand = DestroyMagickWand(wand);
MagickWandTerminus();
return 0;
}
This example will output the expected text...
// ...
srgb(48,45,43) => 1
srgb(50,45,42) => 2
srgb(50,44,43) => 5
srgb(51,45,43) => 1
// ...
So I would guess your lua script would look something like..
***image.lua***
local tlen = ffi.new("size_t[1]")
local t = lib.MagickGetImageHistogram(self.wand, tlen)
for i=0,tlen[0] do
handle_new_pixel(self, t[i], lib.PixelGetColorCount(t[i]))
end

Related

Read the value of pointer to pointer array of struct passed to a function

Context:
Recently I've started programming in a more professional way and currently I'm working on a C driver library that should look decent in code both functionally and esthetically so I've just started to use the consept of pointers more intensely and not very experienced with it in relation to how it works on code.
Problem:
Basically I'm trying to read a values inside each of the struct with a for loop inside initFunt()
My solution to that was to create a struct pointer group for all the created btn_params_t instants and pass that pointer group to initFunc() and from init access each struct member with something like "Btn Pin in the first struct is: %d", BtnPointer[0]->BtnPin
Here's basically the code to explain it:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
typedef struct btn_params_t
{
uint8_t BtnPin;
uint8_t BtnActiveState;
uint8_t BtnPinPullUp;
uint8_t BtnPinPullDown;
void (*PressedISR)();
void (*ReleasedISR)();
} btn_params_t;
void initFunc(btn_params_t **BtnPointer){
printf("Btn Pin in the first struct is: %d", BtnPointer[0]->BtnPin);
}
int main(int argc, char *argv[]) {
btn_params_t Btn0Params = {
.BtnPin = 4,
.BtnActiveState = 0,
.BtnPinPullUp = 1,
.BtnPinPullDown = 0
};
btn_params_t Btn1Params = {.BtnPin = 32};
btn_params_t** BtnGroup = {&Btn0Params, &Btn1Params};
initFunc(BtnGroup);
}
How'd you do such a thing?

Calling local Julia package from C

The Julia documentation shows examples of how to call Base Julia functions from C (e.g. sqrt), which I've been successful in replicating. What I'm really interested in doing is calling locally developed Julia modules and it's not at all clear from the documentation how one would call non-Base functions. There are some discussion threads on the issue from a few years ago, but the APIs appear to have changed in the meantime. Any pointers would be appreciated.
The reason why jl_eval_string("using SomeModule") returns NULL is simply because using SomeModule returns nothing.
You can use functions from other modules by first importing the module, and then retrieving function objects from that Julia module into C. For example, let's use the package GR and its plot function. We can get the plot function with
jl_eval_string("using GR") // this returns nothing
jl_module_t* GR = (jl_module_t *)jl_eval_string("GR") // this returns the module
/* get `plot` function */
jl_function_t *plot = jl_get_function(GR, "plot");
Here we passed GR module as the first argument to jl_get_function. We can, knowing the fact that things will be loaded into the module Main and plot is exported from GR, use the following snippet instead to do the same. Note that jl_main_module holds a pointer to the module Main.
jl_eval_string("using GR")
/* get `plot` function */
jl_function_t *plot = jl_get_function(jl_main_module, "plot");
We can also use plots qualified name.
/* get `plot` function */
jl_function_t *plot = jl_get_function(jl_main_module, "GR.plot");
That said, here is the complete example plotting an array of values using GR. The example uses the first style to get the function GR.plot.
#include <julia.h>
JULIA_DEFINE_FAST_TLS() // only define this once, in an executable (not in a shared library) if you want fast code.
#include <stdio.h>
int main(int argc, char *argv[])
{
/* required: setup the Julia context */
jl_init();
/* create a 1D array of length 100 */
double length = 100;
double *existingArray = (double*)malloc(sizeof(double)*length);
/* create a *thin wrapper* around our C array */
jl_value_t* array_type = jl_apply_array_type((jl_value_t*)jl_float64_type, 1);
jl_array_t *x = jl_ptr_to_array_1d(array_type, existingArray, length, 0);
/* fill in values */
double *xData = (double*)jl_array_data(x);
for (int i = 0; i < length; i++)
xData[i] = i * i;
/* import `Plots` into `Main` module with `using`*/
jl_eval_string("using GR");
jl_module_t* GR = (jl_module_t *)jl_eval_string("GR");;
/* get `plot` function */
jl_function_t *plot = jl_get_function(GR, "plot");
/* create the plot */
jl_value_t* p = jl_call1(plot, (jl_value_t*)x);
/* display the plot */
jl_function_t *disp = jl_get_function(jl_base_module, "display");
jl_call1(disp, p);
getchar();
/* exit */
jl_atexit_hook(0);
return 0;
}
Including a Julia module from a local file and use it in C
I do not know what is exactly meant by a local Julia package, but, you can include your files and then import the modules in those files to do the same. Here is an example module.
# Hello.jl
module Hello
export foo!
foo!(x) = (x .*= 2) # multiply entries of x by 2 inplace
end
To include this file you need to use jl_eval_string("Base.include(Main, \"Hello.jl\")");. For some reason, embedded Julia cannot access include directly. You need to use Base.include(Main, "/path/to/file") instead.
jl_eval_string("Base.include(Main, \"Hello.jl\")");
jl_eval_string("using Main.Hello"); // or just '.Hello'
jl_module_t* Hello = (jl_module_t *)jl_eval_string("Main.Hello"); // or just .Hello
Here is the complete example in C.
#include <julia.h>
JULIA_DEFINE_FAST_TLS() // only define this once, in an executable (not in a shared library) if you want fast code.
#include <stdio.h>
int main(int argc, char *argv[])
{
/* required: setup the Julia context */
jl_init();
/* create a 1D array of length 100 */
double length = 100;
double *existingArray = (double*)malloc(sizeof(double)*length);
/* create a *thin wrapper* around our C array */
jl_value_t* array_type = jl_apply_array_type((jl_value_t*)jl_float64_type, 1);
jl_array_t *x = jl_ptr_to_array_1d(array_type, existingArray, length, 0);
JL_GC_PUSH1(&x);
/* fill in values */
double *xData = (double*)jl_array_data(x);
for (int i = 0; i < length; i++)
xData[i] = i * i;
/* import `Hello` module from file Hello.jl */
jl_eval_string("Base.include(Main, \"Hello.jl\")");
jl_eval_string("using Main.Hello");
jl_module_t* Hello = (jl_module_t *)jl_eval_string("Main.Hello");
/* get `foo!` function */
jl_function_t *foo = jl_get_function(Hello, "foo!");
/* call the function */
jl_call1(foo, (jl_value_t*)x);
/* print new values of x */
for (int i = 0; i < length; i++)
printf("%.1f ", xData[i]);
printf("\n");
JL_GC_POP();
getchar();
/* exit */
jl_atexit_hook(0);
return 0;
}

C pointer casting to and from Go

I'm writing an app for the windows platform using FFmpeg and it's golang wrapper goav, but I'm having trouble understanding how to pass the C pointers between C and Go.
I've stripped out all the relevant parts of the C code, the wrapper and my code, shown below:
C code - libavutil/frame.h
#include <stdint.h>
typedef struct AVFrame {
#define AV_NUM_DATA_POINTERS 8
uint8_t *data[AV_NUM_DATA_POINTERS];
}
Go goav wrapper
package avutil
/*
#cgo pkg-config: libavutil
#include <libavutil/frame.h>
#include <stdlib.h>
// C code I added:
#include <stdio.h>
void SaveFrame(const char* location, uint8_t *data, int width, int height) {
FILE *pFile;
int y;
// Open file
pFile=fopen(location, "wb");
if(pFile==NULL)
return;
// Write header
fprintf(pFile, "P6\n%d %d\n255\n", width, height);
// Write pixel data
for(y=0; y<height; y++)
fwrite(data+y*width, 1, width*3, pFile);
// Close file
fclose(pFile);
}
*/
import "C"
import (
"unsafe"
)
type Frame C.struct_AVFrame
func Data(f *Frame) *uint8 {
// i think this is the function thats not working?
return (*uint8)(unsafe.Pointer((*C.uint8_t)(unsafe.Pointer(&f.data))))
}
func SaveFrame(location string, data *uint8, width int, height int) {
C.SaveFrame(C.CString(location), unsafe.Pointer(data), C.int(width), C.int(height))
}
My Go code
package main
import "github.com/giorgisio/goav/avutil"
func main() {
var frame *avutil.Frame
var data *uint8
//... initialize frame
data = avutil.Data(frame)
avutil.SaveFrame("frame0.ppm", data, 1920, 1080)
}
When I try to save the frame, the resulting image is garbled because the pointer is wrong, how do i fix this?
The data field of the AVFrame struct is an array of 8 pointers.
That is, it's a contiguous chunk of memory containing 8 slots
adjacent to each other—each holding a pointer (to a value of type uint8_t).
IOW, the declaration
uint8_t *data[AV_NUM_DATA_POINTERS];
is better interpreted as
uint8_t* data[AV_NUM_DATA_POINTERS];
and in Go, you'd declare it something like
var data [AV_NUM_DATA_POINTERS]*uint8_t
Now your SaveFrame function declares its data arguments to
be of type uint8_t*. That is okay to pass the address of the
data array of an AVFrame struct as that argument, but more idiomatic
would be to pass the address of its zeroth element—something like
func Data(frame *Frame) *uint8 {
return (*uint8)(unsafe.Pointer(&frame.data[0]))
}

Can I get "macro polymorphism" in C

The type of polymorphism I'm after is this:
suppose I have a macro called draw(), and I have 2 structs, one called circle and the other called square. Is is possible to somehow do something like this:
#define draw() // can I get the text that's behind the macro?
//then maybe, with _Generic achieve this?
void draw_circle(struct circle);
void draw_square(struct square);
struct circle c;
struct square s;
c.draw();//draw is a macro. this time it is supposed to expand to draw_circle(c);
s.draw();//supposed to expand to draw_square(s);
EDIT_1: this is what I have so far, after reading your answers.
//raw_array.h
#pragma once
#include <stdint.h>
#include <stdlib.h>
#define byte uint8_t
#define _GET_OVERRIDE(_1, _2, _3, NAME, ...) NAME
/*#define init_impl(...) _GET_OVERRIDE(__VA_ARGS__, \
init_impl3, init_impl2, init_impl1)(__VA_ARGS__)
#define init( name, ... ) (raw_array * (name); init_impl( (name), __VA_ARGS__))*/
#define array_init_impl(...) _GET_OVERRIDE(__VA_ARGS__, init_array_impl3, init_array_impl2, init_array_impl1)(__VA_ARGS__)
///<summary>creates a variable of type raw_array with name as an identifier, and initializes based on the parameters</summary>
#define RAW_ARRAY( name, ... ) raw_array (name); array_init_impl( (&name), __VA_ARGS__)
typedef struct indexable_memory_block_struct
{
raw_array * _self;
byte * bytes;
size_t element_size;
size_t number_of_elements;
} raw_array;
///<summary>starts the an empty raw_array. only element_size is set.</summary>
///<param name=r_arr>the raw_array to be initialized</param>
///<param name=element_size>the size of the elements in this raw_array</param>
void init_impl1 ( raw_array * r_arr, size_t element_size )
{
r_arr = malloc ( sizeof ( raw_array ) );
r_arr->element_size = element_size;
r_arr->number_of_elements = 0;
r_arr->bytes = NULL;
r_arr->_self = r_arr;
}
///<summary>
///starts the raw_array an empty. byte with its bytes allocated
///to their default value (0).
///</summary>
///<param name=r_arr>the raw_array to be initialized</param>
///<param name=element_size>the size of the elements in this raw_array</param>
///<param name=number_of_elements>the number of elements in the array</param>
void init_impl2 ( raw_array * r_arr, size_t element_size, size_t number_of_elements )
{
r_arr = malloc ( sizeof ( raw_array ) );
r_arr->element_size = element_size;
r_arr->number_of_elements = number_of_elements;
r_arr->bytes = calloc ( number_of_elements, element_size );
r_arr->_self = r_arr;
}
///<summary>
///starts the raw_array copying its contents from a normal array.
///</summary>
///<param name=r_arr>the raw_array to be initialized</param>
///<param name=arr>the normal C array whose contents will be copied to this raw_array</param>
///<param name=element_size>the size of the elements in this raw_array</param>
///<param name=number_of_elements>the number of elements in the array</param>
void init_impl3 ( raw_array * r_arr, const void * const arr, size_t size_of_element, size_t number_of_elements )
{
r_arr->bytes = malloc ( size_of_element * number_of_elements );
memcpy ( r_arr->bytes, arr, size_of_element * number_of_elements );
r_arr->element_size = size_of_element;
r_arr->number_of_elements = number_of_elements;
r_arr->_self = r_arr;
}
there are other parts, but these are the ones currently being ported to this new syntax. Now main:
int main ( int argc, char * argv[] )
{
int data[30];
//line bellow has a compilation error: *expected a ')'*
init ( r_arr, data, sizeof ( int ), 30 );
}
what does it mean expected a ')'
could you guys check out the macro syntax?
About _Generic, I learned about it today, and I'll use it if it's useful, for sure.
EDIT_2: found a gross error, will be fixing it and editing again. Visual Studio is updating (12GB...) So I can't build anything at the moment. [mini-edit]: Guess I fixed the gross error at least. [mini-edit] another very bizarre error in my code, I stringifyed the name token, wth?! corrected now.
EDIT_3: having slept and having VS operational again, I fixed the macros, will edit them and comment out the wrong code. Now I need to the circle.draw() behaviour... any ideas?
Besides #LirooPierre s approach, you could also use C11 Generics. Yes you heard right, C has generics now.
Consider this example:
#include <stdio.h>
#define draw(X) _Generic((X), \
struct circle: draw_circle, \
struct square: draw_square \
)(X)
struct circle{};
struct square{};
void draw_circle(struct circle a)
{
printf("Drawing a circle\n");
}
void draw_square(struct square a)
{
printf("Drawing a square\n");
}
int main(void)
{
struct square a;
draw(a); // "Drawing a square"
}
But even though it should be portable, it sadly is not. M$ Compiler doesn't implement them, but clang and gcc do.
You can really only achieve what want in c with function pointers
struct shape {
{
void (*draw)(struct shape);
};
void draw_circle(struct shape);
void draw_square(struct shape);
#define CIRCLE(c) struct shape c; c.draw = &draw_circle;
#define SQUARE(s) struct shape s; s.draw = &draw_square;
Now you can do something like this:
CIRCLE(c)
SQUARE(s)
c.draw(c);
s.draw(s);
You could add a draw macro too if you don't like the c.draw(c) syntax.
#define DRAW(shape) shape.draw(shape)
DRAW(c);
DRAW(s);
Yes it is possible !
You have to create a pointer on a function in your struct like this:
typedef void (*t_draw)(struct circle); //create a new type called t_draw
struct circle {
t_draw draw;
}
Now in your code you have to assign a function in your struct:
struct circle c;
c.draw = &draw_circle;
and call it by using:
c.draw(/*your args*/);
Create the second structure square like the first and it should be OK !

External Functions and Parameter Size Limitation (C)

I am very much stuck in the following issue. Any help is very much appreciated!
Basically I have a program wich contains an array of structs and I am getting a segmentation error when I call an external function. The error only happens when I have more than 170 items on the array being passed.
Nothing on the function is processed. The program stops exactly when accessing the function.
Is there a limit for the size of the parameters that are passed to external functions?
Main.c
struct ratingObj {
int uid;
int mid;
double rating;
};
void *FunctionLib; /* Handle to shared lib file */
void (*Function)(); /* Pointer to loaded routine */
const char *dlError; /* Pointer to error string */
int main( int argc, char * argv[]){
// ... some code ...
asprintf(&query, "select mid, rating "
"from %s "
"where uid=%d "
"order by rand()", itable, uid);
if (mysql_query(conn2, query)) {
fprintf(stderr, "%s\n", mysql_error(conn2));
exit(1);
}
res2 = mysql_store_result(conn2);
int movieCount = mysql_num_rows(res2);
// withhold is a variable that defines a percentage of the entries
// to be used for calculations (generally 20%)
int listSize = round((movieCount * ((double)withhold/100)));
struct ratingObj moviesToRate[listSize];
int mvCount = 0;
int count =0;
while ((row2 = mysql_fetch_row(res2)) != NULL){
if(count<(movieCount-listSize)){
// adds to another table
}else{
moviesToRate[mvCount].uid = uid;
moviesToRate[mvCount].mid = atoi(row2[0]);
moviesToRate[mvCount].rating = 0.0;
mvCount++;
}
count++;
}
// ... more code ...
FunctionLib = dlopen("library.so", RTLD_LAZY);
dlError = dlerror();
if( dlError ) exit(1);
Function = dlsym( FunctionLib, "getResults");
dlError = dlerror();
(*Function)( moviesToRate, listSize );
// .. more code
}
library.c
struct ratingObj {
int uid;
int mid;
double rating;
};
typedef struct ratingObj ratingObj;
void getResults(struct ratingObj *moviesToRate, int listSize);
void getResults(struct ratingObj *moviesToRate, int listSize){
// ... more code
}
You are likely blowing up the stack. Move the array to outside of the function, i.e. from auto to static land.
Another option is that the // ... more code - array gets populated... part is corrupting the stack.
Edit 0:
After you posted more code - you are using C99 variable sized array on the stack - Bad IdeaTM. Think what happens when your data set grows to thousands, or millions, of records. Switch to dynamic memory allocation, see malloc(3).
You don't show us what listsize is, but I suppose it is a variable and not a constant.
What you are using are variable length arrays, VLA. These are a bit dangerous if they are too large since they usually allocated on the stack.
To work around that you can allocate such a beast dynamically
struct ratingObj (*movies)[listSize] = malloc(sizeof(*movies));
// ...
free(movies);
You'd then have in mind though that movies then is a pointer to array, so you have to reference with one * more than before.
Another, more classical C version would be
struct ratingObj * movies = malloc(sizeof(*movies)*listsize);
// ...
free(movies);

Resources