开发者

Libjpeg error - improper call in state 205

开发者 https://www.devze.com 2023-01-21 15:16 出处:网络
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.

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 JPE开发者_StackOverflowG */
            //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 :

  • I'm using VS2008, but for many reasons I don't use the built-in debugger or emulators. Instead, the exe file is directly deployed and tested on the Windows Mobile device, using a custom dos-like command prompt.
  • libjpeg originally reads from and writes to files, but I'm using a patch (and custom error handler) enabling to read data directly from a buffer, without opening a file. Code can be found here, and it uses an "extended error handler" defined this way :
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);
}


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().


I got the exact same error happen to me. I'm working on an NVidia Jetson developer kit and wanted to draw a JPEG on the screen.

First the width of my image was not a multiple of 16. Once I fixed that part, it would load and then the rendering would fail with that weird error message:

Improper call to JPEG library in state 205

I know that the Jetsons only support a subset of the possible JPEG formats. I regenerated my JPEG image to make sure it was 4:2:0 and not grayscale (although that image had color, but a grayscale image is also not supported by NVidia hardware) and then tried again. The error was gone.

For those interested, here is the command line function I use to fix those JPEG:

convert \
   -sampling-factor 4:2:0 \
   -type truecolor -define colorspace:auto-grayscale=off \
       input.png output.jpg

Then the output.jpg image works (as long as the width is a multiple of 16).


Found the answer to my problem, partly thanks to ruslik. Turns out that I was indeed badly initializing cinfo and jerr between the two functions.

But when I corrected this point, I still had the "state 205" error and thought it was at the same place. Digging in my logs, I found the error message to be issued later in the code execution, and caused by problems with function pointers. My own ugly mistake...

Thanks a lot anyway !

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号