CImg loading image fails with spaces in path name - c++

I have a C++ application that I am developing to scan an image and return coordinates, the whole application works as expected except for this last problem that I can't seem to figure out. a user uploads images to a folder, and then the images get run one at a time to the application in a queue. well the problem is, that we have thousands of users with many folders, and a good amount of these users upload folder/files with a space (ex: " "), in the folder/file name.
When the application runs it crashes, I have narrowed it down to the fact that CImg does not like spaces in the path.
Every time it runs on my local machine with a space in the path I get the following error, which doesn't seem to say much.
Unhandled exception at 0x00BE05F7 in jpeg-info.exe: 0xC00000FD: Stack overflow >(parameters: 0x00000000, 0x00242000).
[CImg] * CImgIOException * [instance(0,0,0,0,00000000,non-shared)] CImg::load(): Failed to open file 'J:\uploads\41039\test name'
[CImg] * CImgIOException * cimg::fopen(): Failed to open file 'J:\uploads\41039\test name' with mode 'rb'.
the line of code it fails on is here.
const char* imagePath = filename.c_str();
CImg<unsigned char> loadImage(imagePath);
I just need to figure out a way to pass a path to CImg with spaces in the string and it not break.
Sidenote: I do have the boost filesystem installed if that makes it any easier to figure out this solution.
EDIT:
I was getting the filename two different ways with not luck on fixing this issue..
original way: (passing const char directly)
const char* filename = cimg_option("-i", "path/to/file/jpeg.jpg", "input jpeg path");
new way: (grabbing path and using boost to format it properly)
const char* getInput = cimg_option("-i", "path/to/file/jpeg.jpg", "input jpeg path");
std::string filename = boost::filesystem::absolute(getInput).string();

Related

How to open Model file for OpenCV's structured edge detector in a DLL for LabVIEW?

I've created the EdgeBoxes.cpp Example DLL for LabVIEW using OpenCV. I'm trying to open the model file in the DLL but all I get is an assertion fail. I also created VI's for morphology, Corner detection, hough transformation but never got any error messages like that.
I tried:
Every path combination using Forward slashes or back slashes.
Putting every file into the same Folder(also in C:\). (LabVIEW VI, DLL, ModelFile)
To open it in LabVIEW first with "Open/Create/Replace.vi"
To open the extracted model.yml file instead of model.yml.gz
Converting the yml file to json, txt doesn't work either
That's the point where I'm clueless:
string filename = "C:\model.yml.gz"
Ptr<StructuredEdgeDetection> pDollar; = createStructuredEdgeDetection(filename);
Error Message I'm receiving:
Error -1002 occurred at OpenCV(4.0.1-dev)
C:\OpenCV\opencv_contrib-master\modules\ximgproc\src\structured_edge_detection.cpp:432:
error: (-215:Assertion failed) modelFile.isOpened() in function
'cv::ximgproc::StructuredEdgeDetectionImpl::StructuredEdgeDetectionImpl'
I don't know how to open this file without getting this error message. Is it even possible to access a file in a DLL call. Do I have to open it somehow in the LabVIEW VI because of permission issues?
Thanks!
Update: 1
Now I tried to read the file with ifstream and it seems like I can acess the file without any Problems (Code below). So the reason why it won't work seems to be in context with OpenCV?
std::ifstream is(filename, std::ifstream::binary);
is.seekg(0, is.end);
int length = is.tellg();
is.seekg(0, is.beg);
char * buffer = new char[length];
is.read(buffer, length);
is.close();
delete[] buffer; // buffer contains the entire file
Update: 2
Now I tried to open the file like OpenCV does after calling:
createStructuredEdgeDetection(filename);
After that OpenCV tries to open the file with:
See Row 431
https://github.com/opencv/opencv_contrib/blob/master/modules/ximgproc/src/structured_edge_detection.cpp
cv::FileStorage modelFile(filename, FileStorage::READ);
if (modelFile.isOpened())
{ return -1; }
Why does it work with
ifstream::binary
Do I have to recompile the "structured_edge_detection.cpp"?
I solved my problem. All you need to do is to pay attention linking only the librarys with a "d" if you are using debug mode in Visual Studio. I was using both like:
opencv_imgproc401d.lib, opencv_imgproc401.lib, opencv.ximg....
After changing the additional linker dependencies only to the debug librarys
opencv_imgproc401d.lib;opencv_ximgproc401d.lib;opencv_core401d.lib;
everything worked fine for me.

SDL2 loading files with special characters

I got a problem, that is: in a Windows application using SDL2 & SDL2_Image, it opens image files, for later saving them with modifications on the image data.
When it opens an image without special characters (like áéíóúñ, say, "buenos aires.jpg") it works as intended. But, if there is any special character as mentioned (say, "córdoba.jpg"), SDL_Image generates an error saying "Couldn't open file". Whatever, if i use the std::ifstream flux with the exact file name that i got from the CSV file (redundant, as "córdoba.jpg" or "misiónes.jpg"), the ifstream works well... Is it an error using the special characters? UNICODE, UTF, have something to do?
A little information about the environment: Windows 10 (spanish, latin american), SDL2 & SDL2_Image (up to date versions), GCC compiler using Mingw64 7.1.0
About the software I'm trying to make: it uses a CSV form, with the names of various states of Argentina, already tried changing encoding on the .CSV. It loads images based on the names found on the CSV, changes them, and saves.
I know maybe I am missing something basic, but already depleted my resources.
IMG_Load() forwards its file argument directly to SDL_RWFromFile():
// http://hg.libsdl.org/SDL_image/file/8fee51506499/IMG.c#l125
SDL_Surface *IMG_Load(const char *file)
{
SDL_RWops *src = SDL_RWFromFile(file, "rb");
const char *ext = SDL_strrchr(file, '.');
if(ext) {
ext++;
}
if(!src) {
/* The error message has been set in SDL_RWFromFile */
return NULL;
}
return IMG_LoadTyped_RW(src, 1, ext);
}
And SDL_RWFromFile()'s file argument should be a UTF-8 string:
SDL_RWops* SDL_RWFromFile(const char* file,
const char* mode)
Function Parameters:
file: a UTF-8 string representing the filename to open
mode: an ASCII string representing the mode to be used for opening the file; see Remarks for details
So pass UTF-8 paths into IMG_Load().
C++11 has UTF-8 string literal support built-in via the u8 prefix:
IMG_Load( u8"córdoba.jpg" );

