/* Convert 8-bit VIPS images to/from JPEG.
 *
 * 28/11/03 JC
 *	- better no-overshoot on tile loop
 * 12/11/04
 *	- better demand size choice for eval
 * 30/6/05 JC
 *	- update im_error()/im_warn()
 *	- now loads and saves exif data
 * 30/7/05
 * 	- now loads ICC profiles
 * 	- now saves ICC profiles from the VIPS header
 * 24/8/05
 * 	- jpeg load sets vips xres/yres from exif, if possible
 * 	- jpeg save sets exif xres/yres from vips, if possible
 * 29/8/05
 * 	- cut from old vips_jpeg.c
 * 20/4/06
 * 	- auto convert to sRGB/mono for save
 * 13/10/06
 * 	- add </libexif/ prefix if required
 * 19/1/07
 * 	- oop, libexif confusion
 * 2/11/07
 * 	- use im_wbuffer() API for BG writes
 * 15/2/08
 * 	- write CMYK if Bands == 4 and Type == CMYK
 * 12/5/09
 *	- fix signed/unsigned warning
 * 13/8/09
 * 	- allow "none" for profile, meaning don't embed one
 * 4/2/10
 * 	- gtkdoc
 */

/*

    This file is part of VIPS.
    
    VIPS is free software; you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

 */

/*

    These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk

 */

/*
#define DEBUG
#define DEBUG_VERBOSE
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif /*HAVE_CONFIG_H*/
#include <vips/intl.h>

#ifndef HAVE_JPEG

#include <vips/vips.h>

int
im_vips2jpeg( IMAGE *in, const char *filename )
{
	im_error( "im_vips2jpeg", "%s",
		_( "JPEG support disabled" ) );

	return( -1 );
}

int
im_vips2bufjpeg( IMAGE *in, IMAGE *out, int qfac, char **obuf, int *olen )
{
	im_error( "im_vips2bufjpeg", "%s",
		_( "JPEG support disabled" ) );

	return( -1 );
}

int
im_vips2mimejpeg( IMAGE *in, int qfac )
{
	im_error( "im_vips2mimejpeg", "%s",
		_( "JPEG support disabled" ) );

	return( -1 );
}

#else /*HAVE_JPEG*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <setjmp.h>
#include <assert.h>

#ifdef HAVE_EXIF
#ifdef UNTAGGED_EXIF
#include <exif-data.h>
#include <exif-loader.h>
#include <exif-ifd.h>
#include <exif-utils.h>
#else /*!UNTAGGED_EXIF*/
#include <libexif/exif-data.h>
#include <libexif/exif-loader.h>
#include <libexif/exif-ifd.h>
#include <libexif/exif-utils.h>
#endif /*UNTAGGED_EXIF*/
#endif /*HAVE_EXIF*/

#include <vips/vips.h>
#include <vips/internal.h>
#include <vips/buf.h>

/* jpeglib includes jconfig.h, which can define HAVE_STDLIB_H ... which we
 * also define. Make sure it's turned off.
 */
#ifdef HAVE_STDLIB_H
#undef HAVE_STDLIB_H
#endif /*HAVE_STDLIB_H*/

#include <jpeglib.h>
#include <jerror.h>

#ifdef WITH_DMALLOC
#include <dmalloc.h>
#endif /*WITH_DMALLOC*/

/* Define a new error handler for when we bomb out.
 */
typedef struct {
	/* Public fields.
	 */
	struct jpeg_error_mgr pub;

	/* Private stuff for us.
	 */
	jmp_buf jmp;		/* longjmp() here to get back to VIPS */
	FILE *fp;		/* fclose() if non-NULL */
} ErrorManager;

/* New output message method - send to VIPS.
 */
METHODDEF(void)
new_output_message( j_common_ptr cinfo )
{
	char buffer[JMSG_LENGTH_MAX];

	(*cinfo->err->format_message)( cinfo, buffer );
	im_error( "vips_jpeg", _( "%s" ), buffer );

#ifdef DEBUG
	printf( "vips_jpeg.c: new_output_message: \"%s\"\n", buffer );
#endif /*DEBUG*/
}

