Debug Assertion Failed - c++

Using Visual Studio 2010, C++.
Programming level: beginner.
I have a code from a book Windows Game Programming Gurus and up until now have managed all problems i have stumbled upon.
But this i don't know what it is.
Here is a screenshot of an error:
That is one nice 8-bit image...
Now, it says File: f:\dd...
In my case f: drive is empty cd-rom...
This is the line where i think error is happening:
_lseek(file_handle, -((int) (bitmap->bitmapinfoheader.biSizeImage)), SEEK_END);
What is this thing?

The f:\dd directory is where the source code of the "C Runtime Library" (CRT) was located, when it was built. Since Microsoft built that, it doesn't correspond to your F: drive.
Anyway, the CRT detected that one of the file handles is wrong. You passed it to the CRT, so you should check why it's wrong. If you press Retry, you'll be put in the debugger. There you can see which of your functions put in the wrong file handle.
It won't tell you why the handle is wrong, though. A common reason is that you tried to open a file, and forgot to check if it succeeded. You only get a file handle if the file name is valid, and you're allowed to read that file.

The assertion happens in the C library. It makes sure you pass valid argument to the lseek() function.
You probably did not check for errors after doing open() or creat() on the file.

Looks like your file_handle is wrong. Are you sure the opening of your image succeeded ?

