Graphviz as library in windows - c++

I am contacting you regarding Graphviz libraries. I have a bug that I observed when using graphviz as a library within c++ code and qt creator on windows.
Based on the example from the Documentation, I used the following function to convert a dot file in png file:
bool saveImageGV(){
GVC_t *gvc= gvContext();
gvAddLibrary(gvc, &gvplugin_dot_layout_LTX_library);
gvAddLibrary(gvc, &gvplugin_core_LTX_library);
gvAddLibrary(gvc, &gvplugin_gd_LTX_library);
FILE *fp = fopen((pathTmp + ".dot").c_str(), "r");
Agraph_t *g = agread(fp,0);
gvLayout(gvc, g, "dot");
FILE *fp2 = fopen((pathTmp + ".png").c_str(), "w");
gvRender(gvc, g, "png", fp2);
gvFreeLayout(gvc, g);
agclose(g); fclose(fp); fclose(fp2);
return (gvFreeContext(gvc));
}
It appears that on linux, this function works very well with graphviz 2.30 and I succeed to convert my dot file into a png file.
However, when I use the windows libraries, I got a segmentation fault with the same function.
My investigations let me think the problems could come from the .dll libraries as, on linux, it worked with the 2.30 version but not with the 2.38 version of the libraries. With windows, 2.30 and 2.38 lead to the same error of segmentation fault.
Is it a well known bug and it exists another way to convert a dot file into png file on windows? I link the libraries from the "Graphviz2.38\lib\release\lib" folder and take the dlls from "Graphviz2.38\lib\release\dll" folder.
I thank you in advance for your response and if you need more information.

graphviz FAQ
maybe it's because of a wrong version of stdio
i had segmentation fault happened in visual studio and here is the solution (using /std:c++latest so the syntax does not conform to the standard, the code is only for understanding)
Agiodisc_t my_iodisc = {
.afread = [](void* chan, char* buf, int bufsize)->int
{
return fread(buf, 1, bufsize, (FILE*)chan);
},
.putstr = [](void* chan,const char* buf)->int
{
return fwrite(buf, 1, strlen(buf), (FILE*)chan);
},
.flush = [](void* chan)->int
{
return fflush((FILE*)chan);
}
};
Agdisc_t my_disc = {
.mem = NULL, // use system default
.id = NULL, // use system default
.io = &my_iodisc
};
FILE* p_file = fopen("1.gv", "r");
Agraph_t* g = agread(p_file, &my_disc);
fclose(p_file);

Related

fopen_s returns error code 2 with system account and win 32 but works fine on winx64 (c++)

I have a cpp program that uses fopen_s to open and read a file created under the directory C:\Windows\System32\config\systemprofile\AppData\Roaming.
My program needs to be compatible with winx64 and win32.
When I run this program with a system account (run using PSTools\PSExec -i -s C:\windows\system32\cmd.exe) and the Win32 compiled version of the program, fopen_s() on any file inside "C:\Windows\System32\config\systemprofile\AppData\Roaming" returns an error code 2, even though the file is present.
However, when I run the x64 compiled version of the same program, it works fine and fopen_s() is able to find and open the same file.
I am sure there are no mistakes as far as passing a valid filename to fopen_s() and I have verified this.
I make sure that the int variable that stores the return value from fopen_s() is set to 0 every time before calling fopen_s(). I am calling fopen_s() in "r" mode.
Also, elsewhere in the same program I am able to create files under the same directory.
I am using VS2019 and cpp +11 to compile my program.
My system is running windows 10 (64-bit) on an x64 processor (Intel(R) Xeon(R) Gold 6136)
Why would a win32 application fail to read a file created under "C:\Windows\System32\config\systemprofile\AppData\Roaming" with a system account while the x64 version of the same application works fine?
Code snippet:
int FileOpenFunc(FILE ** ppFile, std::string sFilename, std::string sOpenMode)
{
int errOpen = 0;
#ifdef _WIN32
errOpen = fopen_s(ppFile, sFilename.c_str(), sOpenMode.c_str());
#else
*ppFile = fopen(sFilename.c_str(), sOpenMode.c_str());
errOpen = errno;
#endif
return errOpen;
}
void func()
{
std::string sFileName = "C:\\Windows\\System32\\config\\systemprofile\\AppData\\Roaming\\Check\\sample.txt";
int errFopenErrNo = 0;
FILE* fp = NULL;
errFopenErrNo = FileOpenFunc(&fp, sFileName, "r");
if (fp!= NULL)
{
//do something
}
else
{
//do something else
}
}

