Skip to content

Instantly share code, notes, and snippets.

@vatsan
Last active August 29, 2015 14:09
Show Gist options
  • Save vatsan/ee6c1b4a75c04ca17d58 to your computer and use it in GitHub Desktop.
Save vatsan/ee6c1b4a75c04ca17d58 to your computer and use it in GitHub Desktop.
/**
* Gautam Muralidhar,Srivatsan Ramanujam Oct 2014
* PL/C function for invoking Canny's Edge Detection from OpenCV
**/
extern "C" {
#include <postgres.h>
#include <fmgr.h>
#include <utils/array.h>
#include <utils/builtins.h>
#include <catalog/pg_type.h>
#include <string>
#include <vector>
#include <stdlib.h>
#include <stdint.h>
#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif
// Postgres interface for getImgSizeFromByteStream
PG_FUNCTION_INFO_V1(get_imgsize);
Datum get_imgsize(PG_FUNCTION_ARGS){
if (PG_ARGISNULL(0)){
ereport(ERROR, (errmsg("Null arrays not accepted")));
}
// Collect the input image byte stream as C string
char* cstr = TextDatumGetCString(PG_GETARG_DATUM(0));
string str(cstr);
vector<string> tokens;
// Tokenize the string on “,” and collect the tokens, which represent individual bytes of the image
Tokenize(str, tokens, ",");
vector<int8_t> src;
for (int i = 0; i < tokens.size(); i++) {
const char* tk = tokens[i].c_str();
int bt = atoi(tk);
src.push_back(bt);
}
// Call the internal getImgSizeFromByteStream function
uint* imgSize = getImgSizeFromByteStream(src);
Datum* imgSizeArray = (Datum*)palloc(sizeof(Datum) * 2);
for (int i = 0; i < 2; i++) {
imgSizeArray[i] = imgSize[i];
}
// Construct the array to be returned back to the database client
ArrayType *res = construct_array(imgSizeArray, 2, INT4OID, 4, true, 'i');
PG_RETURN_ARRAYTYPE_P(res);
}
// Postgres interface for edgeDetectionFromByteStream
PG_FUNCTION_INFO_V1(canny_plc);
Datum canny_plc(PG_FUNCTION_ARGS){
if (PG_ARGISNULL(0)){
ereport(ERROR, (errmsg("Null arrays not accepted")));
}
// Collect the input image byte stream as C string
char* cstr = TextDatumGetCString(PG_GETARG_DATUM(0));
string str(cstr);
vector<string> tokens;
// Tokenize the string on “,” and collect the tokens, which represent individual bytes of the image
Tokenize(str, tokens, ",");
vector<int8_t> src;
for (int i = 0; i < tokens.size(); i++) {
const char* tk = tokens[i].c_str();
int bt = atoi(tk);
src.push_back(bt);
}
// Call the internal getImgSizeFromByteStream function
uint* imgSize = getImgSizeFromByteStream(src);
uint* edge_result = new uint[imgSize[0]*imgSize[1]];
// Call the internal edgeDetectionFromByteStream function
bool success = edgeDetectionFromByteStream(src, edge_result);
if (success) {
Datum* imgSizeArray = (Datum*)palloc(sizeof(Datum) * imgSize[0]*imgSize[1]);
for (int i = 0; i < imgSize[0]*imgSize[1]; i++) {
imgSizeArray[i] = edge_result[i];
}
// Construct the array to be returned back to the database client
ArrayType *res = construct_array(imgSizeArray,
imgSize[0]*imgSize[1], INT4OID, 4, true, 'i');
PG_RETURN_ARRAYTYPE_P(res);
} else {
ereport(ERROR, (errmsg("Edge detection failed")));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment