Search code examples
cjpeglibjpeglibjpeg-turbo

Decompressing jpeg using libjpegturbo returning "Empty input file"


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!


Solution

  • 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.