C++ Tesseract OCR: Getting ObjectCache(): WARNING! LEAK! object still has count 1

I installed libtesseract-dev (v4.1.1) on Ubuntu 20.04 & I am trying out a C++ code to OCR an image to searchable PDF.
My code is somewhat modified than the C++ API example code provided at official website:
/home/test/Desktop/Example2/testexample2.cpp:
#include <leptonica/allheaders.h>
#include <tesseract/baseapi.h>
#include <tesseract/renderer.h>
int main()
{
//const char* input_image = "/usr/src/tesseract-oc/testing/phototest.tif";
//const char* output_base = "my_first_tesseract_pdf";
//const char* datapath = "/Projects/OCR/tesseract/tessdata";
const char* input_image = "001.jpg";
const char* output_base = "001";
const char* datapath = ".";
int timeout_ms = 5000;
const char* retry_config = nullptr;
bool textonly = false;
int jpg_quality = 92;
tesseract::TessBaseAPI *api = new tesseract::TessBaseAPI();
if (api->Init(datapath, "eng")) {
fprintf(stderr, "Could not initialize tesseract.\n");
exit(1);
}
/*
tesseract::TessPDFRenderer *renderer = new tesseract::TessPDFRenderer(
output_base, api->GetDatapath(), textonly, jpg_quality);
*/
tesseract::TessPDFRenderer *renderer = new tesseract::TessPDFRenderer(
output_base, api->GetDatapath(), textonly);
bool succeed = api->ProcessPages(input_image, retry_config, timeout_ms, renderer);
if (!succeed) {
fprintf(stderr, "Error during processing.\n");
return EXIT_FAILURE;
}
api->End();
return EXIT_SUCCESS;
}
I also followed https://stackoverflow.com/a/59382664 as follows:
cd /home/test/Desktop/Example2
wget https://github.com/tesseract-ocr/tessdata/raw/master/eng.traineddata
wget https://github.com/tesseract-ocr/tesseract/blob/master/tessdata/pdf.ttf
export TESSDATA_PREFIX=$(pwd)
gedit config
(In the config file, entered the contents:
tessedit_create_pdf 1 Write .pdf output file
tessedit_create txt 1 Write .txt output file
)
g++ testexample2.cpp -o testexample2 -ltesseract
./testexample2
But on execution, it displays the errors as follows:
Warning: Invalid resolution 0 dpi. Using 70 instead.
Error during processing.
ObjectCache(0x7f1b096669c0)::~ObjectCache(): WARNING! LEAK! object 0x55af5c5241a0 still has count 1 (id /home/test/Desktop/Example2/eng.traineddatapunc-dawg)
ObjectCache(0x7f1b096669c0)::~ObjectCache(): WARNING! LEAK! object 0x55af5c506770 still has count 1 (id /home/test/Desktop/Example2/eng.traineddataword-dawg)
ObjectCache(0x7f1b096669c0)::~ObjectCache(): WARNING! LEAK! object 0x55af5c9a4a70 still has count 1 (id /home/test/Desktop/Example2/eng.traineddatanumber-dawg)
ObjectCache(0x7f1b096669c0)::~ObjectCache(): WARNING! LEAK! object 0x55af5c9a4980 still has count 1 (id /home/test/Desktop/Example2/eng.traineddatabigram-dawg)
ObjectCache(0x7f1b096669c0)::~ObjectCache(): WARNING! LEAK! object 0x55af5d7d5170 still has count 1 (id /home/test/Desktop/Example2/eng.traineddatafreq-dawg)
My directory structure is:
Example2
|------->001.jpg
|------->config
|------->eng.traineddata
|------->pdf.ttf
|------->testexample2
|------->testexample2.cpp
I have searched about this on multiple sources, but could not find any fix for this.
Further, I would like to know if there is someway I can build a binary using C++ compilation from this code + libtesseract such that my binary becomes a standalone portable binary, running which on other Ubuntu systems would not require reinstalling tesseract libraries & their dependencies
tesseract API examples is show case for using tesseract features without covering all specifics of programming language of your choice (c++ in your case).
Just looking at your code even without trying it: you dynamically allocates memory 2x but you did not deallocate them. Try to fix these issues.
You must free use dynamic memory for your class "api"
Use:
... you code...
if (renderer) delete renderer;
if (api) delete api;

render a gvc (graohviz) from c++ console application / or qt gui application