/* New error_exit handler.
 */
METHODDEF(void)
new_error_exit( j_common_ptr cinfo )
{
	ErrorManager *eman = (ErrorManager *) cinfo->err;

#ifdef DEBUG
	printf( "vips_jpeg.c: new_error_exit\n" );
#endif /*DEBUG*/

	/* Close the fp if necessary.
	 */
	if( eman->fp ) {
		(void) fclose( eman->fp );
		eman->fp = NULL;
	}

	/* Send the error message to VIPS. This method is overridden above.
	 */
	(*cinfo->err->output_message)( cinfo );

	/* Jump back.
	 */
	longjmp( eman->jmp, 1 );
}

/* What we track during a JPEG write.
 */
typedef struct {
	IMAGE *in;
	struct jpeg_compress_struct cinfo;
        ErrorManager eman;
	JSAMPROW *row_pointer;
	char *profile_bytes;
	unsigned int profile_length;
	IMAGE *inverted;
} Write;

static void
write_destroy( Write *write )
{
	jpeg_destroy_compress( &write->cinfo );
	IM_FREEF( im_close, write->in );
	IM_FREEF( fclose, write->eman.fp );
	IM_FREE( write->row_pointer );
	IM_FREE( write->profile_bytes );
	IM_FREEF( im_close, write->inverted );
	im_free( write );
}

#define UC IM_BANDFMT_UCHAR

/* Type promotion for save ... just always go to uchar.
 */
static int bandfmt_jpeg[10] = {
/* UC  C   US  S   UI  I   F   X   D   DX */
   UC, UC, UC, UC, UC, UC, UC, UC, UC, UC
};

static Write *
write_new( IMAGE *in )
{
	Write *write;

	if( !(write = IM_NEW( NULL, Write )) )
		return( NULL );
	memset( write, 0, sizeof( Write ) );

	if( !(write->in = im__convert_saveable( in, 
		IM__RGB_CMYK, bandfmt_jpeg )) ) {
		im_error( "im_vips2jpeg", 
			"%s", _( "unable to convert to saveable format" ) );
		write_destroy( write );
		return( NULL );
	} 
	write->row_pointer = NULL;
        write->cinfo.err = jpeg_std_error( &write->eman.pub );
	write->eman.pub.error_exit = new_error_exit;
	write->eman.pub.output_message = new_output_message;
	write->eman.fp = NULL;
	write->profile_bytes = NULL;
	write->profile_length = 0;
	write->inverted = NULL;

        return( write );
}

#ifdef HAVE_EXIF
static void
write_rational( ExifEntry *entry, ExifByteOrder bo, void *data )
{
	ExifRational *v = (ExifRational *) data;

	exif_set_rational( entry->data, bo, *v );
}

static void
write_short( ExifEntry *entry, ExifByteOrder bo, void *data )
{
	ExifShort *v = (ExifShort *) data;

	exif_set_short( entry->data, bo, *v );
}

typedef void (*write_fn)( ExifEntry *, ExifByteOrder, void * );

static int
write_tag( ExifData *ed, ExifTag tag, ExifFormat f, write_fn fn, void *data )
{
	ExifByteOrder bo;
	int found;
	int i;

	bo = exif_data_get_byte_order( ed );

	/* Need to set the tag in all sections which have it :-(
	 */
	found = 0;
	for( i = 0; i < EXIF_IFD_COUNT; i++ ) {
		ExifEntry *entry;

		if( (entry = exif_content_get_entry( ed->ifd[i], tag )) &&
			entry->format == f &&
			entry->components == 1 ) {
			fn( entry, bo, data );
			found = 1;
		}
	}

	if( !found ) {
		/* There was no tag we could update ... make one in ifd[0].
		 */
		ExifEntry *entry;

		entry = exif_entry_new();
		exif_content_add_entry( ed->ifd[0], entry );
		exif_entry_initialize( entry, tag );
		fn( entry, bo, data );
	}

	return( 0 );
}

