Need example of jpeglib-turbo that works in VS2013 x64 - c++

I'm trying to learn how to use the jpeg-turbo library. And I'm have a devil of a time getting started.
The example.c example in the doc folder, and every single example I find on the web, crashes in VS2013 when I try to read a .jpg file.
They compile fine. But when I run them they crash with an access violation error.
What I really need is a tiny working (beginner friendly) example that is known to run properly in VS2013 x64. Including the main(){} code block code.
And if there's anything special in the VS project properties that I might need to set that could be causing this crashing.
I'm pulling my hair out just trying to get one simple example working.
Thanks for the help.
*Edit-- Here is a very small example.
I've also tried to get jpeglib to run with and without using Boost/GIL
But it always crashes when loading the image: exception at 0x00000000774AE4B4 (ntdll.dll)
#include <stdio.h>
#include <assert.h>
#include <jpeglib.h>
#pragma warning(disable: 4996)
int main(int argc, char* argv[])
{
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
JSAMPARRAY buffer;
int row_stride;
//initialize error handling
cinfo.err = jpeg_std_error(&jerr);
FILE* infile;
infile = fopen("source.jpg", "rb");
assert(infile != NULL);
//initialize the decompression
jpeg_create_decompress(&cinfo);
//specify the input
jpeg_stdio_src(&cinfo, infile);
//read headers
(void)jpeg_read_header(&cinfo, TRUE);
jpeg_start_decompress(&cinfo); <----This guy seems to be the culprit
printf("width: %d, height: %d\n", cinfo.output_width, cinfo.output_height);
row_stride = cinfo.output_width * cinfo.output_components;
buffer = (*cinfo.mem->alloc_sarray)
((j_common_ptr)&cinfo, JPOOL_IMAGE, row_stride, 1);
JSAMPLE firstRed, firstGreen, firstBlue; // first pixel of each row, recycled
while (cinfo.output_scanline < cinfo.output_height)
{
(void)jpeg_read_scanlines(&cinfo, buffer, 1);
firstRed = buffer[0][0];
firstBlue = buffer[0][1];
firstGreen = buffer[0][2];
printf("R: %d, G: %d, B: %d\n", firstRed, firstBlue, firstGreen);
}
jpeg_finish_decompress(&cinfo);
return 0;
}

I found the problem.
In my VS project's Linker->Input->Additional Dependencies. I changed it to use turbojpeg-static.lib. Or jpeg-static.lib when I'm using the non turbo enhanced libraries. The turbojpeg.lib or jpeg.lib crashes for some reason when reading the image. FYI, I am using the libjpeg-turbo-1.4.2-vc64.exe version with VS2013. And this is how I got it to work.

One more very important thing that I learned that I'd like to share.
When writing to a new .jpg image. If the new image size is different than the source image. It will typically crash. Especially if the new size is larger than the source. I'm guessing this happens because it takes a much longer time to re-sample the color data to a different size. So this type of action might require it's own thread to prevent crashing. I wasted a lot of time chasing code errors and compiler settings due to this one. So watch out for that one.

Related

segmentation fault when compling c++ code

