Thread: libjpeg sgefault on jpeg_read_scanlines()

  1. #1
    42
    Join Date
    May 2005
    Location
    Estonia
    Posts
    7

    Unhappy libjpeg segfault on jpeg_read_scanlines()

    I have a simple jpeg load function for normal jpeg files.
    If I step through it with gdb I get

    "Program received signal SIGSEGV, Segmentation fault.
    0x1000b73a in ycc_rgb_convert ()"

    The ycc_rgb_convert() is called by jpeg_read_scanlines()
    I tried multiple jpg files and I always get that.

    Am I totally missing out something here, or what could be wrong with it?

    basically this is the function:

    Code:
    #include "libjpeg/jpeglib.h"
    #include <setjmp.h>
    int loadJPEG(char *filename, struct slideshow_img *img) {
      struct jpeg_decompress_struct cinfo;
      struct my_error_mgr jerr;
      FILE *fp;
      int row_stride, state=0;
    	
      cinfo.err = jpeg_std_error(&jerr.pub); // ERROR CONTROL
      jerr.pub.error_exit = my_error_exit;
    	
      if ((fp = fopen(filename, "rb")) == NULL) { //LOAD FILE
      fprintf(errorlog, "Failed to open JPEG file %s\n", filename); return 1;
      }
    	
    	jpeg_create_decompress(&cinfo);
    	jpeg_stdio_src(&cinfo, fp);
    	jpeg_read_header(&cinfo, TRUE);
    	
    	row_stride = cinfo.output_width * cinfo.output_components;
    	
    	img->pixels = (void *)calloc(cinfo.output_height, row_stride); //Allocate Space for pixels
    	
    	jpeg_calc_output_dimensions(&cinfo);
    	jpeg_start_decompress(&cinfo); printf(".");
    	
    	while (cinfo.output_scanline < cinfo.output_height) {
    	  jpeg_read_scanlines(&cinfo, (JSAMPARRAY)(img->pixels+state), 1);
    	  state += row_stride; //Increment pointer offset
    	}
    	
    	jpeg_finish_decompress(&cinfo);
    	jpeg_destroy_decompress(&cinfo);
    	fclose(fp);
    	
    	if (setjmp(jerr.setjmp_buffer)) { //Error
    		jpeg_destroy_decompress(&cinfo);
    		fclose(fp);
    		return 2;
    	}
    	return 0;
    Last edited by Syko; 11-25-2005 at 04:22 PM.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > while (cinfo.output_scanline < cinfo.output_height)
    Is scanline initialised?
    How is it incremented?
    How does your loop ever exit?

    > img->pixels+state
    What type is pixels?
    Do you know how pointer arithmetic works?

    > img->pixels = (void *)calloc(cinfo.output_height, row_stride);
    Why are you casting calloc - you don't need to, this is C.

    Finally, never post code with that oh so creative, yet totally unreadable mess of formatting tags.
    Simple code/code tags will suffice thanks.

  3. #3
    42
    Join Date
    May 2005
    Location
    Estonia
    Posts
    7
    Well that was friendly

    Quote Originally Posted by Salem
    > while (cinfo.output_scanline < cinfo.output_height)
    Is scanline initialised?
    How is it incremented?
    How does your loop ever exit?
    I took that from the example.c that came with the libjpeg source. Here's what it says:
    Quote Originally Posted by example.c
    /* Here we use the library's state variable cinfo.output_scanline as the
    * loop counter, so that we don't have to keep track ourselves.
    */
    while (cinfo.output_scanline < cinfo.output_height) {
    /* jpeg_read_scanlines expects an array of pointers to scanlines.
    * Here the array is only one element long, but you could ask for
    * more than one scanline at a time if that's more convenient.
    */
    (void) jpeg_read_scanlines(&cinfo, buffer, 1);
    /* Assume put_scanline_someplace wants a pointer and sample count. */
    put_scanline_someplace(buffer[0], row_stride);
    }
    Quote Originally Posted by Salem
    > img->pixels+state
    What type is pixels?
    Do you know how pointer arithmetic works?
    This is the structure that's passed to the function as a pointer
    Code:
    struct slideshow_img {
    	int w,h;
    	void *pixels;
    };
    And yes, I know pointer arithmetic works.

    Quote Originally Posted by Salem
    > img->pixels = (void *)calloc(cinfo.output_height, row_stride);
    Why are you casting calloc - you don't need to, this is C.
    I did that to avoid warnings by the compiler. It produces no problem.

    Sry about the formatting tags.

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > Well that was friendly
    What's so unfriendly about asking a few questions about your code?

    > And yes, I know pointer arithmetic works.
    LOL - yeah, right.
    Obviously you don't know that it doesn't work on void*
    But I'm sure there are plenty of people who would tell you otherwise.

    Do you compile with max warnings on your compiler, for example, that line gets me
    Code:
    $ gcc -W -Wall -ansi -pedantic foo.c
    foo.c: In function ‘main’:
    foo.c:6: warning: pointer of type ‘void *’ used in arithmetic
    > I did that to avoid warnings by the compiler. It produces no problem.
    How about actually addressing the warnings, rather than sweeping the problem under the carpet?
    I mean, if it's complaining about int to void* converstions, then include the proper header file.
    And how can you say "no problem" when you're staring down the barrel of a segv ?

    Since you weasled out of the question last time, I'll ask once more
    Is cinfo.output_scanline initlaised?

    Does doing this help?
    struct jpeg_decompress_struct cinfo = &#123; 0 };
    Namely initialising your whole struct to be empty, rather than having some junk values.

  5. #5
    42
    Join Date
    May 2005
    Location
    Estonia
    Posts
    7
    Ok well I was wondering a bit about incrementing a void pointer but I tested it with a small app that increments a void pointer by one and it did increment it by one byte...
    My bad about the calloc() thing. I wasn't compiling with maximum warnings. I included malloc.h and there were no more warnings for that.
    Btw I gave img->pixels the type "JSAMPLE" (which is bsaically an unsigned char)

    About initializing the struct. I wrote the whole thing watching closely example.c and it states:
    Quote Originally Posted by example.c
    /* Now we can initialize the JPEG decompression object. */
    jpeg_create_decompress(&cinfo);
    So I assumed it intializises all the necessary things.

    And I tried your suggestion to initialize it all to 0. The segfault remains...

  6. #6
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    I included malloc.h and there were no more warnings for that.
    Uh oh . . . what compiler are you using?

    What does your calloc line look like now? It should have no cast whatsoever.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Since you seem to be running under Linux, then I suggest some reading

    $ man valgrind
    $ man efence

    Both these help you with tracking down memory problems, because although the segv may be in this particular function, the root cause could be somewhere else.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. linker error when using libjpeg
    By s-men in forum C++ Programming
    Replies: 2
    Last Post: 08-21-2008, 10:02 AM
  2. libjpeg problems linking in cpp
    By parad0x13 in forum C++ Programming
    Replies: 4
    Last Post: 07-19-2008, 04:29 PM
  3. Lib issues: undefined references (libjpeg)
    By psychopath in forum Linux Programming
    Replies: 3
    Last Post: 04-17-2006, 01:28 PM
  4. Compiler errors when using libjpeg.
    By Nikanoru in forum C++ Programming
    Replies: 11
    Last Post: 08-07-2003, 06:46 AM