static int
set_exif_resolution( ExifData *ed, IMAGE *im )
{
	double xres, yres;
	ExifRational xres_rational, yres_rational;
	ExifShort unit;

	/* Always save as inches - more progs support it for read.
	 */
	xres = im->Xres * 25.4;
	yres = im->Yres * 25.4;
	unit = 2;

	/* Wow, how dumb, fix this.
	 */
	xres_rational.numerator = xres * 100000;
	xres_rational.denominator = 100000;
	yres_rational.numerator = yres * 100000;
	yres_rational.denominator = 100000;

	if( write_tag( ed, EXIF_TAG_X_RESOLUTION, EXIF_FORMAT_RATIONAL, 
		write_rational, &xres_rational ) ||
		write_tag( ed, EXIF_TAG_Y_RESOLUTION, EXIF_FORMAT_RATIONAL, 
			write_rational, &yres_rational ) ||
		write_tag( ed, EXIF_TAG_RESOLUTION_UNIT, EXIF_FORMAT_SHORT, 
			write_short, &unit ) ) {
		im_error( "im_jpeg2vips", 
			"%s", _( "error setting JPEG resolution" ) );
		return( -1 );
	}

	return( 0 );
}
#endif /*HAVE_EXIF*/

static int
write_exif( Write *write )
{
	unsigned char *data;
	size_t data_length;
	unsigned int idl;
#ifdef HAVE_EXIF
	ExifData *ed;

	/* Either parse from the embedded EXIF, or if there's none, make
	 * some fresh EXIF we can write the resolution to.
	 */
	if( im_header_get_typeof( write->in, IM_META_EXIF_NAME ) ) {
		if( im_meta_get_blob( write->in, IM_META_EXIF_NAME, 
			(void *) &data, &data_length ) )
			return( -1 );

		if( !(ed = exif_data_new_from_data( data, data_length )) )
			return( -1 );
	}
	else 
		ed = exif_data_new();

	/* Set EXIF resolution from VIPS.
	 */
	if( set_exif_resolution( ed, write->in ) ) {
		exif_data_free( ed );
		return( -1 );
	}

	/* Reserialise and write. exif_data_save_data() returns an int for some
	 * reason.
	 */
	exif_data_save_data( ed, &data, &idl );
	if( !idl ) {
		im_error( "im_jpeg2vips", "%s", _( "error saving EXIF" ) );
		exif_data_free( ed );
		return( -1 );
	}
	data_length = idl;

#ifdef DEBUG
	printf( "im_vips2jpeg: attaching %d bytes of EXIF\n", data_length  );
#endif /*DEBUG*/

	exif_data_free( ed );
	jpeg_write_marker( &write->cinfo, JPEG_APP0 + 1, data, data_length );
	free( data );
#else /*!HAVE_EXIF*/
	/* No libexif ... just copy the embedded EXIF over.
	 */
	if( im_header_get_typeof( write->in, IM_META_EXIF_NAME ) ) {
		if( im_meta_get_blob( write->in, IM_META_EXIF_NAME, 
			(void *) &data, &data_length ) )
			return( -1 );

#ifdef DEBUG
		printf( "im_vips2jpeg: attaching %d bytes of EXIF\n", 
			data_length  );
#endif /*DEBUG*/

		jpeg_write_marker( &write->cinfo, JPEG_APP0 + 1, 
			data, data_length );
	}
#endif /*!HAVE_EXIF*/

	return( 0 );
}

/* ICC writer from lcms, slight tweaks.
 */

#define ICC_MARKER  (JPEG_APP0 + 2)     /* JPEG marker code for ICC */
#define ICC_OVERHEAD_LEN  14            /* size of non-profile data in APP2 */
#define MAX_BYTES_IN_MARKER  65533      /* maximum data len of a JPEG marker */
#define MAX_DATA_BYTES_IN_MARKER  (MAX_BYTES_IN_MARKER - ICC_OVERHEAD_LEN)

/*
 * This routine writes the given ICC profile data into a JPEG file.
 * It *must* be called AFTER calling jpeg_start_compress() and BEFORE
 * the first call to jpeg_write_scanlines().
 * (This ordering ensures that the APP2 marker(s) will appear after the
 * SOI and JFIF or Adobe markers, but before all else.)
 */

