1

As the title states, I'm trying to read a JPEG file using libjpeg-turbo. I tried this code on a mac at home and it worked, but now I'm on Windows and it's giving me a Empty input file error on calling jpeg_read_header. I have verified that the file is not empty by doing a fseek/ftell, and the size I get corresponds to what I expect it to be.

My initial thoughts were that I might not have been opening the file in binary mode, so I tried that as well using _setmode, but that didn't seem to help. Here is my code for reference.

int decodeJpegFile(char* filename)
{
    FILE *file = fopen(filename, "rb");

    if (file == NULL)
    {
        return NULL;
    }

    _setmode(_fileno(file), _O_BINARY);

    fseek(file, 0L, SEEK_END);
    int sz = ftell(file);
    fseek(file, 0L, SEEK_SET);


    struct jpeg_decompress_struct info; //for our jpeg info
    struct jpeg_error_mgr err; //the error handler

    info.err = jpeg_std_error(&err);
    jpeg_create_decompress(&info); //fills info structure
    jpeg_stdio_src(&info, file);
    jpeg_read_header(&info, true); // ****This is where it fails*****
    jpeg_start_decompress(&info);


    int w = info.output_width;
    int h = info.output_height;
    int numChannels = info.num_components; // 3 = RGB, 4 = RGBA
    unsigned long dataSize = w * h * numChannels;

    unsigned char *data = (unsigned char *)malloc(dataSize);
    unsigned char* rowptr;
    while (info.output_scanline < h)
    {
        rowptr = data + info.output_scanline * w * numChannels;
        jpeg_read_scanlines(&info, &rowptr, 1);
    }

    jpeg_finish_decompress(&info);
    fclose(file);

    FILE* outfile = fopen("outFile.raw", "wb");
    size_t data_out = fwrite(data, dataSize, sizeof(unsigned char), outfile);

}`

Any help is much appreciated!

Sid
  • 1,239
  • 2
  • 13
  • 36
  • You really should be using your debugger to see what is going on instead of guessing what may be the issue. – PaulMcKenzie Aug 24 '16 at 21:37
  • You're right. I do not have the source/symbols for libjpeg at the moment so I can't dig around there. I was hoping that someone has already come across this issue, because what I'm trying to do is really basic. Worst case scenario, I'll have to download/build libjpeg myself – Sid Aug 24 '16 at 21:42
  • How do you build your app on Windows? – user58697 Aug 24 '16 at 21:53
  • I'm using visual studio 2015. I got the precompiled binaries, and linked the library/header files – Sid Aug 24 '16 at 21:54
  • The jpeg file? Yes. I'm getting the correct size of the file when doing the fseek/ftell. Also, if it doesn't find the file it will return NULL. So I'm pretty sure the file is in the correct folder – Sid Aug 24 '16 at 22:04
  • 2
    That's what I suspected. See this discussion: https://sourceforge.net/p/gnuwin32/discussion/74807/thread/54e28799/ – user58697 Aug 24 '16 at 23:52
  • 1
    @user58697 Please add this as an answer! – Christian Ternus Aug 25 '16 at 01:00
  • @user58697 thanks a lot for linking that thread! I'm almost certain that's what is happening in my case (although I'm not sure why I see the 'Empty input file' error instead of a crash as mentioned in that thread). I'll look into it tomorrow. Also as Christian said please add your comment as an answer! – Sid Aug 25 '16 at 01:07

2 Answers2

2

The core of the issue is a dll mismatch. The libjpeg is built agains msvcrt.dll, whereas the app is built against whatever runtime provided by MSVS2015. They are incompatible, and the file pointers opened in one runtime make no sense to another.

The solution, as per this discussion, is to avoid jpeg_stdio_src API.

user58697
  • 7,808
  • 1
  • 14
  • 28
  • BTW, there are official builds of libjpeg-turbo for Visual C++ on its page, for example see: https://sourceforge.net/projects/libjpeg-turbo/files/1.5.0/ - I'm using it for years together with `jpeg_stdio_src` API – Anton Malyshev Aug 25 '16 at 01:21
  • @AntonMalyshev I was using the same Visual C++ binaries you are talking about with VS2015 and am still seeing the crash. In fact it is also documented on their website that passing in C runtime handles will fail on Windows unless you build your application against msvcrt.dll. [link](http://www.libjpeg-turbo.org/Documentation/OfficialBinaries) – Sid Aug 29 '16 at 02:39
  • Don't know why, but I have no problems with VS2008, maybe lucky :) – Anton Malyshev Aug 29 '16 at 04:17
0

You are passing C++ true value to jpeg_read_header -- that could also be the reason for failure. You should pass TRUE constant instead.

Anton Malyshev
  • 8,686
  • 2
  • 27
  • 45
  • Yes, technically that is true, but you have this compiler thing that will complain (rather loudly) if `true` were undeclared. – David C. Rankin Aug 25 '16 at 03:22
  • Problem is not with declared/undeclared. true and TRUE or even C++ true and C99 true can have different internal representations (different int values) what can lead to weird runtime errors. I faced this several times. – Anton Malyshev Aug 26 '16 at 08:39
  • I see your point, basically `true` is *implementation defined* so it is up to the OP to verify it is passing what he thinks it is as the `require image` flag. – David C. Rankin Aug 26 '16 at 18:40