Problem with jpg buffer



HI

I know that it is not the appropriate problem for this news group
but maybe someone can tell me where I can ask then:

OK THe problem is that I receive an buffer of data through sockets, and
those data are jpg image (an image compressed using libjpeg). 
Now I want to show them using gdk-pixbuf - what I did (in pthread using
libjpeg library to decompress data to rgb image, using gdk-pixbuf to
create pixbuf and show it in drawingarea). OK. Fine but......

When I receive many images it hangs .... so I tracked it down - there is
no problem with GTK, Pixbuf, sockets, but the problem was with libjpeg -
and exactly with function: 

	jpeg_start_decompress(&cinfo);

I tried to read image from file.jpg (well documented) instead of
decompressing from data in memory but it is still the same problem. Dont
know why - at the beggining it reads fast the file, but after few times
it hangs there (it starts decompressing for ever). I read documentation
for libjpeg library again and it is writen that
jpeg_start_decompress(&cinfo) can be slow however if I do simple
decompressing it should return quickly. So???? I am in .... dont want to
say where :)

OK. Please help.

Zbigniew Wasik
Ps. Here is code:

How I read a file :

int jpg_ReadJpegToRGB_a(  char *fname,
			       int *w_ret, int *h_ret,
			       unsigned char **rgb_return)
{
  static unsigned char             *data = NULL;
  FILE                             *fp = NULL;
  struct jpeg_decompress_struct    cinfo;
  JSAMPROW                         rowptr[1];
  my_error_mgr                     merr;
  int                              w,h,bperpix;

  printf(" ReadJPG: 1.0 \n") ;
  if((fp = fopen(fname, "r")) == NULL)   return 0;
  /* Step 1: allocate and initialize JPEG decompression object */
  printf(" ReadJPG: 2.0 set err mgr\n") ;
  cinfo.err = jpeg_std_error(&merr.pub);
  merr.pub.error_exit     = jp_error_exit;
  merr.pub.output_message = jp_error_output;

  printf(" ReadJPG: 3.0 set error mgr\n") ;
  if(setjmp(merr.setjmp_buffer)) 
    {
      /* jpeg has signaled an error */
      jpeg_destroy_decompress(&cinfo);
      (void)fclose(fp); 
      if(data) (void)free(data);
      return(0);
    }
  jpeg_create_decompress(&cinfo);

  /* Step 2: specify data source (eg, a file) */
  printf(" ReadJPG: 4.0 data source file\n") ;
  jpeg_stdio_src(&cinfo, fp);

  /* Step 3: read file parameters with jpeg_read_header() */
  printf(" ReadJPG: 5.0 header \n") ;
  (void) jpeg_read_header(&cinfo, TRUE);

  printf(" ReadJPG: 6.0 header \n") ;
  jpeg_calc_output_dimensions(&cinfo);
  w = cinfo.output_width;
  h = cinfo.output_height;
 
  printf(" ReadJPG: 7.0 header \n") ;
  bperpix = cinfo.output_components;
  if(bperpix != 1 && bperpix != 3) 
    {
      fprintf(stderr, "%s:  can't read %d-plane JPEG file.",
	      fname, cinfo.output_components);
      jpeg_destroy_decompress(&cinfo);
      fclose(fp); 
      return 0;
    }

  printf(" ReadJPG: 8.0 malloc\n") ;
  if((data = (unsigned char *)malloc( 4 * w * h *
					 sizeof(unsigned char))) == NULL)
    {
      jpeg_destroy_decompress(&cinfo);
      fclose(fp); 
      fprintf(stderr,"ReadJPEG");      
      return 0;
    }
  /* Step 4: set parameters for decompression */
  printf(" ReadJPG: 9.0 start decompress\n") ;
  jpeg_start_decompress(&cinfo);

  /* Step 5: decompress */
  printf(" ReadJPG: 10.0 decompress\n") ;
  while(cinfo.output_scanline < cinfo.output_height) 
    {
      rowptr[0] = (JSAMPROW) &data[cinfo.output_scanline * w * bperpix];
      (void) jpeg_read_scanlines(&cinfo, rowptr, (JDIMENSION) 1);
    }

  printf(" ReadJPG: 11.0 isGray\n") ;
  if(cinfo.jpeg_color_space == JCS_GRAYSCALE) 
    {
      unsigned char *t1, *t2, c;
      int i,j;
      t1 = data;
      t2 = t1 + 3* w * h;
      memcpy(t2, t1, w * h);
      for(i = 0; i < h; i++)
	for(j = 0; j < w; j++)
	  {
	    c = *t2++;
	    *t1++ = c; *t1++ = c; *t1++ = c; 
	  }
    }
  /* Step 6: clean up */
  printf(" ReadJPG: 12.0 Clean up\n") ;
  jpeg_finish_decompress(&cinfo);
  jpeg_destroy_decompress(&cinfo);
  fclose(fp); 
  
  /* finally .... */
  printf(" ReadJPG: 13.0 Final\n") ;
  *w_ret = w;
  *h_ret = h; 
  if(rgb_return)
    {
      *rgb_return = data;
      return(1);
    }
  fprintf(stderr, "Wrong pointer to rgb buffer \n") ;
  return(0);
}


How I use it (more or less):

void main_thread() {
  isRUnning = TRUE ;
  while(isRunning) {
    g_print(" Showing in thread \n") ;
    
    /* It grabs one image (what image depends on command) */

      jpg_ReadJpegToRGB_a("rose.jpg",&(client->width),&(client->height),
			       &(client->rgbBuffer)) ;
      

      /* Now let show the image */
      rgbViewer_showImage(client->source,
				  client->rgbBuffer,
				  client->width,client->height) ;
      

      sleep(5) ; // just for debugging now 5 seconds
 } // end of while

}



SORRY FOR MESS





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]