static void
write_profile_data (j_compress_ptr cinfo,
                   const JOCTET *icc_data_ptr,
                   unsigned int icc_data_len)
{
  unsigned int num_markers;     /* total number of markers we'll write */
  int cur_marker = 1;           /* per spec, counting starts at 1 */
  unsigned int length;          /* number of bytes to write in this marker */

  /* rounding up will fail for length == 0 */
  assert( icc_data_len > 0 );

  /* Calculate the number of markers we'll need, rounding up of course */
  num_markers = (icc_data_len + MAX_DATA_BYTES_IN_MARKER - 1) / 
	  MAX_DATA_BYTES_IN_MARKER;

  while (icc_data_len > 0) {
    /* length of profile to put in this marker */
    length = icc_data_len;
    if (length > MAX_DATA_BYTES_IN_MARKER)
      length = MAX_DATA_BYTES_IN_MARKER;
    icc_data_len -= length;

    /* Write the JPEG marker header (APP2 code and marker length) */
    jpeg_write_m_header(cinfo, ICC_MARKER,
                        (unsigned int) (length + ICC_OVERHEAD_LEN));

    /* Write the marker identifying string "ICC_PROFILE" (null-terminated).
     * We code it in this less-than-transparent way so that the code works
     * even if the local character set is not ASCII.
     */
    jpeg_write_m_byte(cinfo, 0x49);
    jpeg_write_m_byte(cinfo, 0x43);
    jpeg_write_m_byte(cinfo, 0x43);
    jpeg_write_m_byte(cinfo, 0x5F);
    jpeg_write_m_byte(cinfo, 0x50);
    jpeg_write_m_byte(cinfo, 0x52);
    jpeg_write_m_byte(cinfo, 0x4F);
    jpeg_write_m_byte(cinfo, 0x46);
    jpeg_write_m_byte(cinfo, 0x49);
    jpeg_write_m_byte(cinfo, 0x4C);
    jpeg_write_m_byte(cinfo, 0x45);
    jpeg_write_m_byte(cinfo, 0x0);

    /* Add the sequencing info */
    jpeg_write_m_byte(cinfo, cur_marker);
    jpeg_write_m_byte(cinfo, (int) num_markers);

    /* Add the profile data */
    while (length--) {
      jpeg_write_m_byte(cinfo, *icc_data_ptr);
      icc_data_ptr++;
    }
    cur_marker++;
  }
}

/* Write an ICC Profile from a file into the JPEG stream.
 */
static int
write_profile_file( Write *write, const char *profile )
{
	if( !(write->profile_bytes = 
		im__file_read_name( profile, VIPS_ICC_DIR, 
		&write->profile_length )) ) 
		return( -1 );
	write_profile_data( &write->cinfo, 
		(JOCTET *) write->profile_bytes, write->profile_length );

#ifdef DEBUG
	printf( "im_vips2jpeg: attached profile \"%s\"\n", profile );
#endif /*DEBUG*/

	return( 0 );
}

static int
write_profile_meta( Write *write )
{
	void *data;
	size_t data_length;

	if( im_meta_get_blob( write->in, IM_META_ICC_NAME, 
		&data, &data_length ) )
		return( -1 );

	write_profile_data( &write->cinfo, data, data_length );

#ifdef DEBUG
	printf( "im_vips2jpeg: attached %d byte profile from VIPS header\n",
		data_length );
#endif /*DEBUG*/

	return( 0 );
}

static int
write_jpeg_block( REGION *region, Rect *area, void *a )
{
	Write *write = (Write *) a;
	int i;

	/* We are running in a background thread. We need to catch longjmp()s
	 * here instead.
	 */
	if( setjmp( write->eman.jmp ) ) 
		return( -1 );

	for( i = 0; i < area->height; i++ )
		write->row_pointer[i] = (JSAMPROW) 
			IM_REGION_ADDR( region, 0, area->top + i );

	jpeg_write_scanlines( &write->cinfo, write->row_pointer, area->height );

	return( 0 );
}

/* Write a VIPS image to a JPEG compress struct.
 */