Full function code which uses C++ ifstream instead of low-level IO functions.
Jonathan and i tried to make _lseek work only to conclude that it doesn't work...
Don't know if that is entirely true, maybe there is some way it works correctly.
If you (the reader) know, feel free to message me.
The function now works, although main program displays image wrongly, but that is beside matter of this question, _lseek thing is solved :)
int Load_Bitmap_File(BITMAP_FILE_PTR bitmap, char *filename)
{
int file_handle = 0; // the file handle
int index = 0; // looping index
int bitmapWidth = 0;
int bitmapHeight = 0;
int bitmapSize = 0;
UCHAR *temp_buffer = NULL; // used to convert 24 bit images to 16 bit
streampos pos_cur;
ifstream bitmapFile = ifstream ();
bitmapFile.open (filename, ifstream::in);
if (! bitmapFile.is_open ())
{
printError ("Error: OpenFile function failure. ");
// abort
return(0);
}
// load the bitmap file header:
//_lread(file_handle, &(bitmap->bitmapfileheader), sizeof(BITMAPFILEHEADER));
bitmapFile.read ((char *) &(bitmap->bitmapfileheader), sizeof (BITMAPFILEHEADER));
// test if this is a bitmap file
if (bitmap->bitmapfileheader.bfType != BITMAP_ID)
{
// close the file
//_lclose(file_handle);
bitmapFile.close ();
printError ("error: wrong bitmap type");
cout << "error: wrong bitmap type" << endl;
// return error
return(0);
} // end if
// now we know this is a bitmap, so read in all the sections.
if (bitmap->bitmapinfoheader.biSizeImage == 0)
printError ("error: biSizeImage equals 0");
// now the bitmap infoheader:
//_lread(file_handle, &bitmap->bitmapinfoheader, sizeof(BITMAPINFOHEADER));
bitmapFile.seekg (sizeof (BITMAPFILEHEADER), ios::beg);
pos_cur = bitmapFile.tellg (); // save current stream position
bitmapFile.read ((char *) &(bitmap->bitmapinfoheader), sizeof (BITMAPINFOHEADER));
//cout << bitmap->bitmapinfoheader.biBitCount << endl;
// now load the color palette if there is one
if (bitmap->bitmapinfoheader.biBitCount == 8)
{
//_lread(file_handle, &bitmap->palette, MAX_COLORS_PALETTE * sizeof(PALETTEENTRY));
// not tested:
bitmapFile.read ((char *) &(bitmap->palette), MAX_COLORS_PALETTE * sizeof(PALETTEENTRY));
// now set all the flags in the palette correctly and fix the reversed
// BGR RGBQUAD data format
for (index = 0; index < MAX_COLORS_PALETTE; index++)
{
// reverse the red and green fields
int temp_color = bitmap->palette[index].peRed;
bitmap->palette[index].peRed = bitmap->palette[index].peBlue;
bitmap->palette[index].peBlue = temp_color;
// always set the flags word to this
bitmap->palette[index].peFlags = PC_NOCOLLAPSE;
} // end for index
} // end if
bitmapWidth = bitmap->bitmapinfoheader.biWidth * (bitmap->bitmapinfoheader.biBitCount / 8);
bitmapHeight = bitmap->bitmapinfoheader.biHeight;
bitmapSize = bitmapWidth * bitmapHeight;
// finally the image data itself:
//_lseek(file_handle, -((int) (bitmap->bitmapinfoheader.biSizeImage)), SEEK_END);
bitmapFile.seekg (-((int) bitmapSize), ios::end);
//bitmapFile.seekg (sizeof (BITMAPINFOHEADER) + sizeof (BITMAPFILEHEADER) + MAX_COLORS_PALETTE * sizeof(PALETTEENTRY), ios::beg);
// now read in the image, if the image is 8 or 16 bit then simply read it
// but if its 24 bit then read it into a temporary area and then convert
// it to a 16 bit image
if (bitmap->bitmapinfoheader.biBitCount == 8 ||
bitmap->bitmapinfoheader.biBitCount == 16 ||
bitmap->bitmapinfoheader.biBitCount == 24)
{
// delete the last image if there was one
if (bitmap->buffer)
free(bitmap->buffer);
// allocate the memory for the image
//if (!(bitmap->buffer = (UCHAR *) malloc (bitmap->bitmapinfoheader.biSizeImage))) // error: biSizeImage == 0 !
if (!(bitmap->buffer = (UCHAR *) malloc (bitmapSize)))
{
// close the file
//_lclose(file_handle);
bitmapFile.close ();
// return error
return(0);
} // end if
// now read it in
//_lread(file_handle, bitmap->buffer, bitmap->bitmapinfoheader.biSizeImage);
bitmapFile.read ((char *) (bitmap->buffer), bitmapSize);
} // end if
else
{
// serious problem
return(0);
} // end else
// close the file
//_lclose(file_handle);
bitmapFile.close ();
// flip the bitmap
Flip_Bitmap(bitmap->buffer,
bitmap->bitmapinfoheader.biWidth * (bitmap->bitmapinfoheader.biBitCount / 8),
bitmap->bitmapinfoheader.biHeight);
//cout << "biSizeImage: " << bitmap->bitmapinfoheader.biSizeImage << endl;
//cout << (bitmap->bitmapinfoheader.biWidth * (bitmap->bitmapinfoheader.biBitCount / 8)) * bitmap->bitmapinfoheader.biHeight << endl;
// return success
return(1);
} // end Load_Bitmap_File
///////////////////////////////////////////////////////////
Current full source code:
http://pastebin.com/QQ6fMD7P
Expiration date is set to never.
Thanks to all people contributing to this question!

lseek crashes with the debug assertion failed error because it is a 16bit function. I found this out by looking at a chart of 16bit and 32bit functions on the microsoft website.
Solution is to use _llseek. _llseek is a 32bit function and can run on 64bit computers.
You do not need to change any parameters from _lseek to use _llseek.
_lseek(file_handle, -((int) (bitmap->bitmapinfoheader.biSizeImage)), SEEK_END);
becomes
_llseek(file_handle, -((int) (bitmap->bitmapinfoheader.biSizeImage)), SEEK_END);

Related

libjpeg-turbo segmentation fault when writing scanlines to file c++

