JPEG support with ijg - getting access violation

前端 未结 7 1244
余生分开走
余生分开走 2021-01-06 12:00

I was recently trying to update my game to store graphics in compressed formats (JPEG and PNG).

Whilst I ended up settling on a different library, my initial attempt

相关标签:
7条回答
  • 2021-01-06 12:01

    Here is a workaround without having to rebuild the library: Make replacement I/O functions, as André Caron stated, but have nothing in them but the standard stdio functions.

    The code below I made in the past might help. It is written for libpng, but I believe it is easy to do the same in libjpeg.

    I added this to the code:

        png_set_write_fn (png_ptr,file,replwrite,replflush);
    

    Then created the replacement functions:

    void replwrite (png_structp png_ptr, png_bytep data, png_size_t length)
    {
        fwrite (data,1,length,(FILE*) png_get_io_ptr(png_ptr));
    }
    
    void replflush (png_structp png_ptr)
    {
        fflush ((FILE*) png_get_io_ptr(png_ptr));
    }
    

    It always works for me. What I'm actually doing is telling libpng, "Hey, don't use the write functions from the MSVCR that your .dll points to, use these ones, that come from the MSVCR I use in my program, fwrite and fflush". You see it's basically a compatibility issue.

    I hope this or something like this will solve the problem.

    0 讨论(0)
  • 2021-01-06 12:02

    I agree with Hernán. This is not a good interface (I think the internal code itself is probably good), unless you really need to work low-level (and maybe not even then). I think ImageMagick is probably better. They have a "MagickWand" C interface that is more high level, not to mention that it supports many more formats.

    However, I was curious about libjpeg's interface, so I got a test program working to my satisfaction, based on your example program as well as libjpeg.doc, the IJG example, and USING THE IJG JPEG LIBRARY. Anyway, here's the code. It just prints out the dimensions, and the RGB of the first pixel of every row.

    I am very surprised you get an error with my code. It works fine for me, and compiles without any warnings. Can someone else test it?

    #include <stdio.h>
    #include <assert.h>
    #include <jpeglib.h>
    
    int main(int argc, char* argv[])
    {
        struct jpeg_decompress_struct cinfo;
        struct jpeg_error_mgr jerr;
        JSAMPARRAY buffer;
        int row_stride;
    
        //initialize error handling
        cinfo.err = jpeg_std_error(&jerr);
    
        FILE* infile;
        infile = fopen("Sample.jpg", "rb");
        assert(infile != NULL);
    
        //initialize the decompression
        jpeg_create_decompress(&cinfo);
    
        //specify the input
        jpeg_stdio_src(&cinfo, infile);
    
        //read headers
        (void) jpeg_read_header(&cinfo, TRUE);
    
        jpeg_start_decompress(&cinfo);
    
        printf("width: %d, height: %d\n", cinfo.output_width, cinfo.output_height);
    
        row_stride = cinfo.output_width * cinfo.output_components;
    
        buffer = (*cinfo.mem->alloc_sarray)
            ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
    
        JSAMPLE firstRed, firstGreen, firstBlue; // first pixel of each row, recycled
        while (cinfo.output_scanline < cinfo.output_height)
        {
        (void)jpeg_read_scanlines(&cinfo, buffer, 1);
        firstRed = buffer[0][0];
        firstBlue = buffer[0][1];
        firstGreen = buffer[0][2];
        printf("R: %d, G: %d, B: %d\n", firstRed, firstBlue, firstGreen);
        }
    
        jpeg_finish_decompress(&cinfo);
    
        return 0;
    }
    
    0 讨论(0)
  • 2021-01-06 12:14

    I've just encountered the same problem (although I was trying to encode an image). Apparently, FILE* are not portable between DLLs so you can't use any libjpeg API that takes a FILE* as a parameter.

    There are several solutions, but they all come down to having to rebuild the library:

    • Build the library as a static lib, and link it to your application. This is what I did, and it solved my problem.
    • Move the source/destination handlers out of libjpeg and into your application. Then you could build libjpeg as either a static lib or a DLL, whichever suits you. I'm not sure whether this would work, but it is the suggested solution in the "install.doc" file distributed with the source code.
    0 讨论(0)
  • 2021-01-06 12:16

    To work with images in multiple formats, let me recommend you DevIL as a library http://openil.sourceforge.net/. It's an excellent choice, as I've used it many times with excellent results. Beware that it's syntax is OpenGL-like.

    The list of features:

    Supports loading of:

    • .bmp
    • .cut
    • .dcx
    • .dds
    • .exr
    • .ico
    • .icns
    • .gif
    • .jpg
    • .jp2
    • .lbm
    • .lif
    • .mdl
    • .pcd
    • .pcx
    • .pic
    • .png
    • .pnm
    • .psd
    • .psp
    • .raw
    • .sgi
    • .tga
    • .tif
    • .wal
    • .act
    • .pal
    • .hdr
    • Doom graphics

    Supports saving of:

    • .bmp
    • .dds
    • .jpg
    • .pcx
    • .png
    • .pnm
    • .raw
    • .sgi
    • .tga
    • .tif
    • .pal

    Library Features

    • Portable, supports Windows, Mac OS X and *nix.
    • OpenGL-style syntax.
    • Use of image names instead of ugly pointers.
    • Loading from files, file streams or memory "lumps".
    • Direct access to data through ilGetData() and ilSetData().
    • Support for luminance, rgb(a), bgr(a) and colour-indexed images.
    • Support for 3 different numbers of bits per channel.
    • Conversion between all formats and datatypes (including palettes).
    • User-defined automatic conversions if desired when loading images.
    • Automatic conversion when saving images if needed.
    • Automatic conversion of colour-indexed images to truecolour images if desired.
    • Controllable compression when saving.
    • Maintains a state stack that can be pushed and popped.
    • Full support for 3d texture volumes (3d images).
    • Validation of images.
    • Support for layers.
    • Support for mipmaps.
    • Support for animations.
    • User-specified clear colour.
    • Can load a default image if loading fails.
    • User-specified hints.
    • Use of key colours.
    • Support for overlaying an image on top of another.
    • Allows the user to specify their own loading and saving callbacks, even overriding the default ones.
    • Support for user-specified read and write functions.
    • Delphi support.
    • Visual Basic support.
    • Linux support.
    • Can pick and choose which features will be used to create smaller dlls.
    • Choose whether to use the Intel Jpeg Library or libjpeg.
    • A whole host of effects and filters to apply to images, such as embossing and edge detection.
    • Images can be resized or even be put on a larger background (enlarged canvas).
    • OpenGL, Allegro, Windows GDI and DirectX API support.
    0 讨论(0)
  • 2021-01-06 12:17

    It's difficult to see the cause of the access violation from the code sample given. If you can include a stack trace (with symbols) that would help identify the issue. One thing to verify is that the alignment settings for the .LIB and .EXE projects are consistent, this will often lead to nasty problems as struct/class members are not where the compiler expects them to be.

    0 讨论(0)
  • 2021-01-06 12:23

    here is a tested function

    void test(char FileName[])
    {
        unsigned long x, y;
        struct jpeg_decompress_struct info; //for our jpeg info
        struct jpeg_error_mgr err;           //the error handler
        JSAMPARRAY buffer;
        FILE* infile;
        //initialize error handling
        info.err = jpeg_std_error(& err);     
    
        infile = fopen(FileName, "rb");  //open the file
    
        //if the jpeg file doesn't load
        if(!infile) {
        fprintf(stderr, "Error reading JPEG file %s!", FileName);
            // printf("Error reading JPEG file %s!", FileName);
            //return 0;
        }
    
        //initialize the decompression
        jpeg_create_decompress(&info);
    
    
        //specify the input
        jpeg_stdio_src(&info, infile);    
    
        //read headers
        jpeg_read_header(&info, TRUE);   // read jpeg file header
    
        jpeg_start_decompress(&info);    // decompress the file
    
        //set width and height
        x = info.output_width;
        y = info.output_height;
    
        printf("x value is %ul", x);
        printf("x value is %ul", y);
    }
    
    0 讨论(0)
提交回复
热议问题