static int
write_vips( Write *write, int qfac, const char *profile )
{
	IMAGE *in;
	J_COLOR_SPACE space;

	/* The image we'll be writing ... can change, see CMYK.
	 */
	in = write->in;

	/* Should have been converted for save.
	 */
        assert( in->BandFmt == IM_BANDFMT_UCHAR );
	assert( in->Coding == IM_CODING_NONE );
        assert( in->Bands == 1 || in->Bands == 3 || in->Bands == 4 );

        /* Check input image.
         */
	if( im_pincheck( in ) )
		return( -1 );
        if( qfac < 0 || qfac > 100 ) {
                im_error( "im_vips2jpeg", 
			"%s", _( "qfac should be in 0-100" ) );
                return( -1 );
        }

	/* Set compression parameters.
	 */
        write->cinfo.image_width = in->Xsize;
        write->cinfo.image_height = in->Ysize;
	write->cinfo.input_components = in->Bands;
	if( in->Bands == 4 && in->Type == IM_TYPE_CMYK ) {
		space = JCS_CMYK;
		/* IJG always sets an Adobe marker, so we should invert CMYK.
		 */
		if( !(write->inverted = im_open( "vips2jpeg_invert", "p" )) ||
			im_invert( in, write->inverted ) )
			return( -1 );
		in = write->inverted;
	}
	else if( in->Bands == 3 )
		space = JCS_RGB;
	else if( in->Bands == 1 )
		space = JCS_GRAYSCALE;
	else 
		/* Use luminance compression for all channels.
		 */
		space = JCS_UNKNOWN;
	write->cinfo.in_color_space = space; 

	/* Build VIPS output stuff now we know the image we'll be writing.
	 */
	if( !(write->row_pointer = 
		IM_ARRAY( NULL, write->in->Ysize, JSAMPROW )) )
		return( -1 );

	/* Rest to default. 
	 */
        jpeg_set_defaults( &write->cinfo );
        jpeg_set_quality( &write->cinfo, qfac, TRUE );

	/* Build compress tables.
	 */
	jpeg_start_compress( &write->cinfo, TRUE );

	/* Write any APP markers we need.
	 */
	if( write_exif( write ) )
		return( -1 );

	/* A profile supplied as an argument overrides an embedded profile.
	 * "none" means don't attach a profile.
	 */
	if( profile && 
		strcmp( profile, "none" ) != 0 &&
		write_profile_file( write, profile ) )
		return( -1 );
	if( !profile && 
		im_header_get_typeof( in, IM_META_ICC_NAME ) && 
		write_profile_meta( write ) )
		return( -1 );

	/* Write data. Note that the write function grabs the longjmp()!
	 */
	if( vips_sink_disc( write->in, write_jpeg_block, write ) )
		return( -1 );

	/* We have to reinstate the setjmp() before we jpeg_finish_compress().
	 */
	if( setjmp( write->eman.jmp ) ) 
		return( -1 );

	jpeg_finish_compress( &write->cinfo );

	return( 0 );
}

/**
 * im_vips2jpeg:
 * @in: image to save 
 * @filename: file to write to 
 *
 * Write a VIPS image to a file as JPEG.
 *
 * You can embed options in the filename. They have the form:
 *
 * |[
 * filename.jpg:<emphasis>compression</emphasis>,<emphasis>profile</emphasis>
 * ]|
 *
 * <itemizedlist>
 *   <listitem>
 *     <para>
 * <emphasis>compression</emphasis> 
 * Compress with this quality factor. Default 75.
 *     </para>
 *   </listitem>
 *   <listitem>
 *     <para>
 * <emphasis>profile</emphasis> 
 * Attach this ICC profile. For example, "fred.jpg:,/home/john/srgb.icc" will 
 * embed the profile stored in the file "/home/john/srgb.icc" in the JPEG 
 * image. This does not affect the pixels which are written, just the way 
 * they are tagged. You can use the special string "none" to mean 
 * "don't attach a profile".
 *     </para>
 *   </listitem>
 * </itemizedlist>
 *
 * If no profile is specified in the save string and the VIPS header 
 * contains an ICC profile named IM_META_ICC_NAME ("icc-profile-data"), the
 * profile from the VIPS header will be attached.
 *
 * The image is automatically converted to RGB, Monochrome or CMYK before 
 * saving. Any metadata attached to the image is saved as EXIF, if possible.
 *
 * Example:
 *
 * |[
 * im_vips2jpeg( in, "fred.jpg:99,none" );
 * ]|
 *
 * Will write "fred.jpg" at high-quality with no ICC profile.
 *
 * See also: #VipsFormat, im_jpeg2vips().
 *
 * Returns: 0 on success, -1 on error.
 */