I have the following code running on windows 10 in QT Creator, I am trying to write rgb formatted data to a jpeg file using the libjpeg-turbo library
#include <stdio.h>
#include <jpeglib.h>
void writeJpeg(const char *filename, std::vector<unsigned char> &image, uint w, uint h) {
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
FILE *outfile;
JSAMPROW row_pointer[1];
int row_stride;
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
if ((outfile = fopen(filename, "wb")) == NULL) {
fprintf(stderr, "can't open %s\n", filename);
exit(1);
}
jpeg_stdio_dest(&cinfo, outfile);
cinfo.image_width = w;
cinfo.image_height = h;
cinfo.input_components = 3;
cinfo.in_color_space = JCS_RGB;
jpeg_set_defaults(&cinfo);
jpeg_set_quality(&cinfo, 100, true);
jpeg_start_compress(&cinfo, true);
row_stride = w * 3;
JSAMPLE *arr = image.data();
while (cinfo.next_scanline < cinfo.image_height) {
row_pointer[0] = &arr[cinfo.next_scanline * row_stride];
(void)jpeg_write_scanlines(&cinfo, row_pointer, 1);
}
jpeg_finish_compress(&cinfo);
fclose(outfile);
jpeg_destroy_compress(&cinfo);
}
and get SIGSEGV on (void)jpeg_write_scanlines(&cinfo, row_pointer, 1); in this portion of the code
while (cinfo.next_scanline < cinfo.image_height) {
row_pointer[0] = &arr[cinfo.next_scanline * row_stride];
(void)jpeg_write_scanlines(&cinfo, row_pointer, 1);
}
I have tried debugging, but im not entirely sure what the best way to do that is.
I have found out that it crashes after 15 iterations of the loop and my best guess is that I have converted the data poorly from the vector into the pointer array.
Anyways, I cannot figure out how to better allocate the memory or if this is even the problem
Any ideas on what I'm doing wrong plus any tips on how to actually debug this in the future would be greatly appreciated.
EDIT
I changed true to TRUE and printed out every byte in the array like so
while (cinfo.next_scanline < cinfo.image_height) {
row_pointer[0] = &arr[cinfo.next_scanline * row_stride];
QString out = "";
for (int i = 0; i<row_stride; i++)
out += QString::number(row_pointer[0][i]) + " ";
qDebug() << "\n\n==============" << cinfo.next_scanline << "==============\n\n";
qDebug() << out;
(void)jpeg_write_scanlines(&cinfo, row_pointer, 1);
}
and after stepping through its execution, it is able to output all the bytes, yet still crashes on write_jpeg_scanlines
I also noticed some random text being printed out at the end of each scanline
ex:
255 255 255 25520003200!-�U3 on row 12
255 255 255 255eencoded�/�Rf on row 13
231 230 230 255,autoder�)�Pu on row 15, the data where it crashes
not sure if this is just garbage at the end of the pointer, or a symptom of qDebug but it could confirm antons idea of corrupted image data
I see nothing wrong in your code, except C++ bool value true is passed instead of C value TRUE in these calls:
jpeg_set_quality(&cinfo, 100, true);
...
jpeg_start_compress(&cinfo, true);
It may lead to weird crashes sometimes.
Also, the first thing I would try in this case - what if just to output somewhere all the bytes of every row arr[cinfo.next_scanline * row_stride] - does it crash? If it does, possibly you have error in other code preparing the image data.
UPD.: most probably the problem with original code was #include <jpeglib.h> - that should force to search for jpeglib.h in system directories instead of the libjpeg-turbo directories. That could be solved by using #include "jpeglib.h" and specifying the path to libjpeg-turbo include directory to compiler.
Thanks for all of the help, As #AntonMalyshev pointed out, the issue was an incorrect use of libjpeg.
First off I have libjpeg-turbo installed and while it includes a library for libjpeg im sure a better practice would be to just install libjpeg directly. I ended up using #include <turbojpeg.h>.
Secondly, the example code I posted, seems to be only compatible with base libjpeg Using this post and the libjpeg-turbo api I was able to come up with a solution that works.
Thanks, Ethan

Finding the rendezvous structure of tracee (program being debugged)