I am writing a programme which can generate dot desctiption file that I would like to directly on the screen.
I got following code from graphviz.org on how to use it as a library and it works
int main(int argc, char *argv[])
{
Agraph_t* G;
GVC_t* gvc;
gvc = gvContext(); /* library function */
FILE* fl;
FILE* ot;
ot = fopen("/home/test.png", "w");
fl = fopen("/home/my.gv", "r");
G = agread(fl,0);
gvLayout (gvc, G, "dot"); /* library function */
gvRender(gvc, G,"png", ot);
gvFreeLayout(gvc, G); /* library function */
agclose (G); /* library function */
return (gvFreeContext(gvc));
}
When I run it from the qt console application project, it just gives
Press <RETURN> to close this window...
I can see it does generate this test.png file. I am thinking there must be a way that I can show the gvc directly without like opening an png file, right?
Because writing a GUI application for this from scratch seems like an awesomely bad idea, how about using an external program to achieve this?
You can even launch it from within your generating program if you insist:
system("feh -dR1 test.png");

cstdio fopen and fclose not working correctly on osx

I'm using tinyxml through openframeworks which uses cstdio for file access. I can see the example program quite happily create and write files but there is no delete so my plan is to implement remove, but after trying to run this code in my own project it doesn't seem to create a file or notify me of an error.
This code runs as expected on windows, just not on mac osx 10.8.5, no file is generated.
#include <cstdio>
int main(int argc, const char * argv[])
{
bool bClosed = false;
bool bWritten = false;
FILE* testFile;
testFile = fopen(".\\test.xml", "w");
if(testFile)
{
bWritten = fputs("test writing.", testFile);
bClosed = !fclose(testFile);
}
return 0;
}
edit: i now know the file exists as can read from it, i just cant view it in finder, i have hidden files shown, its not found its way into the app's package contents.
On a unix-like system (e.g. Mac OS X and Linux) a Windows path as
".\\test.xml"
should rather be
"./test.xml"
Anyway the simplest solution for this case might just be
"test.xml"

Writing PNG file from pixel data using libpng

I am trying to write PNG file (saving an image in png format) from pixel data read by glReadPixels in openGL using following piece of code (copied from here):
bool writePNGFileFromBuffer(const char *filename, unsigned char *pixels, int w, int h)
{
png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);//8
if (!png)
return false;
png_infop info = png_create_info_struct(png);//7
if (!info) {
png_destroy_write_struct(&png, &info);//
return false;
}
FILE *fp = fopen(filename, "wb");
if (!fp) {
png_destroy_write_struct(&png, &info);//
return false;
}
png_init_io(png, fp);//9
png_set_IHDR(png, info, w, h, 8 /* depth */, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);//10
png_colorp palette = (png_colorp)png_malloc(png, PNG_MAX_PALETTE_LENGTH * sizeof(png_color));//4
if (!palette) {
fclose(fp);
png_destroy_write_struct(&png, &info);//
return false;
}
png_set_PLTE(png, info, palette, PNG_MAX_PALETTE_LENGTH);//12
png_write_info(png, info);//1
png_set_packing(png);//5
png_bytepp rows = (png_bytepp)png_malloc(png, h * sizeof(png_bytep));//
for (int i = 0; i < h; ++i)
rows[i] = (png_bytep)(pixels + (h - i) * w * 3);
png_write_image(png, rows);//2
png_write_end(png, info);//6
png_free(png, palette);//11
png_destroy_write_struct(&png, &info);//3
fclose(fp);
delete[] rows;
return true;
}
I linked the libpng and zlib libraries in the additional dependencies. But when I compile the code it gives following error:
Error 77 error LNK2001: unresolved external symbol png_write_info
It gives this error at about 12 instances marked in the code snippet above. I am clear that it is not able to find the definitions of the functions but I do not know why?
Any help would be appreciated. Thanks
Edit: I looked into the header file "png.h" and it contains declarations for all the functions. Functions are defined in "pngwrite.c" and I think it should take it from the linked library.
Edit2: After hitting around for couple of days, I found that when I change the output type of my project (in which I am using libpng.lib) to Static Lib (.lib), everything works and the code compiles well but with .dll output it throws the above specified error.
And my problem is, I have to use .dll output because that I use in another huge project which I cant change to accept .lib.
Any help on this?
You may be missing "pnglibconf.h" which you must copy from
scripts/pnglibconf.h.prebuilt to pnglibconf.h in your source directory.