int
im_vips2jpeg( IMAGE *in, const char *filename )
{
	Write *write;
	int qfac = 75; 
	char *profile = NULL;

	char *p, *q;

	char name[FILENAME_MAX];
	char mode[FILENAME_MAX];
	char buf[FILENAME_MAX];

	/* Parse mode from filename.
	 */
	im_filename_split( filename, name, mode );
	strcpy( buf, mode ); 
	p = &buf[0];
	if( (q = im_getnextoption( &p )) ) {
		if( strcmp( q, "" ) != 0 )
			qfac = atoi( mode );
	}
	if( (q = im_getnextoption( &p )) ) {
		if( strcmp( q, "" ) != 0 ) 
			profile = q;
	}
	if( (q = im_getnextoption( &p )) ) {
		im_error( "im_vips2jpeg", 
			_( "unknown extra options \"%s\"" ), q );
		return( -1 );
	}

	if( !(write = write_new( in )) )
		return( -1 );

	if( setjmp( write->eman.jmp ) ) {
		/* Here for longjmp() from new_error_exit().
		 */
		write_destroy( write );

		return( -1 );
	}

	/* Can't do this in write_new(), has to be after we've made the
	 * setjmp().
	 */
        jpeg_create_compress( &write->cinfo );

	/* Make output.
	 */
        if( !(write->eman.fp = im__file_open_write( name )) ) {
		write_destroy( write );
                return( -1 );
        }
        jpeg_stdio_dest( &write->cinfo, write->eman.fp );

	/* Convert!
	 */
	if( write_vips( write, qfac, profile ) ) {
		write_destroy( write );
		return( -1 );
	}
	write_destroy( write );

	return( 0 );
}

/* Just like the above, but we write to a memory buffer.
 *
 * A memory buffer for the compressed image.
 */
typedef struct {
	/* Public jpeg fields.
	 */
	struct jpeg_destination_mgr pub;

	/* Private stuff during write.
	 */
	JOCTET *data;		/* Allocated area */
	int used;		/* Number of bytes written so far */
	int size;		/* Max size */

	/* Copy the compressed area here.
	 */
	IMAGE *out;		/* Allocate relative to this */
	char **obuf;		/* Allocated buffer, and size */
	int *olen;
} OutputBuffer;

/* Init dest method.
 */
METHODDEF(void)
init_destination( j_compress_ptr cinfo )
{
	OutputBuffer *buf = (OutputBuffer *) cinfo->dest;
	int mx = cinfo->image_width * cinfo->image_height * 
		cinfo->input_components * sizeof( JOCTET );

	/* Allocate relative to the image we are writing .. freed when we junk
	 * this output.
	 */
	buf->data = (JOCTET *) (*cinfo->mem->alloc_large) 
			( (j_common_ptr) cinfo, JPOOL_IMAGE, mx );
	buf->used = 0;
	buf->size = mx;

	/* Set buf pointers for library.
	 */
	buf->pub.next_output_byte = buf->data;
	buf->pub.free_in_buffer = mx;
}

/* Buffer full method ... should never get this.
 */
METHODDEF(boolean)
empty_output_buffer( j_compress_ptr cinfo )
{
	/* Not really a file write error, but why not. Should never happen.
	 */
	ERREXIT( cinfo, JERR_FILE_WRITE );

	return( 0 );
}

/* Cleanup. Write entire buffer as a MIME type.
 */
METHODDEF(void)
term_destination( j_compress_ptr cinfo )
{
        OutputBuffer *buf = (OutputBuffer *) cinfo->dest;
	int len = buf->size - buf->pub.free_in_buffer;
	void *obuf;

	/* Allocate and copy to the VIPS output area.
	 */
	if( !(obuf = im_malloc( buf->out, len )) )
		ERREXIT( cinfo, JERR_FILE_WRITE );
	memcpy( obuf, buf->data, len );
	*(buf->obuf) = obuf;
	*(buf->olen) = len;
}