Trying to encode a GIF file using giflib

I am given image data and color table I am trying to export it as a single frame GIF using giflib. I looked into the API, but can't get it to work. The program crashes even at the first function:
GifFileType image_out;
int errorCode = 0;
char* fileName = "SomeName.gif";
image_out = *EGifOpenFileName(fileName,true, &errorCode);
It is my understanding that I first need to open a file by specifying it's name and then update it with fileHandle. Then Fill in the screen description, the extension block the image data and add the 3B ending to the file. Then use EGifSpew to export the whole gif. The problem is that I can't even use EGifOpenFileName(); The program crashes at that line.
Can someone help me the API of giflib? This problem is getting really frustrating.
Thanks.
EDIT:
For the purposes of simple encoding I do not want to specify a color table and I just want to encode a single frame GIF.
The prototype is:
GifFileType *EGifOpenFileName(char *GifFileName, bool GifTestExistance, int *ErrorCode)
You should write as
GifFileType* image_out = EGifOpenFileName(fileName,true, &errorCode);
Note GifFileType is not POD type so you should NOT copy like that.

iOS file size during write using only C/C++ APIs

Purpose: I am monitoring file writes in a particular directory on iOS using BSD kernel queues, and poll for file sizes to determine write ends (when the size stops changing). The basic idea is to refresh a folder only after any number of file copies coming from iTunes sync. I have a completely working Objective-C implementation for this but I have my reasons for needing to implement the same thing in C++ only.
Problem: The one thing stopping me is that I can't find a C or C++ API that will get the correct file size during a write. Presumably, one must exist because Objective-C's [NSFileManager attributesOfItemAtPath:] seems to work and we all know it is just calling a C API underneath.
Failed Solutions:
I have tried using stat() and lstat() to get st_size and even st_blocks for allocated block count, and they return correct sizes for most files in a directory, but when there is a file write happening that file's size never changes between poll intervals, and every subsequent file iterated in that directory have a bad size.
I have tried using fseek and ftell but they are also resulting in a very similar issue.
I have also tried modified date instead of size using stat() and st_mtimespec, and the date doesn't appear to change during a write - not that I expected it to.
Going back to NSFileManager's ability to give me the right values, does anyone have an idea what C API call that [NSFileManager attributesOfItemAtPath:] is actually using underneath?
Thanks in advance.
Update:
It appears that this has less to do with in-progress write operations and more with specific files. After closer inspection there are some files which always return a size, and other files that never return a size when using the C API (but will work fine with the Objective-C API). Even creating a copy of the "good" files the C API does not want to give a size for the copy but works fine with the original "good" file. I have both failures and successes with text (xml) files and binary (zip) files. I am using iTunes to add these files to the iPad's app's Documents directory. It is an iPad Mini Retina.
Update 2 - Answer:
Probably any of the above file size methods will work, if your path isn't invisibly trashed, like mine was. See accepted answer on why the path was trashed.
Well this weird behavior turned out to be a problem with the paths, which result in strings that will print normally, but are likely trashed in memory enough that file descriptors sometimes didn't like it (thus only occurring in certain file paths). I was using the dirent API to iterate over the files in a directory and concatenating the dir path and file name erroneously.
Bad Path Concatenation: Obviously (or apparently not-so-obvious at runtime) str-copying over three times is not going to end well.
char* fullPath = (char*)malloc(strlen(dir) + strlen(file) + 2);
strcpy(fullPath, dir);
strcpy(fullPath, "/");
strcpy(fullPath, file);
long sizeBytes = getSize(fullPath);
free(fullPath);
Correct Path Concatenation: Use proper str-concatenation.
char* fullPath = (char*)malloc(strlen(dir) + strlen(file) + 2);
strcpy(fullPath, dir);
strcat(fullPath, "/");
strcat(fullPath, file);
long sizeBytes = getSize(fullPath);
free(fullPath);
Long story short, it was sloppy work on my part, via two typos.

EM algorithm, read and save XML file

I want to save my classifier, and then when I am trying to read it back, it throws segmentation error. I tried to figure it out, and I think it is a bug with opencv.
Here is my code:
bool result = model.train(samples,Mat(),ps,&lables);
printf("Train Result %d\n",result);
CvFileStorage *fs;
fs = cvOpenFileStorage("skin_new.xml",NULL, CV_STORAGE_WRITE);
model.write_params(fs);
cvReleaseFileStorage( &fs );
CvFileStorage *fs1;
//Reading back XML file
fs1 = cvOpenFileStorage("skin_new.xml",NULL , CV_STORAGE_READ);
classifier.read_params(fs1,NULL);
cvReleaseFileStorage( &fs1 );
printf("XML reading done\n");
//the two dominating colors
Mat means = model.getMeans();//This step leads to segmentation error
I'm using OpenCV 2.3.1.
I think you are developing in Linux OS. So I think you don't have the access permission to the skin_new.xml file.
You can use
chmod 777 skin_new.xml
But it's temporary. I'm facing the same problem as well.