I need debugger I am writing to give me the name of shared lib that program being debugged is linking with, or loading dynamically. I get the rendezvous structure as described in link.h, and answers to other questions, using DT_DEBUG, in the loop over _DYNAMIC[].
First, debugger never hits the break point set at r_brk.
Then I put a break in the program being debugged, and use link_map to print all loaded libraries. It only prints libraries loaded by the debugger, not the program being debugged.
It seems that, the rendezvous structure I am getting belongs to the debugger itself. If so, could you please tell me how to get the rendezvous structure of the program I am debugging? If what I am doing must work, your confirmation will be helpful, perhaps with some hint as to what else might be needed.
Thank you.
// You need to include <link.h>. All structures are explained
// in elf(5) manual pages.
// Caller has opened "prog_name", the debugee, and fd is the
// file descriptor. You can send the name instead, and do open()
// here.
// Debugger is tracing the debugee, so we are using ptrace().
void getRandezvousStructure(int fd, pid_t pd, r_debug& rendezvous) {
Elf64_Ehdr elfHeader;
char* elfHdrPtr = (char*) &elfHeader;
read(fd, elfHdrPtr, sizeof(elfHeader));
Elf64_Addr debugeeEntry = elfHeader.e_entry; // entry point of debugee
// Here, set a break at debugeeEntry, and after "PTRACE_CONT",
// and waitpid(), remove the break, and set rip back to debugeeEntry.
// After that, here it goes.
lseek(fd, elfHeader.e_shoff, SEEK_SET); // offset of section header
Elf64_Shdr secHeader;
elfHdrPtr = (char*) &secHeader;
Elf64_Dyn* dynPtr;
// Keep reading until we get: secHeader.sh_addr.
// That is the address of _DYNAMIC.
for (int i = 0; i < elfHeader.e_shnum; i++) {
read(fd, elfHdrPtr, elfHeader.e_shentsize);
if (secHeader.sh_type == SHT_DYNAMIC) {
dynPtr = (Elf64_Dyn*) secHeader.sh_addr; // address of _DYNAMIC
break;
}
}
// Here, we get "dynPtr->d_un.d_ptr" which points to rendezvous
// structure, r_debug
uint64_t data;
for (;; dynPtr++) {
data = ptrace(PTRACE_PEEKDATA, pd, dynPtr, 0);
if (data == DT_NULL) break;
if (data == DT_DEBUG) {
data = ptrace(PTRACE_PEEKDATA, pd, (uint64_t) dynPtr + 8 , 0);
break;
}
}
// Using ptrace() we read sufficient chunk of memory of debugee
// to copy to rendezvous.
int ren_size = sizeof(rendezvous);
char* buffer = new char[2 * ren_size];
char* p = buffer;
int total = 0;
uint64_t value;
for (;;) {
value = ptrace(PTRACE_PEEKDATA, pd, data, 0);
memcpy(p, &value, sizeof(value));
total += sizeof(value);
if (total > ren_size + sizeof(value)) break;
data += sizeof(data);
p += sizeof(data);
}
// Finally, copy the memory to rendezvous, which was
// passed by reference.
memcpy(&rendezvous, buffer, ren_size);
delete [] buffer;
}

Reading COM port in c++, getting errors

