remove old jpeg load stuff
it's just stream now works on buffer, but seems to fail on vipsheader йцук.jpg curiously
This commit is contained in:
parent
ad822109d4
commit
6c1d7db31b
@ -111,9 +111,18 @@ jpeg2vips( const char *name, IMAGE *out, gboolean header_only )
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_JPEG
|
#ifdef HAVE_JPEG
|
||||||
if( vips__jpeg_read_file( filename, out,
|
{
|
||||||
header_only, shrink, fail_on_warn, FALSE ) )
|
VipsStreamInput *input;
|
||||||
|
|
||||||
|
if( !(input = vips_stream_input_new_from_filename( filename )) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
if( vips__jpeg_read_stream( input, out,
|
||||||
|
header_only, shrink, fail_on_warn, FALSE ) ) {
|
||||||
|
VIPS_UNREF( input );
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
VIPS_UNREF( input );
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
vips_error( "im_jpeg2vips",
|
vips_error( "im_jpeg2vips",
|
||||||
"%s", _( "no JPEG support in your libvips" ) );
|
"%s", _( "no JPEG support in your libvips" ) );
|
||||||
|
@ -169,10 +169,6 @@ typedef struct _ReadJpeg {
|
|||||||
*/
|
*/
|
||||||
gboolean fail;
|
gboolean fail;
|
||||||
|
|
||||||
/* Used for file input only.
|
|
||||||
*/
|
|
||||||
char *filename;
|
|
||||||
|
|
||||||
struct jpeg_decompress_struct cinfo;
|
struct jpeg_decompress_struct cinfo;
|
||||||
ErrorManager eman;
|
ErrorManager eman;
|
||||||
gboolean invert_pels;
|
gboolean invert_pels;
|
||||||
@ -193,113 +189,12 @@ typedef struct _ReadJpeg {
|
|||||||
int output_width;
|
int output_width;
|
||||||
int output_height;
|
int output_height;
|
||||||
|
|
||||||
/* If we close and reopen, save the ftell point here.
|
|
||||||
*/
|
|
||||||
long seek_position;
|
|
||||||
|
|
||||||
/* The memory area we read from.
|
|
||||||
*/
|
|
||||||
const void *buf;
|
|
||||||
size_t len;
|
|
||||||
|
|
||||||
/* The stream we read from.
|
/* The stream we read from.
|
||||||
*/
|
*/
|
||||||
VipsStreamInput *input;
|
VipsStreamInput *input;
|
||||||
|
|
||||||
} ReadJpeg;
|
} ReadJpeg;
|
||||||
|
|
||||||
/* Private struct for memory input.
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
/* Public jpeg fields.
|
|
||||||
*/
|
|
||||||
struct jpeg_source_mgr pub;
|
|
||||||
|
|
||||||
/* Private stuff during read.
|
|
||||||
*/
|
|
||||||
const JOCTET *buf;
|
|
||||||
size_t len;
|
|
||||||
} InputBuffer;
|
|
||||||
|
|
||||||
static void
|
|
||||||
init_source( j_decompress_ptr cinfo )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Fill the input buffer --- called whenever buffer is emptied.
|
|
||||||
*
|
|
||||||
* We fill the buffer on readjpeg_buffer(), so this will only be called if
|
|
||||||
* libjpeg tries to read beyond the buffer.
|
|
||||||
*/
|
|
||||||
static boolean
|
|
||||||
fill_input_buffer( j_decompress_ptr cinfo )
|
|
||||||
{
|
|
||||||
static const JOCTET eoi_buffer[4] = {
|
|
||||||
(JOCTET) 0xFF, (JOCTET) JPEG_EOI, 0, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
InputBuffer *src = (InputBuffer *) cinfo->src;
|
|
||||||
|
|
||||||
WARNMS( cinfo, JWRN_JPEG_EOF );
|
|
||||||
src->pub.next_input_byte = eoi_buffer;
|
|
||||||
src->pub.bytes_in_buffer = 2;
|
|
||||||
|
|
||||||
return( TRUE );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Skip data --- used to skip over a potentially large amount of
|
|
||||||
* uninteresting data (such as an APPn marker).
|
|
||||||
*
|
|
||||||
* Writers of suspendable-input applications must note that skip_input_data
|
|
||||||
* is not granted the right to give a suspension return. If the skip extends
|
|
||||||
* beyond the data currently in the buffer, the buffer can be marked empty so
|
|
||||||
* that the next read will cause a fill_input_buffer call that can suspend.
|
|
||||||
* Arranging for additional bytes to be discarded before reloading the input
|
|
||||||
* buffer is the application writer's problem.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
skip_input_data( j_decompress_ptr cinfo, long num_bytes )
|
|
||||||
{
|
|
||||||
InputBuffer *src = (InputBuffer *) cinfo->src;
|
|
||||||
|
|
||||||
if( num_bytes > 0 ) {
|
|
||||||
while (num_bytes > (long) src->pub.bytes_in_buffer) {
|
|
||||||
num_bytes -= (long) src->pub.bytes_in_buffer;
|
|
||||||
(void) (*src->pub.fill_input_buffer) (cinfo);
|
|
||||||
|
|
||||||
/* note we assume that fill_input_buffer will never
|
|
||||||
* return FALSE, so suspension need not be handled.
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
src->pub.next_input_byte += (size_t) num_bytes;
|
|
||||||
src->pub.bytes_in_buffer -= (size_t) num_bytes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* An additional method that can be provided by data source modules is the
|
|
||||||
* resync_to_restart method for error recovery in the presence of RST markers.
|
|
||||||
* For the moment, this source module just uses the default resync method
|
|
||||||
* provided by the JPEG library. That method assumes that no backtracking
|
|
||||||
* is possible.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Terminate source --- called by jpeg_finish_decompress
|
|
||||||
* after all data has been read. Often a no-op.
|
|
||||||
*
|
|
||||||
* NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
|
|
||||||
* application must deal with any cleanup that should happen even
|
|
||||||
* for error exit.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
term_source( j_decompress_ptr cinfo )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#define STREAM_BUFFER_SIZE (4096)
|
#define STREAM_BUFFER_SIZE (4096)
|
||||||
|
|
||||||
/* Private struct for stream input.
|
/* Private struct for stream input.
|
||||||
@ -314,18 +209,18 @@ typedef struct {
|
|||||||
VipsStreamInput *input;
|
VipsStreamInput *input;
|
||||||
unsigned char buf[STREAM_BUFFER_SIZE];
|
unsigned char buf[STREAM_BUFFER_SIZE];
|
||||||
|
|
||||||
} InputSource;
|
} Source;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
stream_init_source( j_decompress_ptr cinfo )
|
stream_init_source( j_decompress_ptr cinfo )
|
||||||
{
|
{
|
||||||
InputSource *source = (InputSource *) cinfo->src;
|
Source *src = (Source *) cinfo->src;
|
||||||
|
|
||||||
/* Start off empty ... libjpeg will call fill_input_buffer to get the
|
/* Start off empty ... libjpeg will call fill_input_buffer to get the
|
||||||
* first bytes.
|
* first bytes.
|
||||||
*/
|
*/
|
||||||
source->pub.next_input_byte = source->buf;
|
src->pub.next_input_byte = src->buf;
|
||||||
source->pub.bytes_in_buffer = 0;
|
src->pub.bytes_in_buffer = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fill the input buffer --- called whenever buffer is emptied.
|
/* Fill the input buffer --- called whenever buffer is emptied.
|
||||||
@ -337,19 +232,19 @@ stream_fill_input_buffer( j_decompress_ptr cinfo )
|
|||||||
(JOCTET) 0xFF, (JOCTET) JPEG_EOI, 0, 0
|
(JOCTET) 0xFF, (JOCTET) JPEG_EOI, 0, 0
|
||||||
};
|
};
|
||||||
|
|
||||||
InputSource *source = (InputSource *) cinfo->src;
|
Source *src = (Source *) cinfo->src;
|
||||||
|
|
||||||
size_t read;
|
size_t read;
|
||||||
|
|
||||||
if( (read = vips_stream_input_read( source->input,
|
if( (read = vips_stream_input_read( src->input,
|
||||||
source->buf, STREAM_BUFFER_SIZE )) == -1 ) {
|
src->buf, STREAM_BUFFER_SIZE )) > 0 ) {
|
||||||
WARNMS( cinfo, JWRN_JPEG_EOF );
|
src->pub.next_input_byte = src->buf;
|
||||||
source->pub.next_input_byte = eoi_buffer;
|
src->pub.bytes_in_buffer = read;
|
||||||
source->pub.bytes_in_buffer = 2;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
source->pub.next_input_byte = source->buf;
|
WARNMS( cinfo, JWRN_JPEG_EOF );
|
||||||
source->pub.bytes_in_buffer = read;
|
src->pub.next_input_byte = eoi_buffer;
|
||||||
|
src->pub.bytes_in_buffer = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
return( TRUE );
|
return( TRUE );
|
||||||
@ -360,41 +255,9 @@ readjpeg_open_input( ReadJpeg *jpeg )
|
|||||||
{
|
{
|
||||||
j_decompress_ptr cinfo = &jpeg->cinfo;
|
j_decompress_ptr cinfo = &jpeg->cinfo;
|
||||||
|
|
||||||
if( jpeg->filename &&
|
|
||||||
!jpeg->eman.fp ) {
|
|
||||||
if( !(jpeg->eman.fp =
|
|
||||||
vips__file_open_read( jpeg->filename, NULL, FALSE )) )
|
|
||||||
return( -1 );
|
|
||||||
jpeg_stdio_src( cinfo, jpeg->eman.fp );
|
|
||||||
if( jpeg->seek_position != -1 )
|
|
||||||
fseek( jpeg->eman.fp, jpeg->seek_position, SEEK_SET );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( jpeg->buf &&
|
|
||||||
!cinfo->src ) {
|
|
||||||
InputBuffer *src;
|
|
||||||
|
|
||||||
cinfo->src = (struct jpeg_source_mgr *)
|
|
||||||
(*cinfo->mem->alloc_small)(
|
|
||||||
(j_common_ptr) cinfo, JPOOL_PERMANENT,
|
|
||||||
sizeof( InputBuffer ) );
|
|
||||||
|
|
||||||
src = (InputBuffer *) cinfo->src;
|
|
||||||
src->buf = jpeg->buf;
|
|
||||||
src->len = jpeg->len;
|
|
||||||
|
|
||||||
src->pub.init_source = init_source;
|
|
||||||
src->pub.fill_input_buffer = fill_input_buffer;
|
|
||||||
src->pub.skip_input_data = skip_input_data;
|
|
||||||
src->pub.resync_to_restart = jpeg_resync_to_restart;
|
|
||||||
src->pub.term_source = term_source;
|
|
||||||
src->pub.bytes_in_buffer = jpeg->len;
|
|
||||||
src->pub.next_input_byte = jpeg->buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( jpeg->input &&
|
if( jpeg->input &&
|
||||||
!cinfo->src ) {
|
!cinfo->src ) {
|
||||||
InputSource *src;
|
Source *src;
|
||||||
|
|
||||||
if( vips_stream_input_rewind( jpeg->input ) )
|
if( vips_stream_input_rewind( jpeg->input ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
@ -402,15 +265,13 @@ readjpeg_open_input( ReadJpeg *jpeg )
|
|||||||
cinfo->src = (struct jpeg_source_mgr *)
|
cinfo->src = (struct jpeg_source_mgr *)
|
||||||
(*cinfo->mem->alloc_small)(
|
(*cinfo->mem->alloc_small)(
|
||||||
(j_common_ptr) cinfo, JPOOL_PERMANENT,
|
(j_common_ptr) cinfo, JPOOL_PERMANENT,
|
||||||
sizeof( InputSource ) );
|
sizeof( Source ) );
|
||||||
|
|
||||||
src = (InputSource *) cinfo->src;
|
src = (Source *) cinfo->src;
|
||||||
src->input = jpeg->input;
|
src->input = jpeg->input;
|
||||||
src->pub.init_source = stream_init_source;
|
src->pub.init_source = stream_init_source;
|
||||||
src->pub.fill_input_buffer = stream_fill_input_buffer;
|
src->pub.fill_input_buffer = stream_fill_input_buffer;
|
||||||
src->pub.skip_input_data = skip_input_data;
|
|
||||||
src->pub.resync_to_restart = jpeg_resync_to_restart;
|
src->pub.resync_to_restart = jpeg_resync_to_restart;
|
||||||
src->pub.term_source = term_source;
|
|
||||||
src->pub.bytes_in_buffer = 0;
|
src->pub.bytes_in_buffer = 0;
|
||||||
src->pub.next_input_byte = src->buf;
|
src->pub.next_input_byte = src->buf;
|
||||||
}
|
}
|
||||||
@ -418,21 +279,6 @@ readjpeg_open_input( ReadJpeg *jpeg )
|
|||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This can be called many times.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
readjpeg_close_input( ReadJpeg *jpeg )
|
|
||||||
{
|
|
||||||
#ifdef DEBUG
|
|
||||||
printf( "readjpeg_close_input:\n" );
|
|
||||||
#endif /*DEBUG*/
|
|
||||||
|
|
||||||
if( jpeg->eman.fp ) {
|
|
||||||
jpeg->seek_position = ftell( jpeg->eman.fp );
|
|
||||||
VIPS_FREEF( fclose, jpeg->eman.fp );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This can be called many times.
|
/* This can be called many times.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
@ -448,8 +294,6 @@ readjpeg_free( ReadJpeg *jpeg )
|
|||||||
jpeg->eman.pub.num_warnings = 0;
|
jpeg->eman.pub.num_warnings = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
readjpeg_close_input( jpeg );
|
|
||||||
|
|
||||||
/* Don't call jpeg_finish_decompress(). It just checks the tail of the
|
/* Don't call jpeg_finish_decompress(). It just checks the tail of the
|
||||||
* file and who cares about that. All mem is freed in
|
* file and who cares about that. All mem is freed in
|
||||||
* jpeg_destroy_decompress().
|
* jpeg_destroy_decompress().
|
||||||
@ -459,7 +303,7 @@ readjpeg_free( ReadJpeg *jpeg )
|
|||||||
*/
|
*/
|
||||||
jpeg_destroy_decompress( &jpeg->cinfo );
|
jpeg_destroy_decompress( &jpeg->cinfo );
|
||||||
|
|
||||||
VIPS_FREE( jpeg->filename );
|
VIPS_UNREF( jpeg->input );
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
@ -470,34 +314,25 @@ readjpeg_close_cb( VipsObject *object, ReadJpeg *jpeg )
|
|||||||
(void) readjpeg_free( jpeg );
|
(void) readjpeg_free( jpeg );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
readjpeg_minimise_cb( VipsObject *object, ReadJpeg *jpeg )
|
|
||||||
{
|
|
||||||
#ifdef DEBUG
|
|
||||||
printf( "readjpeg_minimise_cb:\n" );
|
|
||||||
#endif /*DEBUG*/
|
|
||||||
|
|
||||||
readjpeg_close_input( jpeg );
|
|
||||||
}
|
|
||||||
|
|
||||||
static ReadJpeg *
|
static ReadJpeg *
|
||||||
readjpeg_new( VipsImage *out, int shrink, gboolean fail, gboolean autorotate )
|
readjpeg_new( VipsStreamInput *input, VipsImage *out,
|
||||||
|
int shrink, gboolean fail, gboolean autorotate )
|
||||||
{
|
{
|
||||||
ReadJpeg *jpeg;
|
ReadJpeg *jpeg;
|
||||||
|
|
||||||
if( !(jpeg = VIPS_NEW( out, ReadJpeg )) )
|
if( !(jpeg = VIPS_NEW( out, ReadJpeg )) )
|
||||||
return( NULL );
|
return( NULL );
|
||||||
|
|
||||||
|
jpeg->input = input;
|
||||||
|
g_object_ref( input );
|
||||||
jpeg->shrink = shrink;
|
jpeg->shrink = shrink;
|
||||||
jpeg->fail = fail;
|
jpeg->fail = fail;
|
||||||
jpeg->filename = NULL;
|
|
||||||
jpeg->cinfo.err = jpeg_std_error( &jpeg->eman.pub );
|
jpeg->cinfo.err = jpeg_std_error( &jpeg->eman.pub );
|
||||||
jpeg->eman.pub.error_exit = vips__new_error_exit;
|
jpeg->eman.pub.error_exit = vips__new_error_exit;
|
||||||
jpeg->eman.pub.output_message = vips__new_output_message;
|
jpeg->eman.pub.output_message = vips__new_output_message;
|
||||||
jpeg->eman.fp = NULL;
|
jpeg->eman.fp = NULL;
|
||||||
jpeg->y_pos = 0;
|
jpeg->y_pos = 0;
|
||||||
jpeg->autorotate = autorotate;
|
jpeg->autorotate = autorotate;
|
||||||
jpeg->seek_position = -1;
|
|
||||||
|
|
||||||
/* This is used by the error handlers to signal invalidate on the
|
/* This is used by the error handlers to signal invalidate on the
|
||||||
* output image.
|
* output image.
|
||||||
@ -514,24 +349,10 @@ readjpeg_new( VipsImage *out, int shrink, gboolean fail, gboolean autorotate )
|
|||||||
|
|
||||||
g_signal_connect( out, "close",
|
g_signal_connect( out, "close",
|
||||||
G_CALLBACK( readjpeg_close_cb ), jpeg );
|
G_CALLBACK( readjpeg_close_cb ), jpeg );
|
||||||
g_signal_connect( out, "minimise",
|
|
||||||
G_CALLBACK( readjpeg_minimise_cb ), jpeg );
|
|
||||||
|
|
||||||
return( jpeg );
|
return( jpeg );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set input to a file.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
readjpeg_file( ReadJpeg *jpeg, const char *filename )
|
|
||||||
{
|
|
||||||
jpeg->filename = g_strdup( filename );
|
|
||||||
if( readjpeg_open_input( jpeg ) )
|
|
||||||
return( -1 );
|
|
||||||
|
|
||||||
return( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
find_chroma_subsample( struct jpeg_decompress_struct *cinfo )
|
find_chroma_subsample( struct jpeg_decompress_struct *cinfo )
|
||||||
{
|
{
|
||||||
@ -974,11 +795,6 @@ read_jpeg_generate( VipsRegion *or,
|
|||||||
jpeg->y_pos += 1;
|
jpeg->y_pos += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Shut down the input early if we can.
|
|
||||||
*/
|
|
||||||
if( jpeg->y_pos >= or->im->Ysize )
|
|
||||||
readjpeg_close_input( jpeg );
|
|
||||||
|
|
||||||
VIPS_GATE_STOP( "read_jpeg_generate: work" );
|
VIPS_GATE_STOP( "read_jpeg_generate: work" );
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
@ -1063,8 +879,6 @@ read_jpeg_image( ReadJpeg *jpeg, VipsImage *out )
|
|||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read the jpeg from file or buffer.
|
|
||||||
*/
|
|
||||||
static int
|
static int
|
||||||
vips__jpeg_read( ReadJpeg *jpeg, VipsImage *out, gboolean header_only )
|
vips__jpeg_read( ReadJpeg *jpeg, VipsImage *out, gboolean header_only )
|
||||||
{
|
{
|
||||||
@ -1120,103 +934,18 @@ vips__jpeg_read( ReadJpeg *jpeg, VipsImage *out, gboolean header_only )
|
|||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read a JPEG file into a VIPS image.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
vips__jpeg_read_file( const char *filename, VipsImage *out,
|
|
||||||
gboolean header_only, int shrink, gboolean fail,
|
|
||||||
gboolean autorotate )
|
|
||||||
{
|
|
||||||
ReadJpeg *jpeg;
|
|
||||||
|
|
||||||
if( !(jpeg = readjpeg_new( out, shrink, fail, autorotate )) )
|
|
||||||
return( -1 );
|
|
||||||
|
|
||||||
/* Here for longjmp() from vips__new_error_exit() during startup.
|
|
||||||
*/
|
|
||||||
if( setjmp( jpeg->eman.jmp ) )
|
|
||||||
return( -1 );
|
|
||||||
|
|
||||||
/* Set input to file.
|
|
||||||
*/
|
|
||||||
if( readjpeg_file( jpeg, filename ) )
|
|
||||||
return( -1 );
|
|
||||||
|
|
||||||
if( vips__jpeg_read( jpeg, out, header_only ) )
|
|
||||||
return( -1 );
|
|
||||||
|
|
||||||
VIPS_SETSTR( out->filename, filename );
|
|
||||||
|
|
||||||
/* We can kill off the decompress early if this is just a header read.
|
|
||||||
* This saves an fd during read.
|
|
||||||
*/
|
|
||||||
if( header_only )
|
|
||||||
readjpeg_free( jpeg );
|
|
||||||
|
|
||||||
return( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
vips__jpeg_read_buffer( const void *buf, size_t len, VipsImage *out,
|
|
||||||
gboolean header_only, int shrink, int fail, gboolean autorotate )
|
|
||||||
{
|
|
||||||
ReadJpeg *jpeg;
|
|
||||||
|
|
||||||
if( !(jpeg = readjpeg_new( out, shrink, fail, autorotate )) )
|
|
||||||
return( -1 );
|
|
||||||
|
|
||||||
if( setjmp( jpeg->eman.jmp ) )
|
|
||||||
return( -1 );
|
|
||||||
|
|
||||||
jpeg->buf = buf;
|
|
||||||
jpeg->len = len;
|
|
||||||
if( readjpeg_open_input( jpeg ) )
|
|
||||||
return( -1 );
|
|
||||||
|
|
||||||
if( vips__jpeg_read( jpeg, out, header_only ) )
|
|
||||||
return( -1 );
|
|
||||||
|
|
||||||
return( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
vips__isjpeg_buffer( const void *buf, size_t len )
|
|
||||||
{
|
|
||||||
const guchar *str = (const guchar *) buf;
|
|
||||||
|
|
||||||
if( len >= 2 &&
|
|
||||||
str[0] == 0xff &&
|
|
||||||
str[1] == 0xd8 )
|
|
||||||
return( 1 );
|
|
||||||
|
|
||||||
return( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
vips__isjpeg( const char *filename )
|
|
||||||
{
|
|
||||||
unsigned char buf[2];
|
|
||||||
|
|
||||||
if( vips__get_bytes( filename, buf, 2 ) == 2 &&
|
|
||||||
vips__isjpeg_buffer( buf, 2 ) )
|
|
||||||
return( 1 );
|
|
||||||
|
|
||||||
return( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
vips__jpeg_read_stream( VipsStreamInput *input, VipsImage *out,
|
vips__jpeg_read_stream( VipsStreamInput *input, VipsImage *out,
|
||||||
gboolean header_only, int shrink, int fail, gboolean autorotate )
|
gboolean header_only, int shrink, int fail, gboolean autorotate )
|
||||||
{
|
{
|
||||||
ReadJpeg *jpeg;
|
ReadJpeg *jpeg;
|
||||||
|
|
||||||
if( !(jpeg = readjpeg_new( out, shrink, fail, autorotate )) )
|
if( !(jpeg = readjpeg_new( input, out, shrink, fail, autorotate )) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
if( setjmp( jpeg->eman.jmp ) )
|
if( setjmp( jpeg->eman.jmp ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
jpeg->input = input;
|
|
||||||
if( readjpeg_open_input( jpeg ) )
|
if( readjpeg_open_input( jpeg ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
@ -1232,7 +961,8 @@ vips__isjpeg_stream( VipsStreamInput *input )
|
|||||||
const unsigned char *p;
|
const unsigned char *p;
|
||||||
|
|
||||||
if( (p = vips_stream_input_sniff( input, 2 )) &&
|
if( (p = vips_stream_input_sniff( input, 2 )) &&
|
||||||
vips__isjpeg_buffer( p, 2 ) )
|
p[0] == 0xff &&
|
||||||
|
p[1] == 0xd8 )
|
||||||
return( 1 );
|
return( 1 );
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
|
@ -155,171 +155,9 @@ vips_foreign_load_jpeg_init( VipsForeignLoadJpeg *jpeg )
|
|||||||
jpeg->shrink = 1;
|
jpeg->shrink = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct _VipsForeignLoadJpegFile {
|
|
||||||
VipsForeignLoadJpeg parent_object;
|
|
||||||
|
|
||||||
/* Filename for load.
|
|
||||||
*/
|
|
||||||
char *filename;
|
|
||||||
|
|
||||||
} VipsForeignLoadJpegFile;
|
|
||||||
|
|
||||||
typedef VipsForeignLoadJpegClass VipsForeignLoadJpegFileClass;
|
|
||||||
|
|
||||||
G_DEFINE_TYPE( VipsForeignLoadJpegFile, vips_foreign_load_jpeg_file,
|
|
||||||
vips_foreign_load_jpeg_get_type() );
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
vips_foreign_load_jpeg_file_is_a( const char *filename )
|
|
||||||
{
|
|
||||||
return( vips__isjpeg( filename ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
vips_foreign_load_jpeg_file_header( VipsForeignLoad *load )
|
|
||||||
{
|
|
||||||
VipsForeignLoadJpeg *jpeg = (VipsForeignLoadJpeg *) load;
|
|
||||||
VipsForeignLoadJpegFile *file = (VipsForeignLoadJpegFile *) load;
|
|
||||||
|
|
||||||
if( vips__jpeg_read_file( file->filename, load->out,
|
|
||||||
TRUE, jpeg->shrink, load->fail, jpeg->autorotate ) )
|
|
||||||
return( -1 );
|
|
||||||
|
|
||||||
return( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
vips_foreign_load_jpeg_file_load( VipsForeignLoad *load )
|
|
||||||
{
|
|
||||||
VipsForeignLoadJpeg *jpeg = (VipsForeignLoadJpeg *) load;
|
|
||||||
VipsForeignLoadJpegFile *file = (VipsForeignLoadJpegFile *) load;
|
|
||||||
|
|
||||||
if( vips__jpeg_read_file( file->filename, load->real,
|
|
||||||
FALSE, jpeg->shrink, load->fail, jpeg->autorotate ) )
|
|
||||||
return( -1 );
|
|
||||||
|
|
||||||
return( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
vips_foreign_load_jpeg_file_class_init( VipsForeignLoadJpegFileClass *class )
|
|
||||||
{
|
|
||||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
|
||||||
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
|
||||||
VipsForeignClass *foreign_class = (VipsForeignClass *) class;
|
|
||||||
VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class;
|
|
||||||
|
|
||||||
gobject_class->set_property = vips_object_set_property;
|
|
||||||
gobject_class->get_property = vips_object_get_property;
|
|
||||||
|
|
||||||
object_class->nickname = "jpegload";
|
|
||||||
object_class->description = _( "load jpeg from file" );
|
|
||||||
|
|
||||||
foreign_class->suffs = vips__jpeg_suffs;
|
|
||||||
|
|
||||||
/* We are fast at is_a(), so high priority.
|
|
||||||
*/
|
|
||||||
foreign_class->priority = 50;
|
|
||||||
|
|
||||||
load_class->is_a = vips_foreign_load_jpeg_file_is_a;
|
|
||||||
load_class->header = vips_foreign_load_jpeg_file_header;
|
|
||||||
load_class->load = vips_foreign_load_jpeg_file_load;
|
|
||||||
|
|
||||||
VIPS_ARG_STRING( class, "filename", 1,
|
|
||||||
_( "Filename" ),
|
|
||||||
_( "Filename to load from" ),
|
|
||||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
|
||||||
G_STRUCT_OFFSET( VipsForeignLoadJpegFile, filename ),
|
|
||||||
NULL );
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
vips_foreign_load_jpeg_file_init( VipsForeignLoadJpegFile *file )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct _VipsForeignLoadJpegBuffer {
|
|
||||||
VipsForeignLoadJpeg parent_object;
|
|
||||||
|
|
||||||
/* Load from a buffer.
|
|
||||||
*/
|
|
||||||
VipsArea *buf;
|
|
||||||
|
|
||||||
} VipsForeignLoadJpegBuffer;
|
|
||||||
|
|
||||||
typedef VipsForeignLoadJpegClass VipsForeignLoadJpegBufferClass;
|
|
||||||
|
|
||||||
G_DEFINE_TYPE( VipsForeignLoadJpegBuffer, vips_foreign_load_jpeg_buffer,
|
|
||||||
vips_foreign_load_jpeg_get_type() );
|
|
||||||
|
|
||||||
static int
|
|
||||||
vips_foreign_load_jpeg_buffer_header( VipsForeignLoad *load )
|
|
||||||
{
|
|
||||||
VipsForeignLoadJpeg *jpeg = (VipsForeignLoadJpeg *) load;
|
|
||||||
VipsForeignLoadJpegBuffer *buffer = (VipsForeignLoadJpegBuffer *) load;
|
|
||||||
|
|
||||||
if( vips__jpeg_read_buffer( buffer->buf->data, buffer->buf->length,
|
|
||||||
load->out, TRUE, jpeg->shrink, load->fail, jpeg->autorotate ) )
|
|
||||||
return( -1 );
|
|
||||||
|
|
||||||
return( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
vips_foreign_load_jpeg_buffer_load( VipsForeignLoad *load )
|
|
||||||
{
|
|
||||||
VipsForeignLoadJpeg *jpeg = (VipsForeignLoadJpeg *) load;
|
|
||||||
VipsForeignLoadJpegBuffer *buffer = (VipsForeignLoadJpegBuffer *) load;
|
|
||||||
|
|
||||||
if( vips__jpeg_read_buffer( buffer->buf->data, buffer->buf->length,
|
|
||||||
load->real, FALSE, jpeg->shrink, load->fail, jpeg->autorotate ) )
|
|
||||||
return( -1 );
|
|
||||||
|
|
||||||
return( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
vips_foreign_load_jpeg_buffer_is_a( const void *buf, size_t len )
|
|
||||||
{
|
|
||||||
return( vips__isjpeg_buffer( buf, len ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
vips_foreign_load_jpeg_buffer_class_init(
|
|
||||||
VipsForeignLoadJpegBufferClass *class )
|
|
||||||
{
|
|
||||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
|
||||||
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
|
||||||
VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class;
|
|
||||||
|
|
||||||
gobject_class->set_property = vips_object_set_property;
|
|
||||||
gobject_class->get_property = vips_object_get_property;
|
|
||||||
|
|
||||||
object_class->nickname = "jpegload_buffer";
|
|
||||||
object_class->description = _( "load jpeg from buffer" );
|
|
||||||
|
|
||||||
load_class->is_a_buffer = vips_foreign_load_jpeg_buffer_is_a;
|
|
||||||
load_class->header = vips_foreign_load_jpeg_buffer_header;
|
|
||||||
load_class->load = vips_foreign_load_jpeg_buffer_load;
|
|
||||||
|
|
||||||
VIPS_ARG_BOXED( class, "buffer", 1,
|
|
||||||
_( "Buffer" ),
|
|
||||||
_( "Buffer to load from" ),
|
|
||||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
|
||||||
G_STRUCT_OFFSET( VipsForeignLoadJpegBuffer, buf ),
|
|
||||||
VIPS_TYPE_BLOB );
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
vips_foreign_load_jpeg_buffer_init( VipsForeignLoadJpegBuffer *buffer )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct _VipsForeignLoadJpegStream {
|
typedef struct _VipsForeignLoadJpegStream {
|
||||||
VipsForeignLoadJpeg parent_object;
|
VipsForeignLoadJpeg parent_object;
|
||||||
|
|
||||||
/* Load from a buffer.
|
|
||||||
*/
|
|
||||||
VipsStreamInput *input;
|
VipsStreamInput *input;
|
||||||
|
|
||||||
} VipsForeignLoadJpegStream;
|
} VipsForeignLoadJpegStream;
|
||||||
@ -395,6 +233,206 @@ vips_foreign_load_jpeg_stream_init( VipsForeignLoadJpegStream *stream )
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct _VipsForeignLoadJpegFile {
|
||||||
|
VipsForeignLoadJpeg parent_object;
|
||||||
|
|
||||||
|
char *filename;
|
||||||
|
|
||||||
|
} VipsForeignLoadJpegFile;
|
||||||
|
|
||||||
|
typedef VipsForeignLoadJpegClass VipsForeignLoadJpegFileClass;
|
||||||
|
|
||||||
|
G_DEFINE_TYPE( VipsForeignLoadJpegFile, vips_foreign_load_jpeg_file,
|
||||||
|
vips_foreign_load_jpeg_get_type() );
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
vips_foreign_load_jpeg_file_is_a( const char *filename )
|
||||||
|
{
|
||||||
|
VipsStreamInput *input;
|
||||||
|
gboolean result;
|
||||||
|
|
||||||
|
if( !(input = vips_stream_input_new_from_filename( filename )) )
|
||||||
|
return( FALSE );
|
||||||
|
result = vips__isjpeg_stream( input );
|
||||||
|
VIPS_UNREF( input );
|
||||||
|
|
||||||
|
return( result );
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
vips_foreign_load_jpeg_file_header( VipsForeignLoad *load )
|
||||||
|
{
|
||||||
|
VipsForeignLoadJpeg *jpeg = (VipsForeignLoadJpeg *) load;
|
||||||
|
VipsForeignLoadJpegFile *file = (VipsForeignLoadJpegFile *) load;
|
||||||
|
|
||||||
|
VipsStreamInput *input;
|
||||||
|
|
||||||
|
if( !(input = vips_stream_input_new_from_filename( file->filename )) )
|
||||||
|
return( -1 );
|
||||||
|
if( vips__jpeg_read_stream( input, load->out,
|
||||||
|
TRUE, jpeg->shrink, load->fail, jpeg->autorotate ) ) {
|
||||||
|
VIPS_UNREF( input );
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
VIPS_UNREF( input );
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
vips_foreign_load_jpeg_file_load( VipsForeignLoad *load )
|
||||||
|
{
|
||||||
|
VipsForeignLoadJpeg *jpeg = (VipsForeignLoadJpeg *) load;
|
||||||
|
VipsForeignLoadJpegFile *file = (VipsForeignLoadJpegFile *) load;
|
||||||
|
|
||||||
|
VipsStreamInput *input;
|
||||||
|
|
||||||
|
if( !(input = vips_stream_input_new_from_filename( file->filename )) )
|
||||||
|
return( -1 );
|
||||||
|
if( vips__jpeg_read_stream( input, load->real,
|
||||||
|
FALSE, jpeg->shrink, load->fail, jpeg->autorotate ) ) {
|
||||||
|
VIPS_UNREF( input );
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
VIPS_UNREF( input );
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
vips_foreign_load_jpeg_file_class_init( VipsForeignLoadJpegFileClass *class )
|
||||||
|
{
|
||||||
|
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||||
|
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||||
|
VipsForeignClass *foreign_class = (VipsForeignClass *) class;
|
||||||
|
VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class;
|
||||||
|
|
||||||
|
gobject_class->set_property = vips_object_set_property;
|
||||||
|
gobject_class->get_property = vips_object_get_property;
|
||||||
|
|
||||||
|
object_class->nickname = "jpegload";
|
||||||
|
object_class->description = _( "load jpeg from file" );
|
||||||
|
|
||||||
|
foreign_class->suffs = vips__jpeg_suffs;
|
||||||
|
|
||||||
|
/* We are fast at is_a(), so high priority.
|
||||||
|
*/
|
||||||
|
foreign_class->priority = 50;
|
||||||
|
|
||||||
|
load_class->is_a = vips_foreign_load_jpeg_file_is_a;
|
||||||
|
load_class->header = vips_foreign_load_jpeg_file_header;
|
||||||
|
load_class->load = vips_foreign_load_jpeg_file_load;
|
||||||
|
|
||||||
|
VIPS_ARG_STRING( class, "filename", 1,
|
||||||
|
_( "Filename" ),
|
||||||
|
_( "Filename to load from" ),
|
||||||
|
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||||
|
G_STRUCT_OFFSET( VipsForeignLoadJpegFile, filename ),
|
||||||
|
NULL );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
vips_foreign_load_jpeg_file_init( VipsForeignLoadJpegFile *file )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct _VipsForeignLoadJpegBuffer {
|
||||||
|
VipsForeignLoadJpeg parent_object;
|
||||||
|
|
||||||
|
VipsBlob *blob;
|
||||||
|
|
||||||
|
} VipsForeignLoadJpegBuffer;
|
||||||
|
|
||||||
|
typedef VipsForeignLoadJpegClass VipsForeignLoadJpegBufferClass;
|
||||||
|
|
||||||
|
G_DEFINE_TYPE( VipsForeignLoadJpegBuffer, vips_foreign_load_jpeg_buffer,
|
||||||
|
vips_foreign_load_jpeg_get_type() );
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
vips_foreign_load_jpeg_buffer_is_a( const void *buf, size_t len )
|
||||||
|
{
|
||||||
|
VipsStreamInput *input;
|
||||||
|
gboolean result;
|
||||||
|
|
||||||
|
if( !(input = vips_stream_input_new_from_memory( buf, len )) )
|
||||||
|
return( FALSE );
|
||||||
|
result = vips__isjpeg_stream( input );
|
||||||
|
VIPS_UNREF( input );
|
||||||
|
|
||||||
|
return( result );
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
vips_foreign_load_jpeg_buffer_header( VipsForeignLoad *load )
|
||||||
|
{
|
||||||
|
VipsForeignLoadJpeg *jpeg = (VipsForeignLoadJpeg *) load;
|
||||||
|
VipsForeignLoadJpegBuffer *buffer = (VipsForeignLoadJpegBuffer *) load;
|
||||||
|
|
||||||
|
VipsStreamInput *input;
|
||||||
|
|
||||||
|
if( !(input = vips_stream_input_new_from_blob( buffer->blob )) )
|
||||||
|
return( -1 );
|
||||||
|
if( vips__jpeg_read_stream( input, load->out,
|
||||||
|
TRUE, jpeg->shrink, load->fail, jpeg->autorotate ) ) {
|
||||||
|
VIPS_UNREF( input );
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
VIPS_UNREF( input );
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
vips_foreign_load_jpeg_buffer_load( VipsForeignLoad *load )
|
||||||
|
{
|
||||||
|
VipsForeignLoadJpeg *jpeg = (VipsForeignLoadJpeg *) load;
|
||||||
|
VipsForeignLoadJpegBuffer *buffer = (VipsForeignLoadJpegBuffer *) load;
|
||||||
|
|
||||||
|
VipsStreamInput *input;
|
||||||
|
|
||||||
|
if( !(input = vips_stream_input_new_from_blob( buffer->blob )) )
|
||||||
|
return( -1 );
|
||||||
|
if( vips__jpeg_read_stream( input, load->real,
|
||||||
|
FALSE, jpeg->shrink, load->fail, jpeg->autorotate ) ) {
|
||||||
|
VIPS_UNREF( input );
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
VIPS_UNREF( input );
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
vips_foreign_load_jpeg_buffer_class_init(
|
||||||
|
VipsForeignLoadJpegBufferClass *class )
|
||||||
|
{
|
||||||
|
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||||
|
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||||
|
VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class;
|
||||||
|
|
||||||
|
gobject_class->set_property = vips_object_set_property;
|
||||||
|
gobject_class->get_property = vips_object_get_property;
|
||||||
|
|
||||||
|
object_class->nickname = "jpegload_buffer";
|
||||||
|
object_class->description = _( "load jpeg from buffer" );
|
||||||
|
|
||||||
|
load_class->is_a_buffer = vips_foreign_load_jpeg_buffer_is_a;
|
||||||
|
load_class->header = vips_foreign_load_jpeg_buffer_header;
|
||||||
|
load_class->load = vips_foreign_load_jpeg_buffer_load;
|
||||||
|
|
||||||
|
VIPS_ARG_BOXED( class, "buffer", 1,
|
||||||
|
_( "Buffer" ),
|
||||||
|
_( "Buffer to load from" ),
|
||||||
|
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||||
|
G_STRUCT_OFFSET( VipsForeignLoadJpegBuffer, blob ),
|
||||||
|
VIPS_TYPE_BLOB );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
vips_foreign_load_jpeg_buffer_init( VipsForeignLoadJpegBuffer *buffer )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
#endif /*HAVE_JPEG*/
|
#endif /*HAVE_JPEG*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -185,13 +185,6 @@ int vips__jpeg_write_buffer( VipsImage *in,
|
|||||||
gboolean overshoot_deringing, gboolean optimize_scans,
|
gboolean overshoot_deringing, gboolean optimize_scans,
|
||||||
int quant_table );
|
int quant_table );
|
||||||
|
|
||||||
int vips__isjpeg_buffer( const void *buf, size_t len );
|
|
||||||
int vips__isjpeg( const char *filename );
|
|
||||||
int vips__jpeg_read_file( const char *name, VipsImage *out,
|
|
||||||
gboolean header_only, int shrink, gboolean fail, gboolean autorotate );
|
|
||||||
int vips__jpeg_read_buffer( const void *buf, size_t len, VipsImage *out,
|
|
||||||
gboolean header_only, int shrink, int fail, gboolean autorotate );
|
|
||||||
|
|
||||||
int vips__jpeg_read_stream( VipsStreamInput *input, VipsImage *out,
|
int vips__jpeg_read_stream( VipsStreamInput *input, VipsImage *out,
|
||||||
gboolean header_only, int shrink, int fail, gboolean autorotate );
|
gboolean header_only, int shrink, int fail, gboolean autorotate );
|
||||||
int vips__isjpeg_stream( VipsStreamInput *input );
|
int vips__isjpeg_stream( VipsStreamInput *input );
|
||||||
|
@ -169,7 +169,8 @@ GType vips_stream_input_get_type( void );
|
|||||||
VipsStreamInput *vips_stream_input_new_from_descriptor( int descriptor );
|
VipsStreamInput *vips_stream_input_new_from_descriptor( int descriptor );
|
||||||
VipsStreamInput *vips_stream_input_new_from_filename( const char *filename );
|
VipsStreamInput *vips_stream_input_new_from_filename( const char *filename );
|
||||||
VipsStreamInput *vips_stream_input_new_from_blob( VipsBlob *blob );
|
VipsStreamInput *vips_stream_input_new_from_blob( VipsBlob *blob );
|
||||||
VipsStreamInput *vips_stream_input_new_from_memory( void *data, size_t size );
|
VipsStreamInput *vips_stream_input_new_from_memory( const void *data,
|
||||||
|
size_t size );
|
||||||
|
|
||||||
ssize_t vips_stream_input_read( VipsStreamInput *input,
|
ssize_t vips_stream_input_read( VipsStreamInput *input,
|
||||||
unsigned char *buffer, size_t length );
|
unsigned char *buffer, size_t length );
|
||||||
@ -217,8 +218,8 @@ typedef struct _VipsStreamOutputClass {
|
|||||||
|
|
||||||
GType vips_stream_output_get_type( void );
|
GType vips_stream_output_get_type( void );
|
||||||
|
|
||||||
VipsStreamOutput *vips_stream_output_new_to_descriptor( int descriptor );
|
VipsStreamOutput *vips_stream_output_new_from_descriptor( int descriptor );
|
||||||
VipsStreamOutput *vips_stream_output_new_to_filename( const char *filename );
|
VipsStreamOutput *vips_stream_output_new_from_filename( const char *filename );
|
||||||
int vips_stream_output_write( VipsStreamOutput *stream,
|
int vips_stream_output_write( VipsStreamOutput *stream,
|
||||||
const unsigned char *buffer, size_t buffer_size );
|
const unsigned char *buffer, size_t buffer_size );
|
||||||
|
|
||||||
|
@ -253,7 +253,7 @@ vips_stream_input_read_real( VipsStreamInput *input,
|
|||||||
if( available <= 0 )
|
if( available <= 0 )
|
||||||
return( 0 );
|
return( 0 );
|
||||||
|
|
||||||
memcpy( buffer, area->data, available );
|
memcpy( buffer, area->data + input->read_position, available );
|
||||||
|
|
||||||
return( available );
|
return( available );
|
||||||
}
|
}
|
||||||
@ -448,7 +448,7 @@ vips_stream_input_new_from_blob( VipsBlob *blob )
|
|||||||
* Returns: a new #VipsStream
|
* Returns: a new #VipsStream
|
||||||
*/
|
*/
|
||||||
VipsStreamInput *
|
VipsStreamInput *
|
||||||
vips_stream_input_new_from_memory( void *data, size_t size )
|
vips_stream_input_new_from_memory( const void *data, size_t size )
|
||||||
{
|
{
|
||||||
VipsStreamInput *stream;
|
VipsStreamInput *stream;
|
||||||
VipsBlob *blob;
|
VipsBlob *blob;
|
||||||
|
@ -83,7 +83,6 @@ class TestColour:
|
|||||||
|
|
||||||
assert_almost_equal_objects(before, after, threshold=10)
|
assert_almost_equal_objects(before, after, threshold=10)
|
||||||
|
|
||||||
|
|
||||||
# test results from Bruce Lindbloom's calculator:
|
# test results from Bruce Lindbloom's calculator:
|
||||||
# http://www.brucelindbloom.com
|
# http://www.brucelindbloom.com
|
||||||
def test_dE00(self):
|
def test_dE00(self):
|
||||||
|
Loading…
Reference in New Issue
Block a user