title: Little more help with writing a o buffer with libjpeg
body: <p>So I have managed to find another question discussing how to use the libjpeg to compress an image to jpeg. I have found this code which is supposed to work:</p>
  
  <p><a href="https://stackoverflow.com/questions/1443390/compressing-iplimage-to-jpeg-using-libjpeg-in-opencv">Compressing IplImage to JPEG using libjpeg in OpenCV</a></p>
  
  <p>Here's the code (it compiles ok):</p>
  
  <pre><code>/*
  This a custom destination manager for jpeglib that
  enables the use of memory to memory compression.
  
  See IJG documentation for details.
  */
  typedef struct {
  struct jpeg_destination_mgr pub; /* base class */
  JOCTET* buffer; /* buffer start address */
  int bufsize; /* size of buffer */
  size_t datasize; /* final size of compressed data */
  int* outsize; /* user pointer to datasize */
  int errcount; /* counts up write errors due to
  buffer overruns */
  } memory_destination_mgr;
  
  typedef memory_destination_mgr* mem_dest_ptr;
  
  /* ------------------------------------------------------------- */
  /* MEMORY DESTINATION INTERFACE METHODS */
  /* ------------------------------------------------------------- */
  
  
  /* This function is called by the library before any data gets written */
  METHODDEF(void)
  init_destination (j_compress_ptr cinfo)
  {
  mem_dest_ptr dest = (mem_dest_ptr)cinfo-&gt;dest;
  
  dest-&gt;pub.next_output_byte = dest-&gt;buffer; /* set destination buffer */
  dest-&gt;pub.free_in_buffer = dest-&gt;bufsize; /* input buffer size */
  dest-&gt;datasize = 0; /* reset output size */
  dest-&gt;errcount = 0; /* reset error count */
  }
  
  /* This function is called by the library if the buffer fills up
  
  I just reset destination pointer and buffer size here.
  Note that this behavior, while preventing seg faults
  will lead to invalid output streams as data is over-
  written.
  */
  METHODDEF(boolean)
  empty_output_buffer (j_compress_ptr cinfo)
  {
  mem_dest_ptr dest = (mem_dest_ptr)cinfo-&gt;dest;
  dest-&gt;pub.next_output_byte = dest-&gt;buffer;
  dest-&gt;pub.free_in_buffer = dest-&gt;bufsize;
  ++dest-&gt;errcount; /* need to increase error count */
  
  return TRUE;
  }
  
  /* Usually the library wants to flush output here.
  
  I will calculate output buffer size here.
  Note that results become incorrect, once
  empty_output_buffer was called.
  This situation is notified by errcount.
  */
  METHODDEF(void)
  term_destination (j_compress_ptr cinfo)
  {
  mem_dest_ptr dest = (mem_dest_ptr)cinfo-&gt;dest;
  dest-&gt;datasize = dest-&gt;bufsize - dest-&gt;pub.free_in_buffer;
  if (dest-&gt;outsize) *dest-&gt;outsize += (int)dest-&gt;datasize;
  }
  
  /* Override the default destination manager initialization
  provided by jpeglib. Since we want to use memory-to-memory
  compression, we need to use our own destination manager.
  */
  GLOBAL(void)
  jpeg_memory_dest (j_compress_ptr cinfo, JOCTET* buffer, int bufsize, int* outsize)
  {
  mem_dest_ptr dest;
  
  /* first call for this instance - need to setup */
  if (cinfo-&gt;dest == 0) {
  cinfo-&gt;dest = (struct jpeg_destination_mgr *)
  (*cinfo-&gt;mem-&gt;alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
  sizeof (memory_destination_mgr));
  }
  
  dest = (mem_dest_ptr) cinfo-&gt;dest;
  dest-&gt;bufsize = bufsize;
  dest-&gt;buffer = buffer;
  dest-&gt;outsize = outsize;
  /* set method callbacks */
  dest-&gt;pub.init_destination = init_destination;
  dest-&gt;pub.empty_output_buffer = empty_output_buffer;
  dest-&gt;pub.term_destination = term_destination;
  }
  
  /* ------------------------------------------------------------- */
  /* MEMORY SOURCE INTERFACE METHODS */
  /* ------------------------------------------------------------- */
  
  /* Called before data is read */
  METHODDEF(void)
  init_source (j_decompress_ptr dinfo)
  {
  /* nothing to do here, really. I mean. I'm not lazy or something, but...
  we're actually through here. */
  }
  
  /* Called if the decoder wants some bytes that we cannot provide... */
  METHODDEF(boolean)
  fill_input_buffer (j_decompress_ptr dinfo)
  {
  /* we can't do anything about this. This might happen if the provided
  buffer is either invalid with regards to its content or just a to
  small bufsize has been given. */
  
  /* fail. */
  return FALSE;
  }
  
  /* From IJG docs: "it's not clear that being smart is worth much trouble"
  So I save myself some trouble by ignoring this bit.
  */
  METHODDEF(void)
  skip_input_data (j_decompress_ptr dinfo, INT32 num_bytes)
  {
  /* There might be more data to skip than available in buffer.
  This clearly is an error, so screw this mess. */
  if ((size_t)num_bytes &gt; dinfo-&gt;src-&gt;bytes_in_buffer) {
  dinfo-&gt;src-&gt;next_input_byte = 0; /* no buffer byte */
  dinfo-&gt;src-&gt;bytes_in_buffer = 0; /* no input left */
  } else {
  dinfo-&gt;src-&gt;next_input_byte += num_bytes;
  dinfo-&gt;src-&gt;bytes_in_buffer -= num_bytes;
  }
  }
  
  /* Finished with decompression */
  METHODDEF(void)
  term_source (j_decompress_ptr dinfo)
  {
  /* Again. Absolute laziness. Nothing to do here. Boring. */
  }
  
  GLOBAL(void)
  jpeg_memory_src (j_decompress_ptr dinfo, unsigned char* buffer, size_t size)
  {
  struct jpeg_source_mgr* src;
  
  /* first call for this instance - need to setup */
  if (dinfo-&gt;src == 0) {
  dinfo-&gt;src = (struct jpeg_source_mgr *)
  (*dinfo-&gt;mem-&gt;alloc_small) ((j_common_ptr) dinfo, JPOOL_PERMANENT,
  sizeof (struct jpeg_source_mgr));
  }
  
  src = dinfo-&gt;src;
  src-&gt;next_input_byte = buffer;
  src-&gt;bytes_in_buffer = size;
  src-&gt;init_source = init_source;
  src-&gt;fill_input_buffer = fill_input_buffer;
  src-&gt;skip_input_data = skip_input_data;
  src-&gt;term_source = term_source;
  /* IJG recommend to use their function - as I don't know ****
  about how to do better, I follow this recommendation */
  src-&gt;resync_to_restart = jpeg_resync_to_restart;
  }
  </code></pre>
  
  <p>All I need to do is replace the jpeg_stdio_dest in my program with this code:</p>
  
  <pre><code>int numBytes = 0; //size of jpeg after compression
  char * storage = new char[150000]; //storage buffer
  JOCTET *jpgbuff = (JOCTET*)storage; //JOCTET pointer to buffer
  jpeg_memory_dest(&amp;cinfo,jpgbuff,150000,&amp;numBytes);
  </code></pre>
  
  <p>So I need some help to incorporate the above four lines into this function which now works but writes to a file instead of a memory:</p>
  
  <pre><code>int write_jpeg_file( char *filename )
  {
      struct jpeg_compress_struct cinfo;
      struct jpeg_error_mgr jerr;
  
      /* this is a pointer to one row of image data */
      JSAMPROW row_pointer[1];
      FILE *outfile = fopen( filename, "wb" );
  
      if ( !outfile )
      {
          printf("Error opening output jpeg file %s\n!", filename );
          return -1;
      }
      cinfo.err = jpeg_std_error( &amp;jerr );
      jpeg_create_compress(&amp;cinfo);
      jpeg_stdio_dest(&amp;cinfo, outfile);
  
      /* Setting the parameters of the output file here */
      cinfo.image_width = width;  
      cinfo.image_height = height;
      cinfo.input_components = bytes_per_pixel;
      cinfo.in_color_space = color_space;
      /* default compression parameters, we shouldn't be worried about these */
      jpeg_set_defaults( &amp;cinfo );
      /* Now do the compression .. */
      jpeg_start_compress( &amp;cinfo, TRUE );
      /* like reading a file, this time write one row at a time */
      while( cinfo.next_scanline &lt; cinfo.image_height )
      {
          row_pointer[0] = &amp;raw_image[ cinfo.next_scanline * cinfo.image_width *  cinfo.input_components];
          jpeg_write_scanlines( &amp;cinfo, row_pointer, 1 );
      }
      /* similar to read file, clean up after we're done compressing */
      jpeg_finish_compress( &amp;cinfo );
      jpeg_destroy_compress( &amp;cinfo );
      fclose( outfile );
      /* success code is 1! */
      return 1;
  }
  </code></pre>
  
  <p>Anybody could help me out a bit with it? I've tried meddling with it but I am not sure how to do it. I I just replace this line:</p>
  
  <pre><code>jpeg_stdio_dest(&amp;cinfo, outfile);
  </code></pre>
  
  <p>It's not going to work. There is more stuff that needs to be changed a bit in that function and I am being a little lost from all those pointers and memory management.</p>