/* Set dest to one of our objects.
 */
static void
buf_dest( j_compress_ptr cinfo, IMAGE *out, char **obuf, int *olen )
{
	OutputBuffer *buf;

	/* The destination object is made permanent so that multiple JPEG 
	 * images can be written to the same file without re-executing 
	 * jpeg_stdio_dest. This makes it dangerous to use this manager and 
	 * a different destination manager serially with the same JPEG object,
	 * because their private object sizes may be different.  
	 *
	 * Caveat programmer.
	 */
	if( !cinfo->dest ) {    /* first time for this JPEG object? */
		cinfo->dest = (struct jpeg_destination_mgr *)
			(*cinfo->mem->alloc_small) 
				( (j_common_ptr) cinfo, JPOOL_PERMANENT,
				  sizeof( OutputBuffer ) );
	}

	buf = (OutputBuffer *) cinfo->dest;
	buf->pub.init_destination = init_destination;
	buf->pub.empty_output_buffer = empty_output_buffer;
	buf->pub.term_destination = term_destination;

	/* Save output parameters.
	 */
	buf->out = out;
	buf->obuf = obuf;
	buf->olen = olen;
}

/**
 * im_vips2bufjpeg:
 * @in: image to save 
 * @out: allocate output buffer local to this
 * @qfac: JPEG quality factor
 * @obuf: return output buffer here
 * @olen: return output length here
 *
 * As im_vips2jpeg(), but save as a memory buffer. The memory is allocated
 * local to @out (that is, when @out is closed the memory will be released,
 * pass %NULL to release yourself). 
 *
 * The address of the buffer is returned in @obuf, the length of the buffer in
 * @olen. @olen should really be a size_t rather than an int :-(
 *
 * See also: #VipsFormat, im_vips2jpeg().
 *
 * Returns: 0 on success, -1 on error.
 */
int
im_vips2bufjpeg( IMAGE *in, IMAGE *out, int qfac, char **obuf, int *olen )
{
	Write *write;

	if( !(write = write_new( in )) )
		return( -1 );

	/* Clear output parameters.
	 */
	*obuf = NULL;
	*olen = 0;

	/* Make jpeg compression object.
 	 */
	if( setjmp( write->eman.jmp ) ) {
		/* Here for longjmp() from new_error_exit().
		 */
		write_destroy( write );

		return( -1 );
	}
        jpeg_create_compress( &write->cinfo );

	/* Attach output.
	 */
        buf_dest( &write->cinfo, out, obuf, olen );

	/* Convert!
	 */
	if( write_vips( write, qfac, NULL ) ) {
		write_destroy( write );

		return( -1 );
	}
	write_destroy( write );

	return( 0 );
}

/**
 * im_vips2mimejpeg:
 * @in: image to save 
 * @qfac: JPEG quality factor
 *
 * As im_vips2jpeg(), but save as a mime jpeg on stdout.
 *
 * See also: #VipsFormat, im_vips2jpeg().
 *
 * Returns: 0 on success, -1 on error.
 */
int
im_vips2mimejpeg( IMAGE *in, int qfac )
{
	IMAGE *base;
	int len;
	char *buf;

	if( !(base = im_open( "im_vips2mimejpeg:1", "p" )) )
		return( -1 );
	if( im_vips2bufjpeg( in, base, qfac, &buf, &len ) ) {
		im_close( base );
		return( -1 );
	}

	/* Write as a MIME type.
	 */
	printf( "Content-length: %d\r\n", len );
	printf( "Content-type: image/jpeg\r\n" );
	printf( "\r\n" );
	if( fwrite( buf, sizeof( char ), len, stdout ) != (size_t) len ) {
		im_error( "im_vips2mimejpeg", 
			"%s", _( "error writing output" ) );
		return( -1 );
	}

	fflush( stdout );
	im_close( base );

	return( 0 );
}

#endif /*HAVE_JPEG*/
