c++cwindows-mobilelibjpeg

Libjpeg error - improper call in state 205


I'm using libjpeg (C/C++ programming on Windows Mobile 6.5), in order to decode images from an IP camera (sent in a MJPEG stream), before pushing them into a DirectShow graph.

Until now, I've been using a single function for : receiving the stream, parsing it manually (in order to find JPEG data starting- and end-point), decoding the data (i.e. initializing the libjpeg structures, reading the JPEG header, doing the actual decoding...) and finally pushing it into the graph. This works properly, but in order to make things smoother and tidier, i'd like to use a function for receiving, that calls another function (later, a thread) for decoding/pushing.

So, as a first step, instead of doing all the JPEG work right after finding the data in the stream, I simply call another function which is in charge of the JPEG structures init / header reading / decoding / pushing.

And this is where I get an error I can't decipher : "improper call to jpeg library in state 205".

// EDITED FOR CLARITY

For now, my code looks like :

void receive1() {
    while(1)
    {
        if(recvfrom(/* ... */) > 0)
        {
            /* parse the received data for JPEG start and end */

            /* decode the JPEG */
            //Declarations
            struct jpeg_decompress_struct cinfo;
            struct my_error_mgr jerr;

            // Step 1: allocation / initialization
            cinfo.err = jpeg_std_error(&jerr.pub);
            jerr.pub.error_exit = my_error_exit;
            if(setjmp(jerr.setjmp_buffer))
            {
                printf("--ERROR LIBJPEG\n");
                /* quit with error code */
            }

            // Next steps : proceed with the decoding and displaying...
            jpeg_create_decompress(&cinfo);
            /* ... */
        }
    }
}

I'd like to have my code look like :

void receive2() {
  while(1)
  {
    if(recvfrom(/* ... */) > 0)
    {
        /* parse the received data for JPEG start and end */

        decode(data);
    }
  }
}  

int decode(char* data) {
    /* decode the JPEG */
    //Declarations
    struct jpeg_decompress_struct cinfo;
    struct my_error_mgr jerr;

    // Step 1: allocation / initialization
    cinfo.err = jpeg_std_error(&jerr.pub);
    jerr.pub.error_exit = my_error_exit;
    if(setjmp(jerr.setjmp_buffer)) // This is where the "state 205" error occurs
    {
        printf("--ERROR LIBJPEG\n");
        /* quit with error code */
    }

    // Next steps : proceed with the decoding and displaying...
    jpeg_create_decompress(&cinfo);
    /* ... */

    return 0;
}

Any help would be appreciated here. Thanks a lot !

// EDIT

I'm realizing I've omitted quite a lot of information in my original post. Here are some (maybe) useful details :

typedef struct my_error_mgr * my_error_ptr;  

struct my_error_mgr 
{
    struct jpeg_error_mgr pub;
    jmp_buf setjmp_buffer;
};  

METHODDEF(void) my_error_exit (j_common_ptr cinfo)
{
    my_error_ptr myerr = (my_error_ptr) cinfo->err;   

    /* Always display the message. */
    (*cinfo->err->output_message) (cinfo);

    /* Return control to the setjmp point */
    longjmp(myerr->setjmp_buffer, 1);
}

Solution

  • 205 is 0xCD, that is the standard value put by VS in debug mode in unitialized memory, so I think that your cinfo was not initialized properly at the moment you've called the decoder. Post the code when you use it.

    Also, the setjump() you're using make me think it's IJG library. Be careful with it because it's not a standard function. It remembers the exact state of the thread and stack when you've made the call and is able to return to that position from anywhere, except cases when this state is not valid anymore, as in:

    int init_fn(){
         if (setjump(my_state)){
            // ERROR!
         };
    return 0;
    };
    
    int decode(){
         init_fn();
         do_work();
    };
    

    here the saved state is not valid at the time you call the actual decoder. For MT case you have to call the setjump() from the same thread as longjmp().