First time poster long time reader.
I've been playing round with reading in data from a bluetooth GPS unit.
I can connect to it using hyperterm and see the data
The following log is from the hyperterm
$GPRMC,195307.109,A,5208.2241,N,00027.7689,W,000.0,345.8,310712,,,A*7E
$GPVTG,345.8,T,,M,000.0,N,000.0,K,A*07
$GPGGA,195308.109,5208.2242,N,00027.7688,W,1,04,2.1,58.9,M,47.3,M,,0000*7E
$GPGSA,A,3,19,03,11,22,,,,,,,,,5.5,2.1,5.0*3F
$GPRMC,195308.109,A,5208.2242,N,00027.7688,W,000.0,345.8,310712,,,A*73
$GPVTG,345.8,T,,M,000.0,N,000.0,K,A*07
$GPGGA,195309.109,5208.2243,N,00027.7688,W,1,04,2.1,58.9,M,47.3,M,,0000*7E
END LOG
The following log is from my C++ program
$GPGSV,3,3,12,14,20,105,16,28,18,323,,08,07,288,,16,01,178,*7A
$GPRMC,195,3,2ÿþÿÿÿL.š945.109,A,5208.2386,N,00027.7592,W,000.0,169.5,8,323,,08,07,288,,16,01,178,*7A
$GPRMC,195,3,2ÿþÿÿÿL.š310712,,,A*70
$GPVTG,169.5,T,,M,000.0,N,000.0,K,A*06
8,07,288,,16,01,178,*7A
$GPRMC,195,3,2ÿþÿÿÿL.š310712,,,A*70
$GPVTG,169.5,T,,M,000.0,N,000.0,K,A*06
8,07,288,,16,01,178,*7A
$GPRMC,195,3,2ÿþÿÿÿL.š$GPGGA,195946.109,5208.2386,N,00027.7592,W,1.0,K,A*06
8,07,288,,16,01,178,*7A
END LOG
THE PROBLEM
I've left the line feeds as they come, the C++ output has extra line feeds, not sure why?
The C++ log also has some funky chars...?
The Code
for (int n=0;n<100;n++) {
char INBUFFER[100];
cv::waitKey(1000);
bStatus = ReadFile(comport, // Handle
&INBUFFER, // Incoming data
100, // Number of bytes to read
&bytes_read, // Number of bytes read
NULL);
cout << "bStatus " << bStatus << endl;
if (bStatus != 0)
{
// error processing code goes here
}
LogFile << INBUFFER;
}
I'm using settings...
comSettings.BaudRate = 2400;
comSettings.StopBits = ONESTOPBIT;
comSettings.ByteSize = 8;
comSettings.Parity = NOPARITY;
comSettings.fParity = FALSE;
...which as far as I can tell are the same as the settings used by hyperterm.
Any hints on what I'm doing wrong?
cheers!
UPDATE
So after updating to use bytes_read and account for the extra LF at the end of NMEA data I now have...
if (bytes_read!=0) {
for (int i=0; i < bytes_read; i++) {
LogFile << INBUFFER[i];
}
}
Which appears to have fixed things!
$GPGGA,215057.026,5208.2189,N,00027.7349,W,1,04,6.8,244.6,M,47.3,M,,0000*41
$GPGSA,A,3,32,11,01,19,,,,,,,,,9.7,6.8,7.0*3D
$GPRMC,215057.026,A,5208.2189,N,00027.7349,W,002.0,208.7,310712,,,A*74
$GPVTG,208.7,T,,M,002.0,N,003.8,K,A*09
$GPGGA,215058.026,5208.2166,N,00027.7333,W,1,04,6.8,243.1,M,47.3,M,,0000*42
Thanks folks, your help was much appreciated.
You have a bytes_read var, but you don't do anything with it? Seems to me that you're dumping the entire INBUFFER to the file, no matter how many/few bytes are actually loaded into it?

Libzip - read file contents from zip