I am now days struggling at this question from my code,the code could be complied successfully but when I ran the binary file, the segmentation fault would occured and here below was the problem:
Program received signal SIGSEGV, Segmentation fault. _int_malloc (av=av#entry=0x7ffff6adfb20 <main_arena>, bytes=bytes#entry=15859713) at malloc.c:3802 malloc.c: No such file or directory.
Env:ubuntu 16.04 VM workstation
Com: g++, version:5.4.0
c++:c++11
Lib: imebra 5.0.1
Here is my code:
#include <imebra/imebra.h>
#include <iostream>
#include <fstream>
#include <stdlib.h>
#define img_height 2816
#define img_width 2816
#define img_bit 2
#define img_size img_height*img_width*img_bit //15.1MB
using namespace std;
//MONOCHROME1: indicates that the greyscale ranges from bright to dark with ascending pixel values
//MONOCHROME2: indicates that the greyscale ranges from dark to bright with ascending pixel values
/*
create an Image object
fill the image object with raw data
create a DICOM dataset
add the image to the DICOM dataset
fill all the necessary DICOM tags (e.g. sop class, instance, patient name, etc)
save the DICOM dataset
*/
int main()
{
//ifstream mydata("/home/lixingyu/GH1.raw",ios::binary);
//uint32_t *pImgData = (uint32_t *)malloc(img_size*sizeof(uint32_t));
//mydata.read(pImgData,img_size);
FILE *fp = NULL;
fp = fopen("/home/lixingyu/123.raw","rb");
uint32_t *pImgData = new (std::nothrow) uint32_t (img_size);
fread(pImgData,sizeof(uint32_t),img_size,fp);
cout<<"success"<<endl;
/*---------program stop here -------*/
// Creat an image 500 pixels wide , 400 pixels height
// each sample is a 16 bit unsigned value, the colorspace
// is monochrome_2, the higher bit used is 15
// imebra ::MutableImage image(500,400,imebra::bitDepth_t::depthU16,"MONOCHROME_2",15);
imebra ::MutableImage image(img_height,img_width,imebra::bitDepth_t::depthU16,"MONOCHROME2",15);
// 1. Fill the image with data
// We use a writing data handler to write into the image.
// The data is committed into the image only when the writing
// data handler goes out of scope.
imebra::WritingDataHandlerNumeric writeIntoImage(image.getWritingDataHandler());
for (size_t y=0;y!=img_width;++y)
{
for (size_t x=0; x!= img_height; ++x)
{
writeIntoImage.setUnsignedLong(y*img_height+x,pImgData[y*img_height+x]);
}
}
// specify the tansfer syntax and the charset
imebra::charsetsList_t charsets;
charsets.push_back("ISO 2022 IR 6");
//Explicit VR little endian
imebra::MutableDataSet dataSet("1.2.840.10008.1.2.1",charsets);
// add the image to the dataSet
dataSet.setImage(0,image,imebra::imageQuality_t::veryHigh);
// set the patient name
dataSet.setUnicodePatientName(imebra::TagId(imebra::tagId_t::PatientName_0010_0010),imebra::UnicodePatientName(L"fjx",L"",L""));
// save to a file
imebra::CodecFactory::save(dataSet,"GH1.dcm",imebra::codecType_t::dicom);
free(pImgData);
}
When I use gdb to debug my code, the question occured and I have changed my stack size to 100MB,but then the segementation fault would occure.
Maybe something wrong with Dynamic memory application??
Could anyone help me out?
FYI,The func of imebra::XXX are all from imebra lib.
You are not allowed to call free on memory allocated by new. That causes undefined behavior. You must call delete instead.
You are also allocating only one uint32_t (and initialing it with the value img_size), not an array of img_size many. For that you would need new (std::nothrow) uint32_t[img_size]; instead (and later delete[] instead of delete). So you are going to write out-of-bounds with fread.
You also need to check that the return value of new(std::nothrow) is not a null pointer, which would happen on allocation failure. If you use the throwing version, then you won't need that check.
Please don't use new like this though and use std::vector instead. malloc in C++ is even worse than new.
Similarly, don't use the C IO library in C++. Use std::ifstream instead.

Run-time check Failure #2 , while using API for saving image frame

MSVS 2010 , Windows 7
I am using an API to access camera features.
The following function displays a frame and saves it.
void DisplayThread::OnBufferDisplay( PvBuffer *aBuffer )
{
mDisplayWnd->Display( *aBuffer ); //displaying frame
//Now let us try to save the frame with name of the form %Y%m%d%H%M%S.bmp
system("mkdir D:\\ABCD" );
struct tm *tm;
int count;
time_t t;
char str_time[20];
t = time(NULL);
tm = localtime(&t);
strftime(str_time, sizeof(str_time), "%Y%m%d%H%M%S.bmp", tm); //name of the frame
char name[1000]; //sufficient space
sprintf(name,"%s",str_time);
char path[]="D:\\ABCD";
strcat(path,name); //path =path+"\\"+name;
// char* str=(char*)(void*)Marshal::StringToHGlobalAnsi(path);
PvString lFilename( path );
PvString lCompleteFileName( lFilename );
PvBufferWriter lBufferWriter; //The following function saves image
PvResult lResult = lBufferWriter.Store( aBuffer, lCompleteFileName, PvBufferFormatBMP );
}
The name of the bmp file that is saved is of the form %Y%m%d%H%M%S.bmp
The program builds perfectly fine , even display is coming correctly,
but the following error message pops up:
It looks like something is wrong with the memory allocation with the variable 'name'.
But I have allocated sufficient space, even then I am getting this error.
Why it is happening ?
Kindly let me know if more info is required to debug this.
Note: The value returned by lBufferWriter.Store() is 'OK' (indicating that buffer/frame writing was successful), but no file is getting saved. I guess this is because of the run-time check failure I am getting.
Please help.
Your path[] array size is 8 and it is too small to hold the string after concatenation.
As this path variable is on the stack, it is corrupting your stack.
So, your buffer should be large enough to hold the data that you want to put into it.
In your case Just change the line to:
char path[1024]="D:\\ABCD";

Reading Raw RGB video file in C++

I am doing my assignment to read a .rgb video file and display it in the window. I have only known how to read and display an image in C++. What should I do when reading the video and display it frame by frame. I don't want to use third party libraries, just pure C++ and windows programming.
My idea is: firstly load the whole video file into the program using fopen and allocate the buffer for it. Then just like display an image, I wanna treat the whole video as an array of frames, so after rendering the first frame, I will go to the next frame. In addition, how to keep the video display at a constant fps? If you have any learning resources or coding pieces, it would be very helpful!
Thanks
Since you haven't mentioned platform you are using.
But this snippet will help you to read file frame by frame.
#include <stdio.h>
int main()
{
FILE * fp = NULL;
int size = 800 * 600 * 2;
unsigned char * rawData = NULL;
fp = fopen("raw.rgb", "r+b");
rawData = (unsigned char *)malloc(size);
if (NULL == rawData)
return -1;
if (fp)
{
while(!feof(fp))
{
fread(rawData, size, 1, fp);
// GOT FRAME
}
fclose(fp);
fp = NULL;
}
}
Doing this without using any third-party library will be a lot of lot of works!
You may use the OpenCV library to do the work. Check http://opencv.org/

Reading file with fread() in reverse order causes memory leak?

I have a program that basically does this:
Opens some binary file
Reads the file backwards (by backwards, I mean it starts near EOF, and ends reading at beginning of file, i.e. reads the file "right-to-left"), using 4MB chunks
Closes the file
My question is: why memory consumption looks like below, even though there are no obvious memory leaks in my attached code?
Here's the source of program that was run to obtain above image:
#include <stdio.h>
#include <string.h>
int main(void)
{
//allocate stuff
const int bufferSize = 4*1024*1024;
FILE *fileHandle = fopen("./input.txt", "rb");
if (!fileHandle)
{
fprintf(stderr, "No file for you\n");
return 1;
}
unsigned char *buffer = new unsigned char[bufferSize];
if (!buffer)
{
fprintf(stderr, "No buffer for you\n");
return 1;
}
//get file size. file can be BIG, hence the fseeko() and ftello()
//instead of fseek() and ftell().
fseeko(fileHandle, 0, SEEK_END);
off_t totalSize = ftello(fileHandle);
fseeko(fileHandle, 0, SEEK_SET);
//read the file... in reverse order. This is important.
for (off_t pos = totalSize - bufferSize, j = 0;
pos >= 0;
pos -= bufferSize, j ++)
{
if (j % 10 == 0)
{
fprintf(stderr,
"reading like crazy: %lld / %lld\n",
pos, totalSize);
}
/*
* below is the heart of the problem. see notes below
*/
//seek to desired position
fseeko(fileHandle, pos, SEEK_SET);
//read the chunk
fread(buffer, sizeof(unsigned char), bufferSize, fileHandle);
}
fclose(fileHandle);
delete []buffer;
}
I have also following observations:
Even though RAM usage jumps by 1GB, the whole program uses only 5MB thorough whole execution.
Commenting call to fread() out makes memory leak go away. This is weird, since I don't allocate anything anywhere near it, that could trigger memory leak...
Also, reading the file normally instead of backwards (= commenting call to fseeko() out), makes memory leak go away as well. This is the ultra-weird part.
Further information...
Following doesn't help:
Checking results of fread() - yields nothing out of ordinary.
Switching to normal, 32-bit fseek and ftell.
Doing stuff like setbuf(fileHandle, NULL).
Doing stuff like setvbuf(fileHandle, NULL, _IONBF, *any integer*).
Compiled with g++ 4.5.3 on Windows 7 via cygwin and mingw; without any optimalizations, just g++ test.cpp -o test. Both present such behaviour.
The file used in tests was 4GB long, full of zeros.
The weird pause in the middle of the chart could be explained with some kind of temporary I/O hangup, unrelated to this question.
Finally, if I wrap reading in infinite loop... the memory usage stops increasing after first iteration.
I think it has to do with some kind of internal cache building up till it's filled with whole file. How does it really work behind the scenes? How can I prevent that in a portable way??
I think, this is more an OS issue (or even an OS resource use reporting issue) than an issue with your program. Of course, it only uses 5 MB of memory: 1 MB for itself (libs, stack etc.) and 4 MB for the buffer. Whenever you do a fread(), the OS seems to "bind" part of the file to your process, and seems to release it not at the same speed. As memory use on your machine is low, this is not a problem: The OS just keeps the already read data "hanging around" longer than necessary, probably assuming, that your application might read it again, soon, and then it doesn't have to do that binding again.
If memory pressure was higher, than the OS is very likely to unbind the memory faster, so that jump on your memory usage history would be smaller.
I had the exact same problem, although in Java but it doesn't matter in this context. I solved it by reading much bigger chunks at a time. I also read 4Mb size chunks, but when I increased it to 100-200 Mb the problem went away. Perhaps it'll do that for you as well. I'm on Windows 7.

Reading a file located in memory with libavformat

I'm currently trying to read small video files sent from a server
In order to read a file using libavformat, you are supposed to call
av_open_input_file(&avFormatContext, "C:\\path\\to\\video.avi", 0, 0, 0);
The problem is that in this case the file is not on the disk, but in memory.
What I'm doing for the moment is downloading the file, writing it on the disk using a temporary name, and then calling av_open_input_file with the temporary file name, which is not a very clean solution.
In fact what I want is a function like av_open_custom(&avFormatContext, &myReadFunction, &mySeekFunction); but I didn't find any in the documentation.
I guess it is technically possible, since the name of the file is not something that helps the library determine which format it is using.
So is there a function like this, or an alternative to av_open_input_file?
It's funny how I always find the solution by myself right after I post the question on this site, even though I've been working on this problem for hours.
In fact you have to initialize avFormatContext->pb before calling av_open_input, and pass to it a fake filename.
This is not written in the documentation but in a commentary directly in the library's source code.
Example code if you want to load from an istream (untested, just so somebody which has the same problem can get the idea)
static int readFunction(void* opaque, uint8_t* buf, int buf_size) {
auto& me = *reinterpret_cast<std::istream*>(opaque);
me.read(reinterpret_cast<char*>(buf), buf_size);
return me.gcount();
}
std::ifstream stream("file.avi", std::ios::binary);
const std::shared_ptr<unsigned char> buffer(reinterpret_cast<unsigned char*>(av_malloc(8192)), &av_free);
const std::shared_ptr<AVIOContext> avioContext(avio_alloc_context(buffer.get(), 8192, 0, reinterpret_cast<void*>(static_cast<std::istream*>(&stream)), &readFunction, nullptr, nullptr), &av_free);
const auto avFormat = std::shared_ptr<AVFormatContext>(avformat_alloc_context(), &avformat_free_context);
auto avFormatPtr = avFormat.get();
avFormat->pb = avioContext.get();
avformat_open_input(&avFormatPtr, "dummyFilename", nullptr, nullptr);
This is great information and helped me out quite a bit, but there are a couple of issues people should be aware of. libavformat can and will mess with your buffer that you gave to avio_alloc_context. This leads to really annoying double-free errors or possibly memory leaks. When I started searching for the problem, I found https://lists.ffmpeg.org/pipermail/libav-user/2012-December/003257.html which nailed it perfectly.
My workaround when cleaning up from this work is to just go ahead and call
av_free(avioContext->buffer)
and then setting your own buffer pointer (that you allocated for your avio_alloc_context call) to NULL if you care.
Tomaka17's excellent answer gave me a good start toward solving an analogous problem using Qt QIODevice rather than std::istream. I found I needed to blend aspects of Tomaka17's solution, with aspects of the related experience at http://cdry.wordpress.com/2009/09/09/using-custom-io-callbacks-with-ffmpeg/
My custom Read function looks like this:
int readFunction(void* opaque, uint8_t* buf, int buf_size)
{
QIODevice* stream = (QIODevice*)opaque;
int numBytes = stream->read((char*)buf, buf_size);
return numBytes;
}
...but I also needed to create a custom Seek function:
int64_t seekFunction(void* opaque, int64_t offset, int whence)
{
if (whence == AVSEEK_SIZE)
return -1; // I don't know "size of my handle in bytes"
QIODevice* stream = (QIODevice*)opaque;
if (stream->isSequential())
return -1; // cannot seek a sequential stream
if (! stream->seek(offset) )
return -1;
return stream->pos();
}
...and I tied it together like this:
...
const int ioBufferSize = 32768;
unsigned char * ioBuffer = (unsigned char *)av_malloc(ioBufferSize + FF_INPUT_BUFFER_PADDING_SIZE); // can get av_free()ed by libav
AVIOContext * avioContext = avio_alloc_context(ioBuffer, ioBufferSize, 0, (void*)(&fileStream), &readFunction, NULL, &seekFunction);
AVFormatContext * container = avformat_alloc_context();
container->pb = avioContext;
avformat_open_input(&container, "dummyFileName", NULL, NULL);
...
Note I have not yet worked out the memory management issues.