I using libzip to work with zip files and everything goes fine, until i need to read file from zip
I need to read just a whole text files, so it will be great to achieve something like PHP "file_get_contents" function.
To read file from zip there is a function "int
zip_fread(struct zip_file *file, void *buf, zip_uint64_t nbytes)".
Main problem what i don't know what size of buf must be and how many nbytes i must read (well i need to read whole file, but files have different size). I can just do a big buffer to fit them all and read all it's size, or do a while loop until fread return -1 but i don't think it's rational option.
You can try using zip_stat to get file size.
http://linux.die.net/man/3/zip_stat
I haven't used the libzip interface but from what you write it seems to look very similar to a file interface: once you got a handle to the stream you keep calling zip_fread() until this function return an error (ir, possibly, less than requested bytes). The buffer you pass in us just a reasonably size temporary buffer where the data is communicated.
Personally I would probably create a stream buffer for this so once the file in the zip archive is set up it can be read using the conventional I/O stream methods. This would look something like this:
struct zipbuf: std::streambuf {
zipbuf(???): file_(???) {}
private:
zip_file* file_;
enum { s_size = 8196 };
char buffer_[s_size];
int underflow() {
int rc(zip_fread(this->file_, this->buffer_, s_size));
this->setg(this->buffer_, this->buffer_,
this->buffer_ + std::max(0, rc));
return this->gptr() == this->egptr()
? traits_type::eof()
: traits_type::to_int_type(*this->gptr());
}
};
With this stream buffer you should be able to create an std::istream and read the file into whatever structure you need:
zipbuf buf(???);
std::istream in(&buf);
...
Obviously, this code isn't tested or compiled. However, when you replace the ??? with whatever is needed to open the zip file, I'd think this should pretty much work.
Here is a routine I wrote that extracts data from a zip-stream and prints out a line at a time. This uses zlib, not libzip, but if this code is useful to you, feel free to use it:
#
# compile with -lz option in order to link in the zlib library
#
#include <zlib.h>
#define Z_CHUNK 2097152
int unzipFile(const char *fName)
{
z_stream zStream;
char *zRemainderBuf = malloc(1);
unsigned char zInBuf[Z_CHUNK];
unsigned char zOutBuf[Z_CHUNK];
char zLineBuf[Z_CHUNK];
unsigned int zHave, zBufIdx, zBufOffset, zOutBufIdx;
int zError;
FILE *inFp = fopen(fName, "rbR");
if (!inFp) { fprintf(stderr, "could not open file: %s\n", fName); return EXIT_FAILURE; }
zStream.zalloc = Z_NULL;
zStream.zfree = Z_NULL;
zStream.opaque = Z_NULL;
zStream.avail_in = 0;
zStream.next_in = Z_NULL;
zError = inflateInit2(&zStream, (15+32)); /* cf. http://www.zlib.net/manual.html */
if (zError != Z_OK) { fprintf(stderr, "could not initialize z-stream\n"); return EXIT_FAILURE; }
*zRemainderBuf = '\0';
do {
zStream.avail_in = fread(zInBuf, 1, Z_CHUNK, inFp);
if (zStream.avail_in == 0)
break;
zStream.next_in = zInBuf;
do {
zStream.avail_out = Z_CHUNK;
zStream.next_out = zOutBuf;
zError = inflate(&zStream, Z_NO_FLUSH);
switch (zError) {
case Z_NEED_DICT: { fprintf(stderr, "Z-stream needs dictionary!\n"); return EXIT_FAILURE; }
case Z_DATA_ERROR: { fprintf(stderr, "Z-stream suffered data error!\n"); return EXIT_FAILURE; }
case Z_MEM_ERROR: { fprintf(stderr, "Z-stream suffered memory error!\n"); return EXIT_FAILURE; }
}
zHave = Z_CHUNK - zStream.avail_out;
zOutBuf[zHave] = '\0';
/* copy remainder buffer onto line buffer, if not NULL */
if (zRemainderBuf) {
strncpy(zLineBuf, zRemainderBuf, strlen(zRemainderBuf));
zBufOffset = strlen(zRemainderBuf);
}
else
zBufOffset = 0;
/* read through zOutBuf for newlines */
for (zBufIdx = zBufOffset, zOutBufIdx = 0; zOutBufIdx < zHave; zBufIdx++, zOutBufIdx++) {
zLineBuf[zBufIdx] = zOutBuf[zOutBufIdx];
if (zLineBuf[zBufIdx] == '\n') {
zLineBuf[zBufIdx] = '\0';
zBufIdx = -1;
fprintf(stdout, "%s\n", zLineBuf);
}
}
/* copy some of line buffer onto the remainder buffer, if there are remnants from the z-stream */
if (strlen(zLineBuf) > 0) {
if (strlen(zLineBuf) > strlen(zRemainderBuf)) {
/* to minimize the chance of doing another (expensive) malloc, we double the length of zRemainderBuf */
free(zRemainderBuf);
zRemainderBuf = malloc(strlen(zLineBuf) * 2);
}
strncpy(zRemainderBuf, zLineBuf, zBufIdx);
zRemainderBuf[zBufIdx] = '\0';
}
} while (zStream.avail_out == 0);
} while (zError != Z_STREAM_END);
/* close gzip stream */
zError = inflateEnd(&zStream);
if (zError != Z_OK) {
fprintf(stderr, "could not close z-stream!\n");
return EXIT_FAILURE;
}
if (zRemainderBuf)
free(zRemainderBuf);
fclose(inFp);
return EXIT_SUCCESS;
}
With any streaming you should consider the memory requirements of your app.
A good buffer size is large, but you do not want to have too much memory in use depending on your RAM usage requirements. A small buffer size will require you call your read and write operations more times which are expensive in terms of time performance. So, you need to find a buffer in the middle of those two extremes.
Typically I use a size of 4096 (4KB) which is sufficiently large for many purposes. If you want, you can go larger. But at the worst case size of 1 byte, you will be waiting a long time for you read to complete.
So to answer your question, there is no "right" size to pick. It is a choice you should make so that the speed of your app and the memory it requires are what you need.

How do I get the DC coefficient from a jpg using the jpg library?

I am new to this stuff, but I need to get the dc-coefficient from a jpeg using the jpeg library?
I was told as a hint that the corresponding function is in jdhuff.c, but I can't find it. I tried to find a decent article about the jpg library where I can get this, but no success so far.
So I hope you guys can help me a bit and point me to either some documentation or have a hint.
So, here is what I know:
A jpg picture consists of 8x8 Blocks. That are 64 Pixels. 63 of it are named AC and 1 is named DC. Thats the coefficient. The position is at array[0][0].
But how do I exactly read that with the jpg library? I am using C++.
edit:
This is what I have so far:
read_jpeg::read_jpeg( const std::string& filename )
{
FILE* fp = NULL; // File-Pointer
jpeg_decompress_struct cinfo; // jpeg decompression parameters
JSAMPARRAY buffer; // Output row-buffer
int row_stride = 0; // physical row width
my_error_mgr jerr; // Custom Error Manager
// Set Error Manager
cinfo.err = jpeg_std_error(&jerr.pub);
jerr.pub.error_exit = my_error_exit;
// Handle longjump
if (setjmp(jerr.setjmp_buffer)) {
// JPEG has signaled an error. Clean up and throw an exception.
jpeg_destroy_decompress(&cinfo);
fclose(fp);
throw std::runtime_error("Error: jpeg has reported an error.");
}
// Open the file
if ( (fp = fopen(filename.c_str(), "rb")) == NULL )
{
std::stringstream ss;
ss << "Error: Cannot read '" << filename.c_str() << "' from the specified location!";
throw std::runtime_error(ss.str());
}
// Initialize jpeg decompression
jpeg_create_decompress(&cinfo);
// Show jpeg where to read the data
jpeg_stdio_src(&cinfo, fp);
// Read the header
jpeg_read_header(&cinfo, TRUE);
// Decompress the file
jpeg_start_decompress(&cinfo);
// JSAMPLEs per row in output buffer
row_stride = cinfo.output_width * cinfo.output_components;
// Make a one-row-high sample array
buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
// Read image using jpgs counter
while (cinfo.output_scanline < cinfo.output_height)
{
// Read the image
jpeg_read_scanlines(&cinfo, buffer, 1);
}
// Finish the decompress
jpeg_finish_decompress(&cinfo);
// Release memory
jpeg_destroy_decompress(&cinfo);
// Close the file
fclose(fp);
}
This is not possible using the standard API. With libjpeg API the closest you can get is raw pixel data of Y/Cb/Cr channels.
To get coefficients' data you'd need to hack the decode_mcu function (or its callers) to save the data decoded there.