split vips_new_*() modes up
New modes and properties mean we can use _build() for all the vipsimage init stuff now.
This commit is contained in:
parent
17c5ab4383
commit
7257c5426a
|
@ -290,7 +290,7 @@ typedef struct _VipsImageClass {
|
||||||
/* An image has been modified in some way and downstream caches all
|
/* An image has been modified in some way and downstream caches all
|
||||||
* need dropping.
|
* need dropping.
|
||||||
*/
|
*/
|
||||||
int (*invalidate)( VipsImage *image );
|
void (*invalidate)( VipsImage *image );
|
||||||
|
|
||||||
} VipsImageClass;
|
} VipsImageClass;
|
||||||
|
|
||||||
|
@ -348,11 +348,17 @@ int vips_image_get_yoffset( VipsImage *image );
|
||||||
size_t vips_image_size( VipsImage *image );
|
size_t vips_image_size( VipsImage *image );
|
||||||
|
|
||||||
void vips_image_written( VipsImage *image );
|
void vips_image_written( VipsImage *image );
|
||||||
|
void vips_image_invalidate_all( VipsImage *image );
|
||||||
void vips_image_preeval( VipsImage *image );
|
void vips_image_preeval( VipsImage *image );
|
||||||
void vips_image_eval( VipsImage *image, int w, int h );
|
void vips_image_eval( VipsImage *image, int w, int h );
|
||||||
void vips_image_posteval( VipsImage *image );
|
void vips_image_posteval( VipsImage *image );
|
||||||
|
|
||||||
VipsImage *vips_image_open( const char *filename, const char *mode );
|
VipsImage *vips_image_new( const char *mode );
|
||||||
|
VipsImage *vips_image_new_from_file( const char *filename, const char *mode );
|
||||||
|
VipsImage *vips_image_new_from_file_raw( const char *filename,
|
||||||
|
int xsize, int ysize, int bands, int offset );
|
||||||
|
VipsImage *vips_image_new_from_memory( void *buffer,
|
||||||
|
int xsize, int ysize, int bands, VipsBandFormat bandfmt );
|
||||||
|
|
||||||
gboolean vips_image_isMSBfirst( VipsImage *image );
|
gboolean vips_image_isMSBfirst( VipsImage *image );
|
||||||
gboolean vips_image_isfile( VipsImage *image );
|
gboolean vips_image_isfile( VipsImage *image );
|
||||||
|
|
|
@ -80,7 +80,7 @@ typedef int (*im__fftproc_fn)( VipsImage *, VipsImage *, VipsImage * );
|
||||||
/* iofuncs
|
/* iofuncs
|
||||||
*/
|
*/
|
||||||
int vips_open_input( VipsImage *image );
|
int vips_open_input( VipsImage *image );
|
||||||
int vips_open_input_rw( VipsImage *image );
|
int vips_image_open_input( VipsImage *image );
|
||||||
|
|
||||||
int im_mapfile( VipsImage * );
|
int im_mapfile( VipsImage * );
|
||||||
int im_mapfilerw( VipsImage * );
|
int im_mapfilerw( VipsImage * );
|
||||||
|
|
|
@ -96,7 +96,7 @@ void im_region_copy( REGION *reg, REGION *dest, Rect *r, int x, int y );
|
||||||
#define IM_REGION_N_ELEMENTS(R) \
|
#define IM_REGION_N_ELEMENTS(R) \
|
||||||
((size_t)((R)->valid.width * (R)->im->Bands))
|
((size_t)((R)->valid.width * (R)->im->Bands))
|
||||||
#define IM_REGION_SIZEOF_LINE(R) \
|
#define IM_REGION_SIZEOF_LINE(R) \
|
||||||
((size_t)((R)->valid.width * IM_IMAGE_SIZEOF_PEL((R)->im)))
|
((size_t)((R)->valid.width * VIPS_IMAGE_SIZEOF_PEL((R)->im)))
|
||||||
|
|
||||||
/* If DEBUG is defined, add bounds checking.
|
/* If DEBUG is defined, add bounds checking.
|
||||||
*/
|
*/
|
||||||
|
@ -104,7 +104,7 @@ void im_region_copy( REGION *reg, REGION *dest, Rect *r, int x, int y );
|
||||||
#define IM_REGION_ADDR(R,X,Y) \
|
#define IM_REGION_ADDR(R,X,Y) \
|
||||||
( (im_rect_includespoint( &(R)->valid, (X), (Y) ))? \
|
( (im_rect_includespoint( &(R)->valid, (X), (Y) ))? \
|
||||||
((R)->data + ((Y) - (R)->valid.top) * IM_REGION_LSKIP(R) + \
|
((R)->data + ((Y) - (R)->valid.top) * IM_REGION_LSKIP(R) + \
|
||||||
((X) - (R)->valid.left) * IM_IMAGE_SIZEOF_PEL((R)->im)): \
|
((X) - (R)->valid.left) * VIPS_IMAGE_SIZEOF_PEL((R)->im)): \
|
||||||
(fprintf( stderr, \
|
(fprintf( stderr, \
|
||||||
"IM_REGION_ADDR: point out of bounds, " \
|
"IM_REGION_ADDR: point out of bounds, " \
|
||||||
"file \"%s\", line %d\n" \
|
"file \"%s\", line %d\n" \
|
||||||
|
@ -122,7 +122,7 @@ void im_region_copy( REGION *reg, REGION *dest, Rect *r, int x, int y );
|
||||||
#define IM_REGION_ADDR(R,X,Y) \
|
#define IM_REGION_ADDR(R,X,Y) \
|
||||||
((R)->data + \
|
((R)->data + \
|
||||||
((Y)-(R)->valid.top) * IM_REGION_LSKIP(R) + \
|
((Y)-(R)->valid.top) * IM_REGION_LSKIP(R) + \
|
||||||
((X)-(R)->valid.left) * IM_IMAGE_SIZEOF_PEL((R)->im))
|
((X)-(R)->valid.left) * VIPS_IMAGE_SIZEOF_PEL((R)->im))
|
||||||
#endif /*DEBUG*/
|
#endif /*DEBUG*/
|
||||||
|
|
||||||
#define IM_REGION_ADDR_TOPLEFT(R) ( (R)->data )
|
#define IM_REGION_ADDR_TOPLEFT(R) ( (R)->data )
|
||||||
|
|
|
@ -15,9 +15,7 @@ libiofuncs_la_SOURCES = \
|
||||||
im_demand_hint.c \
|
im_demand_hint.c \
|
||||||
im_generate.c \
|
im_generate.c \
|
||||||
im_histlin.c \
|
im_histlin.c \
|
||||||
im_image.c \
|
|
||||||
im_mapfile.c \
|
im_mapfile.c \
|
||||||
im_partial.c \
|
|
||||||
im_prepare.c \
|
im_prepare.c \
|
||||||
im_setbuf.c \
|
im_setbuf.c \
|
||||||
im_setupout.c \
|
im_setupout.c \
|
||||||
|
|
|
@ -113,7 +113,7 @@ input_image_init( im_object *obj, char *str )
|
||||||
{
|
{
|
||||||
IMAGE **im = (IMAGE **) obj;
|
IMAGE **im = (IMAGE **) obj;
|
||||||
|
|
||||||
return( !(*im = vips_image_open( str, "rd" )) );
|
return( !(*im = vips_image_new_from_file( str, "rd" )) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Input image type.
|
/* Input image type.
|
||||||
|
@ -133,7 +133,7 @@ output_image_init( im_object *obj, char *str )
|
||||||
{
|
{
|
||||||
IMAGE **im = (IMAGE **) obj;
|
IMAGE **im = (IMAGE **) obj;
|
||||||
|
|
||||||
return( !(*im = vips_image_open( str, "w" )) );
|
return( !(*im = vips_image_new_from_file( str, "w" )) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Output image type.
|
/* Output image type.
|
||||||
|
@ -153,7 +153,7 @@ rw_image_init( im_object *obj, char *str )
|
||||||
{
|
{
|
||||||
IMAGE **im = (IMAGE **) obj;
|
IMAGE **im = (IMAGE **) obj;
|
||||||
|
|
||||||
return( !(*im = vips_image_open( str, "rw" )) );
|
return( !(*im = vips_image_new_from_file( str, "rw" )) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* RW image type.
|
/* RW image type.
|
||||||
|
@ -215,7 +215,8 @@ input_imagevec_init( im_object *obj, char *str )
|
||||||
iv->vec[i] = NULL;
|
iv->vec[i] = NULL;
|
||||||
|
|
||||||
for( i = 0; i < nargs; i++ )
|
for( i = 0; i < nargs; i++ )
|
||||||
if( !(iv->vec[i] = vips_image_open( strv[i], "rd" )) ) {
|
if( !(iv->vec[i] =
|
||||||
|
vips_image_new_from_file( strv[i], "rd" )) ) {
|
||||||
g_strfreev( strv );
|
g_strfreev( strv );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
|
|
@ -170,7 +170,7 @@ im_cp_descv( IMAGE *out, IMAGE *in1, ... )
|
||||||
;
|
;
|
||||||
va_end( ap );
|
va_end( ap );
|
||||||
if( i == MAX_IMAGES ) {
|
if( i == MAX_IMAGES ) {
|
||||||
im_error( "im_cp_descv",
|
vips_error( "im_cp_descv",
|
||||||
"%s", _( "too many images" ) );
|
"%s", _( "too many images" ) );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
|
|
@ -150,6 +150,19 @@ im__link_map( IMAGE *im, VSListMap2Fn fn, void *a, void *b )
|
||||||
{
|
{
|
||||||
static int serial = 0;
|
static int serial = 0;
|
||||||
|
|
||||||
|
/* Invalidate callbacks might do anything, including removing images
|
||||||
|
* or invalidating other images, so we can't trigger them from within
|
||||||
|
* the image loop. Instead we collect a list of image to invalidate
|
||||||
|
* and trigger them all in one go, checking that they are not
|
||||||
|
* invalidated.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* im__link_mapp() needs to make the list, ref all the images, call
|
||||||
|
* the callbacks, then unref and free the list.
|
||||||
|
*/
|
||||||
|
|
||||||
|
FIXME
|
||||||
|
|
||||||
serial += 1;
|
serial += 1;
|
||||||
return( im__link_mapp( im, fn, &serial, a, b ) );
|
return( im__link_mapp( im, fn, &serial, a, b ) );
|
||||||
}
|
}
|
||||||
|
@ -159,7 +172,7 @@ im__link_map( IMAGE *im, VSListMap2Fn fn, void *a, void *b )
|
||||||
static im_demand_type
|
static im_demand_type
|
||||||
find_least( im_demand_type a, im_demand_type b )
|
find_least( im_demand_type a, im_demand_type b )
|
||||||
{
|
{
|
||||||
return( (im_demand_type) IM_MIN( (int) a, (int) b ) );
|
return( (im_demand_type) VIPS_MIN( (int) a, (int) b ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -191,7 +204,7 @@ im_demand_hint_array( IMAGE *im, VipsDemandStyle hint, IMAGE **in )
|
||||||
/* How many input images are there? And how many are IM_ANY?
|
/* How many input images are there? And how many are IM_ANY?
|
||||||
*/
|
*/
|
||||||
for( i = 0, len = 0, nany = 0; in[i]; i++, len++ )
|
for( i = 0, len = 0, nany = 0; in[i]; i++, len++ )
|
||||||
if( in[i]->dhint == IM_ANY )
|
if( in[i]->dhint == VIPS_DEMAND_STYLE_ANY )
|
||||||
nany++;
|
nany++;
|
||||||
|
|
||||||
set_hint = hint;
|
set_hint = hint;
|
||||||
|
@ -206,7 +219,7 @@ im_demand_hint_array( IMAGE *im, VipsDemandStyle hint, IMAGE **in )
|
||||||
/* Special case: if all the inputs are IM_ANY, then output can
|
/* Special case: if all the inputs are IM_ANY, then output can
|
||||||
* be IM_ANY regardless of what this function wants.
|
* be IM_ANY regardless of what this function wants.
|
||||||
*/
|
*/
|
||||||
set_hint = IM_ANY;
|
set_hint = VIPS_DEMAND_STYLE_ANY;
|
||||||
else
|
else
|
||||||
/* Find the most restrictive of all the hints available to us.
|
/* Find the most restrictive of all the hints available to us.
|
||||||
*/
|
*/
|
||||||
|
@ -263,7 +276,7 @@ im_demand_hint( IMAGE *im, VipsDemandStyle hint, ... )
|
||||||
;
|
;
|
||||||
va_end( ap );
|
va_end( ap );
|
||||||
if( i == MAX_IMAGES ) {
|
if( i == MAX_IMAGES ) {
|
||||||
im_error( "im_demand_hint", "%s", _( "too many images" ) );
|
vips_error( "im_demand_hint", "%s", _( "too many images" ) );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -207,7 +207,7 @@ im_start_many( IMAGE *out, void *a, void *b )
|
||||||
|
|
||||||
/* Alocate space for region array.
|
/* Alocate space for region array.
|
||||||
*/
|
*/
|
||||||
if( !(ar = IM_ARRAY( NULL, n + 1, REGION * )) )
|
if( !(ar = VIPS_ARRAY( NULL, n + 1, REGION * )) )
|
||||||
return( NULL );
|
return( NULL );
|
||||||
|
|
||||||
/* Create a set of regions.
|
/* Create a set of regions.
|
||||||
|
@ -251,7 +251,7 @@ im_allocate_input_array( IMAGE *out, ... )
|
||||||
|
|
||||||
/* Allocate array.
|
/* Allocate array.
|
||||||
*/
|
*/
|
||||||
if( !(ar = IM_ARRAY( out, n + 1, IMAGE * )) )
|
if( !(ar = VIPS_ARRAY( out, n + 1, IMAGE * )) )
|
||||||
return( NULL );
|
return( NULL );
|
||||||
|
|
||||||
/* Fill array.
|
/* Fill array.
|
||||||
|
@ -365,13 +365,13 @@ im_generate( IMAGE *im,
|
||||||
g_assert( !im_image_sanity( im ) );
|
g_assert( !im_image_sanity( im ) );
|
||||||
|
|
||||||
if( !im->hint_set ) {
|
if( !im->hint_set ) {
|
||||||
im_error( "im_generate",
|
vips_error( "im_generate",
|
||||||
"%s", _( "im_demand_hint() not set" ) );
|
"%s", _( "im_demand_hint() not set" ) );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( im->Xsize <= 0 || im->Ysize <= 0 || im->Bands <= 0 ) {
|
if( im->Xsize <= 0 || im->Ysize <= 0 || im->Bands <= 0 ) {
|
||||||
im_error( "im_generate",
|
vips_error( "im_generate",
|
||||||
"%s", _( "bad dimensions" ) );
|
"%s", _( "bad dimensions" ) );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
@ -384,11 +384,11 @@ im_generate( IMAGE *im,
|
||||||
/* Look at output type to decide our action.
|
/* Look at output type to decide our action.
|
||||||
*/
|
*/
|
||||||
switch( im->dtype ) {
|
switch( im->dtype ) {
|
||||||
case IM_PARTIAL:
|
case VIPS_IMAGE_PARTIAL:
|
||||||
/* Output to partial image. Just attach functions and return.
|
/* Output to partial image. Just attach functions and return.
|
||||||
*/
|
*/
|
||||||
if( im->generate || im->start || im->stop ) {
|
if( im->generate || im->start || im->stop ) {
|
||||||
im_error( "im_generate",
|
vips_error( "im_generate",
|
||||||
"%s", _( "func already attached" ) );
|
"%s", _( "func already attached" ) );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
@ -405,14 +405,14 @@ im_generate( IMAGE *im,
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IM_SETBUF:
|
case VIPS_IMAGE_SETBUF:
|
||||||
case IM_SETBUF_FOREIGN:
|
case VIPS_IMAGE_SETBUF_FOREIGN:
|
||||||
case IM_MMAPINRW:
|
case VIPS_IMAGE_MMAPINRW:
|
||||||
case IM_OPENOUT:
|
case VIPS_IMAGE_OPENOUT:
|
||||||
/* Eval now .. sanity check.
|
/* Eval now .. sanity check.
|
||||||
*/
|
*/
|
||||||
if( im->generate || im->start || im->stop ) {
|
if( im->generate || im->start || im->stop ) {
|
||||||
im_error( "im_generate",
|
vips_error( "im_generate",
|
||||||
"%s", _( "func already attached" ) );
|
"%s", _( "func already attached" ) );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
@ -430,7 +430,7 @@ im_generate( IMAGE *im,
|
||||||
im->client1 = a;
|
im->client1 = a;
|
||||||
im->client2 = b;
|
im->client2 = b;
|
||||||
|
|
||||||
if( im->dtype == IM_OPENOUT )
|
if( im->dtype == VIPS_IMAGE_OPENOUT )
|
||||||
res = vips_sink_disc( im,
|
res = vips_sink_disc( im,
|
||||||
(VipsRegionWrite) write_vips, NULL );
|
(VipsRegionWrite) write_vips, NULL );
|
||||||
else
|
else
|
||||||
|
@ -446,15 +446,12 @@ im_generate( IMAGE *im,
|
||||||
default:
|
default:
|
||||||
/* Not a known output style.
|
/* Not a known output style.
|
||||||
*/
|
*/
|
||||||
im_error( "im_generate", _( "unable to output to a %s image" ),
|
vips_error( "im_generate", _( "unable to output to a %s image" ),
|
||||||
im_dtype2char( im->dtype ) );
|
im_dtype2char( im->dtype ) );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Successful write: trigger "written".
|
vips_image_written( im );
|
||||||
*/
|
|
||||||
if( im__trigger_callbacks( im->writtenfns ) )
|
|
||||||
return( -1 );
|
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,102 +0,0 @@
|
||||||
/* im_image.c ... area of memory as an image
|
|
||||||
*
|
|
||||||
* Written on: 11/7/00
|
|
||||||
* Modified on:
|
|
||||||
* 20/3/01 JC
|
|
||||||
* - oops, broken for IM_BANDFMT_UCHAR
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include <config.h>
|
|
||||||
#endif /*HAVE_CONFIG_H*/
|
|
||||||
#include <vips/intl.h>
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include <vips/vips.h>
|
|
||||||
#include <vips/internal.h>
|
|
||||||
|
|
||||||
#ifdef WITH_DMALLOC
|
|
||||||
#include <dmalloc.h>
|
|
||||||
#endif /*WITH_DMALLOC*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* im_image:
|
|
||||||
* @buffer: start of memory area
|
|
||||||
* @xsize: image width
|
|
||||||
* @ysize: image height
|
|
||||||
* @bands: image bands (or bytes per pixel)
|
|
||||||
* @bandfmt: image format
|
|
||||||
*
|
|
||||||
* This function wraps an #IMAGE around a memory buffer. VIPS does not take
|
|
||||||
* responsibility for the area of memory, it's up to you to make sure it's
|
|
||||||
* freed when the image is closed. See for example im_add_close_callback().
|
|
||||||
*
|
|
||||||
* See also: im_binfile(), im_raw2vips(), im_open().
|
|
||||||
*
|
|
||||||
* Returns: the new #IMAGE, or %NULL on error.
|
|
||||||
*/
|
|
||||||
IMAGE *
|
|
||||||
im_image( void *buffer, int xsize, int ysize, int bands, VipsBandFmt bandfmt )
|
|
||||||
{
|
|
||||||
IMAGE *im;
|
|
||||||
|
|
||||||
if( xsize <= 0 || ysize <= 0 || bands <= 0 ||
|
|
||||||
bandfmt < 0 || bandfmt > IM_BANDFMT_DPCOMPLEX ) {
|
|
||||||
im_error( "im_image", "%s", _( "bad parameters" ) );
|
|
||||||
return( NULL );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Make new output image for us.
|
|
||||||
*/
|
|
||||||
if( !(im = im_init( "untitled" )) )
|
|
||||||
return( NULL );
|
|
||||||
|
|
||||||
/* Set header fields.
|
|
||||||
*/
|
|
||||||
im->Xsize = xsize;
|
|
||||||
im->Ysize = ysize;
|
|
||||||
im->Bands = bands;
|
|
||||||
im->BandFmt = bandfmt;
|
|
||||||
im->Bbits = im_bits_of_fmt( bandfmt );
|
|
||||||
im->Coding = IM_CODING_NONE;
|
|
||||||
|
|
||||||
if( bands == 1 )
|
|
||||||
im->Type = IM_TYPE_B_W;
|
|
||||||
else if( bands == 3 )
|
|
||||||
im->Type = IM_TYPE_RGB;
|
|
||||||
else
|
|
||||||
im->Type = IM_TYPE_MULTIBAND;
|
|
||||||
|
|
||||||
im->data = (char *) buffer;
|
|
||||||
im->dtype = IM_SETBUF_FOREIGN;
|
|
||||||
|
|
||||||
return( im );
|
|
||||||
}
|
|
|
@ -138,17 +138,17 @@ im__mmap( int fd, int writeable, size_t length, gint64 offset )
|
||||||
|
|
||||||
if( !(hMMFile = CreateFileMapping( hFile,
|
if( !(hMMFile = CreateFileMapping( hFile,
|
||||||
NULL, flProtect, 0, 0, NULL )) ) {
|
NULL, flProtect, 0, 0, NULL )) ) {
|
||||||
im_error_system( GetLastError(), "im_mapfile",
|
vips_error_system( GetLastError(), "im_mapfile",
|
||||||
"%s", _( "unable to CreateFileMapping" ) );
|
"%s", _( "unable to CreateFileMapping" ) );
|
||||||
printf( "CreateFileMapping failed: %s\n", im_error_buffer() );
|
printf( "CreateFileMapping failed: %s\n", vips_error_buffer() );
|
||||||
return( NULL );
|
return( NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !(baseaddr = (char *)MapViewOfFile( hMMFile, dwDesiredAccess,
|
if( !(baseaddr = (char *)MapViewOfFile( hMMFile, dwDesiredAccess,
|
||||||
dwFileOffsetHigh, dwFileOffsetLow, length )) ) {
|
dwFileOffsetHigh, dwFileOffsetLow, length )) ) {
|
||||||
im_error_system( GetLastError(), "im_mapfile",
|
vips_error_system( GetLastError(), "im_mapfile",
|
||||||
"%s", _( "unable to MapViewOfFile" ) );
|
"%s", _( "unable to MapViewOfFile" ) );
|
||||||
printf( "MapViewOfFile failed: %s\n", im_error_buffer() );
|
printf( "MapViewOfFile failed: %s\n", vips_error_buffer() );
|
||||||
CloseHandle( hMMFile );
|
CloseHandle( hMMFile );
|
||||||
return( NULL );
|
return( NULL );
|
||||||
}
|
}
|
||||||
|
@ -186,9 +186,9 @@ im__mmap( int fd, int writeable, size_t length, gint64 offset )
|
||||||
|
|
||||||
baseaddr = mmap( 0, length, prot, MAP_SHARED, fd, (off_t) offset );
|
baseaddr = mmap( 0, length, prot, MAP_SHARED, fd, (off_t) offset );
|
||||||
if( baseaddr == MAP_FAILED ) {
|
if( baseaddr == MAP_FAILED ) {
|
||||||
im_error_system( errno, "im_mapfile",
|
vips_error_system( errno, "im_mapfile",
|
||||||
"%s", _( "unable to mmap" ) );
|
"%s", _( "unable to mmap" ) );
|
||||||
im_warn( "im_mapfile", _( "map failed (%s), "
|
vips_warn( "im_mapfile", _( "map failed (%s), "
|
||||||
"running very low on system resources, "
|
"running very low on system resources, "
|
||||||
"expect a crash soon" ), strerror( errno ) );
|
"expect a crash soon" ), strerror( errno ) );
|
||||||
return( NULL );
|
return( NULL );
|
||||||
|
@ -204,13 +204,13 @@ im__munmap( void *start, size_t length )
|
||||||
{
|
{
|
||||||
#ifdef OS_WIN32
|
#ifdef OS_WIN32
|
||||||
if( !UnmapViewOfFile( start ) ) {
|
if( !UnmapViewOfFile( start ) ) {
|
||||||
im_error_system( GetLastError(), "im_mapfile",
|
vips_error_system( GetLastError(), "im_mapfile",
|
||||||
"%s", _( "unable to UnmapViewOfFile" ) );
|
"%s", _( "unable to UnmapViewOfFile" ) );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
#else /*!OS_WIN32*/
|
#else /*!OS_WIN32*/
|
||||||
if( munmap( start, length ) < 0 ) {
|
if( munmap( start, length ) < 0 ) {
|
||||||
im_error_system( errno, "im_mapfile",
|
vips_error_system( errno, "im_mapfile",
|
||||||
"%s", _( "unable to munmap file" ) );
|
"%s", _( "unable to munmap file" ) );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
@ -232,18 +232,18 @@ im_mapfile( IMAGE *im )
|
||||||
*/
|
*/
|
||||||
g_assert( im->file_length > 0 );
|
g_assert( im->file_length > 0 );
|
||||||
if( im->file_length < 64 ) {
|
if( im->file_length < 64 ) {
|
||||||
im_error( "im_mapfile",
|
vips_error( "im_mapfile",
|
||||||
"%s", _( "file is less than 64 bytes" ) );
|
"%s", _( "file is less than 64 bytes" ) );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
if( fstat( im->fd, &st ) == -1 ) {
|
if( fstat( im->fd, &st ) == -1 ) {
|
||||||
im_error( "im_mapfile",
|
vips_error( "im_mapfile",
|
||||||
"%s", _( "unable to get file status" ) );
|
"%s", _( "unable to get file status" ) );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
m = (mode_t) st.st_mode;
|
m = (mode_t) st.st_mode;
|
||||||
if( !S_ISREG( m ) ) {
|
if( !S_ISREG( m ) ) {
|
||||||
im_error( "im_mapfile",
|
vips_error( "im_mapfile",
|
||||||
"%s", _( "not a regular file" ) );
|
"%s", _( "not a regular file" ) );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
@ -271,13 +271,13 @@ im_mapfilerw( IMAGE *im )
|
||||||
*/
|
*/
|
||||||
g_assert( im->file_length > 0 );
|
g_assert( im->file_length > 0 );
|
||||||
if( fstat( im->fd, &st ) == -1 ) {
|
if( fstat( im->fd, &st ) == -1 ) {
|
||||||
im_error( "im_mapfilerw",
|
vips_error( "im_mapfilerw",
|
||||||
"%s", _( "unable to get file status" ) );
|
"%s", _( "unable to get file status" ) );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
m = (mode_t) st.st_mode;
|
m = (mode_t) st.st_mode;
|
||||||
if( im->file_length < 64 || !S_ISREG( m ) ) {
|
if( im->file_length < 64 || !S_ISREG( m ) ) {
|
||||||
im_error( "im_mapfile",
|
vips_error( "im_mapfile",
|
||||||
"%s", _( "unable to read data" ) );
|
"%s", _( "unable to read data" ) );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
@ -305,19 +305,19 @@ im_remapfilerw( IMAGE *image )
|
||||||
|
|
||||||
if( !(hMMFile = CreateFileMapping( hFile,
|
if( !(hMMFile = CreateFileMapping( hFile,
|
||||||
NULL, PAGE_READWRITE, 0, 0, NULL )) ) {
|
NULL, PAGE_READWRITE, 0, 0, NULL )) ) {
|
||||||
im_error_system( GetLastError(), "im_mapfile",
|
vips_error_system( GetLastError(), "im_mapfile",
|
||||||
"%s", _( "unable to CreateFileMapping" ) );
|
"%s", _( "unable to CreateFileMapping" ) );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !UnmapViewOfFile( image->baseaddr ) ) {
|
if( !UnmapViewOfFile( image->baseaddr ) ) {
|
||||||
im_error_system( GetLastError(), "im_mapfile",
|
vips_error_system( GetLastError(), "im_mapfile",
|
||||||
"%s", _( "unable to UnmapViewOfFile" ) );
|
"%s", _( "unable to UnmapViewOfFile" ) );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
if( !(baseaddr = (char *)MapViewOfFileEx( hMMFile, FILE_MAP_WRITE,
|
if( !(baseaddr = (char *)MapViewOfFileEx( hMMFile, FILE_MAP_WRITE,
|
||||||
0, 0, 0, image->baseaddr )) ) {
|
0, 0, 0, image->baseaddr )) ) {
|
||||||
im_error_system( GetLastError(), "im_mapfile",
|
vips_error_system( GetLastError(), "im_mapfile",
|
||||||
"%s", _( "unable to MapViewOfFile" ) );
|
"%s", _( "unable to MapViewOfFile" ) );
|
||||||
CloseHandle( hMMFile );
|
CloseHandle( hMMFile );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
@ -332,23 +332,23 @@ im_remapfilerw( IMAGE *image )
|
||||||
}
|
}
|
||||||
#else /*!OS_WIN32*/
|
#else /*!OS_WIN32*/
|
||||||
{
|
{
|
||||||
assert( image->dtype == IM_MMAPIN );
|
assert( image->dtype == VIPS_IMAGE_MMAPIN );
|
||||||
|
|
||||||
baseaddr = mmap( image->baseaddr, image->length,
|
baseaddr = mmap( image->baseaddr, image->length,
|
||||||
PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED,
|
PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED,
|
||||||
image->fd, 0 );
|
image->fd, 0 );
|
||||||
if( baseaddr == (void *)-1 ) {
|
if( baseaddr == (void *)-1 ) {
|
||||||
im_error( "im_mapfile", _( "unable to mmap: \"%s\" - %s" ),
|
vips_error( "im_mapfile", _( "unable to mmap: \"%s\" - %s" ),
|
||||||
image->filename, strerror( errno ) );
|
image->filename, strerror( errno ) );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /*OS_WIN32*/
|
#endif /*OS_WIN32*/
|
||||||
|
|
||||||
image->dtype = IM_MMAPINRW;
|
image->dtype = VIPS_IMAGE_MMAPINRW;
|
||||||
|
|
||||||
if( baseaddr != image->baseaddr ) {
|
if( baseaddr != image->baseaddr ) {
|
||||||
im_error( "im_mapfile", _( "unable to mmap \"%s\" to same "
|
vips_error( "im_mapfile", _( "unable to mmap \"%s\" to same "
|
||||||
"address" ), image->filename );
|
"address" ), image->filename );
|
||||||
image->baseaddr = baseaddr;
|
image->baseaddr = baseaddr;
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
|
@ -1,65 +0,0 @@
|
||||||
/* @(#) im_partial: initialise a partial IMAGE. Just set im->dtype.
|
|
||||||
* @(#)
|
|
||||||
* @(#) IMAGE *
|
|
||||||
* @(#) im_partial( file_name )
|
|
||||||
* @(#) char *file_name;
|
|
||||||
* @(#)
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include <config.h>
|
|
||||||
#endif /*HAVE_CONFIG_H*/
|
|
||||||
#include <vips/intl.h>
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include <vips/vips.h>
|
|
||||||
#include <vips/internal.h>
|
|
||||||
|
|
||||||
#ifdef WITH_DMALLOC
|
|
||||||
#include <dmalloc.h>
|
|
||||||
#endif /*WITH_DMALLOC*/
|
|
||||||
|
|
||||||
IMAGE *
|
|
||||||
im_partial( const char *filename )
|
|
||||||
{
|
|
||||||
IMAGE *im = im_init( filename );
|
|
||||||
|
|
||||||
if( !im )
|
|
||||||
return(NULL);
|
|
||||||
im->dtype = IM_PARTIAL;
|
|
||||||
|
|
||||||
/* No need to set demand style - im_demand_hint() from application
|
|
||||||
* will do this.
|
|
||||||
*/
|
|
||||||
|
|
||||||
return( im );
|
|
||||||
}
|
|
|
@ -99,7 +99,7 @@ im__test_kill( IMAGE *im )
|
||||||
/* Has kill been set for this image? If yes, abort evaluation.
|
/* Has kill been set for this image? If yes, abort evaluation.
|
||||||
*/
|
*/
|
||||||
if( im->kill ) {
|
if( im->kill ) {
|
||||||
im_error( "im__test_kill", _( "killed for image \"%s\"" ),
|
vips_error( "im__test_kill", _( "killed for image \"%s\"" ),
|
||||||
im->filename );
|
im->filename );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
@ -162,18 +162,18 @@ im_prepare( REGION *reg, Rect *r )
|
||||||
#endif /*DEBUG*/
|
#endif /*DEBUG*/
|
||||||
|
|
||||||
switch( im->dtype ) {
|
switch( im->dtype ) {
|
||||||
case IM_PARTIAL:
|
case VIPS_IMAGE_PARTIAL:
|
||||||
if( im_region_fill( reg, r,
|
if( im_region_fill( reg, r,
|
||||||
(im_region_fill_fn) fill_region, NULL ) )
|
(im_region_fill_fn) fill_region, NULL ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IM_SETBUF:
|
case VIPS_IMAGE_SETBUF:
|
||||||
case IM_SETBUF_FOREIGN:
|
case VIPS_IMAGE_SETBUF_FOREIGN:
|
||||||
case IM_MMAPIN:
|
case VIPS_IMAGE_MMAPIN:
|
||||||
case IM_MMAPINRW:
|
case VIPS_IMAGE_MMAPINRW:
|
||||||
case IM_OPENIN:
|
case VIPS_IMAGE_OPENIN:
|
||||||
/* Attach to existing buffer.
|
/* Attach to existing buffer.
|
||||||
*/
|
*/
|
||||||
if( im_region_image( reg, r ) )
|
if( im_region_image( reg, r ) )
|
||||||
|
@ -182,7 +182,7 @@ im_prepare( REGION *reg, Rect *r )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
im_error( "im_prepare", _( "unable to input from a %s image" ),
|
vips_error( "im_prepare", _( "unable to input from a %s image" ),
|
||||||
im_dtype2char( im->dtype ) );
|
im_dtype2char( im->dtype ) );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
@ -204,7 +204,7 @@ im_prepare_to_generate( REGION *reg, REGION *dest, Rect *r, int x, int y )
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
if( !im->generate ) {
|
if( !im->generate ) {
|
||||||
im_error( "im_prepare_to", "%s", _( "incomplete header" ) );
|
vips_error( "im_prepare_to", "%s", _( "incomplete header" ) );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -271,7 +271,7 @@ im_prepare_to( REGION *reg, REGION *dest, Rect *r, int x, int y )
|
||||||
if( !dest->data ||
|
if( !dest->data ||
|
||||||
dest->im->BandFmt != reg->im->BandFmt ||
|
dest->im->BandFmt != reg->im->BandFmt ||
|
||||||
dest->im->Bands != reg->im->Bands ) {
|
dest->im->Bands != reg->im->Bands ) {
|
||||||
im_error( "im_prepare_to",
|
vips_error( "im_prepare_to",
|
||||||
"%s", _( "inappropriate region type" ) );
|
"%s", _( "inappropriate region type" ) );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
@ -297,7 +297,7 @@ im_prepare_to( REGION *reg, REGION *dest, Rect *r, int x, int y )
|
||||||
/* Test that dest->valid is large enough.
|
/* Test that dest->valid is large enough.
|
||||||
*/
|
*/
|
||||||
if( !im_rect_includesrect( &dest->valid, &wanted ) ) {
|
if( !im_rect_includesrect( &dest->valid, &wanted ) ) {
|
||||||
im_error( "im_prepare_to", "%s", _( "dest too small" ) );
|
vips_error( "im_prepare_to", "%s", _( "dest too small" ) );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -314,7 +314,7 @@ im_prepare_to( REGION *reg, REGION *dest, Rect *r, int x, int y )
|
||||||
y = clipped2.top;
|
y = clipped2.top;
|
||||||
|
|
||||||
if( im_rect_isempty( &final ) ) {
|
if( im_rect_isempty( &final ) ) {
|
||||||
im_error( "im_prepare_to",
|
vips_error( "im_prepare_to",
|
||||||
"%s", _( "valid clipped to nothing" ) );
|
"%s", _( "valid clipped to nothing" ) );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
@ -327,8 +327,8 @@ im_prepare_to( REGION *reg, REGION *dest, Rect *r, int x, int y )
|
||||||
/* Input or output image type?
|
/* Input or output image type?
|
||||||
*/
|
*/
|
||||||
switch( im->dtype ) {
|
switch( im->dtype ) {
|
||||||
case IM_OPENOUT:
|
case VIPS_IMAGE_OPENOUT:
|
||||||
case IM_PARTIAL:
|
case VIPS_IMAGE_PARTIAL:
|
||||||
/* We are generating with a sequence.
|
/* We are generating with a sequence.
|
||||||
*/
|
*/
|
||||||
if( im_prepare_to_generate( reg, dest, &final, x, y ) )
|
if( im_prepare_to_generate( reg, dest, &final, x, y ) )
|
||||||
|
@ -336,9 +336,9 @@ im_prepare_to( REGION *reg, REGION *dest, Rect *r, int x, int y )
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IM_MMAPIN:
|
case VIPS_IMAGE_MMAPIN:
|
||||||
case IM_MMAPINRW:
|
case VIPS_IMAGE_MMAPINRW:
|
||||||
case IM_OPENIN:
|
case VIPS_IMAGE_OPENIN:
|
||||||
/* Attach to existing buffer and copy to dest.
|
/* Attach to existing buffer and copy to dest.
|
||||||
*/
|
*/
|
||||||
if( im_region_image( reg, &final ) )
|
if( im_region_image( reg, &final ) )
|
||||||
|
@ -347,8 +347,8 @@ im_prepare_to( REGION *reg, REGION *dest, Rect *r, int x, int y )
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IM_SETBUF:
|
case VIPS_IMAGE_SETBUF:
|
||||||
case IM_SETBUF_FOREIGN:
|
case VIPS_IMAGE_SETBUF_FOREIGN:
|
||||||
/* Could be either input or output. If there is a generate
|
/* Could be either input or output. If there is a generate
|
||||||
* function, we are outputting.
|
* function, we are outputting.
|
||||||
*/
|
*/
|
||||||
|
@ -365,7 +365,7 @@ im_prepare_to( REGION *reg, REGION *dest, Rect *r, int x, int y )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
im_error( "im_prepare_to", _( "unable to input from a "
|
vips_error( "im_prepare_to", _( "unable to input from a "
|
||||||
"%s image" ), im_dtype2char( im->dtype ) );
|
"%s image" ), im_dtype2char( im->dtype ) );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
@ -390,87 +390,3 @@ im_prepare_many( REGION **reg, Rect *r )
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *
|
|
||||||
im_invalidate_region( REGION *reg )
|
|
||||||
{
|
|
||||||
reg->invalid = TRUE;
|
|
||||||
|
|
||||||
return( NULL );
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *
|
|
||||||
im_invalidate_image( IMAGE *im, GSList **to_be_invalidated )
|
|
||||||
{
|
|
||||||
g_mutex_lock( im->sslock );
|
|
||||||
(void) im_slist_map2( im->regions,
|
|
||||||
(VSListMap2Fn) im_invalidate_region, NULL, NULL );
|
|
||||||
g_mutex_unlock( im->sslock );
|
|
||||||
|
|
||||||
*to_be_invalidated = g_slist_prepend( *to_be_invalidated, im );
|
|
||||||
|
|
||||||
return( NULL );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Trigger a callbacks on a list of images, where the callbacks might create
|
|
||||||
* or destroy the images.
|
|
||||||
*
|
|
||||||
* We make a set of temp regions to hold the images open, but when we switch
|
|
||||||
* to VipsObject we should incr/decr ref count.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
im_invalidate_trigger( GSList *images )
|
|
||||||
{
|
|
||||||
GSList *regions;
|
|
||||||
GSList *p;
|
|
||||||
|
|
||||||
regions = NULL;
|
|
||||||
for( p = images; p; p = p->next ) {
|
|
||||||
IMAGE *im = (IMAGE *) p->data;
|
|
||||||
|
|
||||||
regions = g_slist_prepend( regions, im_region_create( im ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
for( p = images; p; p = p->next ) {
|
|
||||||
IMAGE *im = (IMAGE *) p->data;
|
|
||||||
|
|
||||||
(void) im__trigger_callbacks( im->invalidatefns );
|
|
||||||
}
|
|
||||||
|
|
||||||
for( p = regions; p; p = p->next ) {
|
|
||||||
REGION *r = (REGION *) p->data;
|
|
||||||
|
|
||||||
im_region_free( r );
|
|
||||||
}
|
|
||||||
|
|
||||||
g_slist_free( regions );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* im_invalidate:
|
|
||||||
* @im: #IMAGE to invalidate
|
|
||||||
*
|
|
||||||
* Invalidate all pixel caches on an #IMAGE and any derived images. The
|
|
||||||
* "invalidate" callback is triggered for all invalidated images.
|
|
||||||
*
|
|
||||||
* See also: im_add_invalidate_callback().
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
im_invalidate( IMAGE *im )
|
|
||||||
{
|
|
||||||
GSList *to_be_invalidated;
|
|
||||||
|
|
||||||
/* Invalidate callbacks might do anything, including removing images
|
|
||||||
* or invalidating other images, so we can't trigger them from within
|
|
||||||
* the image loop. Instead we collect a list of image to invalidate
|
|
||||||
* and trigger them all in one go, checking that they are not
|
|
||||||
* invalidated.
|
|
||||||
*/
|
|
||||||
to_be_invalidated = NULL;
|
|
||||||
(void) im__link_map( im,
|
|
||||||
(VSListMap2Fn) im_invalidate_image, &to_be_invalidated, NULL );
|
|
||||||
|
|
||||||
im_invalidate_trigger( to_be_invalidated );
|
|
||||||
|
|
||||||
g_slist_free( to_be_invalidated );
|
|
||||||
}
|
|
||||||
|
|
|
@ -296,6 +296,8 @@ enum {
|
||||||
PROP_KILL,
|
PROP_KILL,
|
||||||
PROP_MODE,
|
PROP_MODE,
|
||||||
PROP_DEMAND,
|
PROP_DEMAND,
|
||||||
|
PROP_SIZEOF_HEADER,
|
||||||
|
PROP_FOREIGN_BUFFER,
|
||||||
PROP_LAST
|
PROP_LAST
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -306,6 +308,7 @@ enum {
|
||||||
SIG_EVAL,
|
SIG_EVAL,
|
||||||
SIG_POSTEVAL,
|
SIG_POSTEVAL,
|
||||||
SIG_WRITTEN,
|
SIG_WRITTEN,
|
||||||
|
SIG_INVALIDATE,
|
||||||
SIG_LAST
|
SIG_LAST
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -597,7 +600,7 @@ lazy_real_image( Lazy *lazy )
|
||||||
/* Otherwise, fall back to a "p".
|
/* Otherwise, fall back to a "p".
|
||||||
*/
|
*/
|
||||||
if( !real &&
|
if( !real &&
|
||||||
!(real = vips_image_open( lazy->filename, "p" )) )
|
!(real = vips_image_new( "p" )) )
|
||||||
return( NULL );
|
return( NULL );
|
||||||
|
|
||||||
return( real );
|
return( real );
|
||||||
|
@ -831,7 +834,7 @@ vips_image_build( VipsObject *object )
|
||||||
else {
|
else {
|
||||||
VipsImage *x;
|
VipsImage *x;
|
||||||
|
|
||||||
if( !(x = vips_image_open( filename, "p" )) )
|
if( !(x = vips_image_new( "p" )) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
vips_object_local( image, x );
|
vips_object_local( image, x );
|
||||||
if( vips_image_open_input( x ) )
|
if( vips_image_open_input( x ) )
|
||||||
|
@ -871,6 +874,63 @@ vips_image_build( VipsObject *object )
|
||||||
image->dtype = VIPS_IMAGE_PARTIAL;
|
image->dtype = VIPS_IMAGE_PARTIAL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'a':
|
||||||
|
/* Check parameters.
|
||||||
|
*/
|
||||||
|
if( image->sizeof_header < 0 ) {
|
||||||
|
vips_error( "vips_image_open_raw",
|
||||||
|
"%s", _( "bad parameters" ) );
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( (image->fd = im__open_image_file( filename )) == -1 )
|
||||||
|
return( -1 );
|
||||||
|
image->dtype = VIPS_IMAGE_OPENIN;
|
||||||
|
image->dhint = VIPS_DEMAND_STYLE_THINSTRIP;
|
||||||
|
|
||||||
|
if( image->Bands == 1 )
|
||||||
|
image->Type = VIPS_INTERPRETATION_B_W;
|
||||||
|
else if( image->Bands == 3 )
|
||||||
|
image->Type = VIPS_INTERPRETATION_RGB;
|
||||||
|
else
|
||||||
|
image->Type = VIPS_INTERPRETATION_MULTIBAND;
|
||||||
|
|
||||||
|
/* Read the real file length and check against what we think
|
||||||
|
* the size should be.
|
||||||
|
*/
|
||||||
|
if( (image->file_length = im_file_length( image->fd )) == -1 )
|
||||||
|
return( -1 );
|
||||||
|
|
||||||
|
/* Very common, so a special message.
|
||||||
|
*/
|
||||||
|
if( image->file_length < vips_image_size( image ) ) {
|
||||||
|
vips_error( "VipsImage",
|
||||||
|
_( "unable to open %s: file too short" ),
|
||||||
|
image->filename );
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Just weird. Only print a warning for this, since we should
|
||||||
|
* still be able to process it without coredumps.
|
||||||
|
*/
|
||||||
|
if( image->file_length > vips_image_size( image ) )
|
||||||
|
vips_warn( "VipsImage",
|
||||||
|
_( "%s is longer than expected" ),
|
||||||
|
image->filename );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'm':
|
||||||
|
if( image->Bands == 1 )
|
||||||
|
image->Type = VIPS_INTERPRETATION_B_W;
|
||||||
|
else if( image->Bands == 3 )
|
||||||
|
image->Type = VIPS_INTERPRETATION_RGB;
|
||||||
|
else
|
||||||
|
image->Type = VIPS_INTERPRETATION_MULTIBAND;
|
||||||
|
|
||||||
|
image->dtype = VIPS_IMAGE_SETBUF_FOREIGN;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
vips_error( "VipsImage", _( "bad mode \"%s\"" ), mode );
|
vips_error( "VipsImage", _( "bad mode \"%s\"" ), mode );
|
||||||
|
|
||||||
|
@ -887,6 +947,28 @@ vips_image_build( VipsObject *object )
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void *
|
||||||
|
vips_region_invalidate( REGION *reg )
|
||||||
|
{
|
||||||
|
reg->invalid = TRUE;
|
||||||
|
|
||||||
|
return( NULL );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
vips_image_real_invalidate( VipsImage *image )
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_VIPS
|
||||||
|
printf( "vips_image_real_invalidate: " );
|
||||||
|
vips_object_dump( VIPS_OBJECT( image ) );
|
||||||
|
#endif /*DEBUG_VIPS*/
|
||||||
|
|
||||||
|
g_mutex_lock( image->sslock );
|
||||||
|
(void) im_slist_map2( image->regions,
|
||||||
|
(VSListMap2Fn) vips_region_invalidate, NULL, NULL );
|
||||||
|
g_mutex_unlock( image->sslock );
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
vips_image_class_init( VipsImageClass *class )
|
vips_image_class_init( VipsImageClass *class )
|
||||||
{
|
{
|
||||||
|
@ -909,11 +991,13 @@ vips_image_class_init( VipsImageClass *class )
|
||||||
vobject_class->print = vips_image_print;
|
vobject_class->print = vips_image_print;
|
||||||
vobject_class->build = vips_image_build;
|
vobject_class->build = vips_image_build;
|
||||||
|
|
||||||
|
class->invalidate = vips_image_real_invalidate;
|
||||||
|
|
||||||
/* Create properties.
|
/* Create properties.
|
||||||
*/
|
*/
|
||||||
pspec = g_param_spec_int( "width", "Width",
|
pspec = g_param_spec_int( "width", "Width",
|
||||||
_( "Image width in pixels" ),
|
_( "Image width in pixels" ),
|
||||||
0, 1000000, 0,
|
1, 1000000, 0,
|
||||||
G_PARAM_READWRITE );
|
G_PARAM_READWRITE );
|
||||||
g_object_class_install_property( gobject_class, PROP_WIDTH, pspec );
|
g_object_class_install_property( gobject_class, PROP_WIDTH, pspec );
|
||||||
vips_object_class_install_argument( vobject_class, pspec,
|
vips_object_class_install_argument( vobject_class, pspec,
|
||||||
|
@ -922,7 +1006,7 @@ vips_image_class_init( VipsImageClass *class )
|
||||||
|
|
||||||
pspec = g_param_spec_int( "height", "Height",
|
pspec = g_param_spec_int( "height", "Height",
|
||||||
_( "Image height in pixels" ),
|
_( "Image height in pixels" ),
|
||||||
0, 1000000, 0,
|
1, 1000000, 0,
|
||||||
G_PARAM_READWRITE );
|
G_PARAM_READWRITE );
|
||||||
g_object_class_install_property( gobject_class, PROP_HEIGHT, pspec );
|
g_object_class_install_property( gobject_class, PROP_HEIGHT, pspec );
|
||||||
vips_object_class_install_argument( vobject_class, pspec,
|
vips_object_class_install_argument( vobject_class, pspec,
|
||||||
|
@ -931,7 +1015,7 @@ vips_image_class_init( VipsImageClass *class )
|
||||||
|
|
||||||
pspec = g_param_spec_int( "bands", "Bands",
|
pspec = g_param_spec_int( "bands", "Bands",
|
||||||
_( "Number of bands in image" ),
|
_( "Number of bands in image" ),
|
||||||
0, 1000000, 0,
|
1, 1000000, 0,
|
||||||
G_PARAM_READWRITE );
|
G_PARAM_READWRITE );
|
||||||
g_object_class_install_property( gobject_class, PROP_BANDS, pspec );
|
g_object_class_install_property( gobject_class, PROP_BANDS, pspec );
|
||||||
vips_object_class_install_argument( vobject_class, pspec,
|
vips_object_class_install_argument( vobject_class, pspec,
|
||||||
|
@ -983,6 +1067,25 @@ vips_image_class_init( VipsImageClass *class )
|
||||||
VIPS_ARGUMENT_NONE,
|
VIPS_ARGUMENT_NONE,
|
||||||
G_STRUCT_OFFSET( VipsImage, dhint ) );
|
G_STRUCT_OFFSET( VipsImage, dhint ) );
|
||||||
|
|
||||||
|
pspec = g_param_spec_int( "sizeof_header", "Size of header",
|
||||||
|
_( "Offset in bytes from start of file" ),
|
||||||
|
0, 1000000, IM_SIZEOF_HEADER,
|
||||||
|
G_PARAM_READWRITE );
|
||||||
|
g_object_class_install_property( gobject_class,
|
||||||
|
PROP_SIZEOF_HEADER, pspec );
|
||||||
|
vips_object_class_install_argument( vobject_class, pspec,
|
||||||
|
VIPS_ARGUMENT_SET_ONCE | VIPS_ARGUMENT_CONSTRUCT,
|
||||||
|
G_STRUCT_OFFSET( VipsImage, sizeof_header ) );
|
||||||
|
|
||||||
|
pspec = g_param_spec_pointer( "foreign_buffer", "Foreign buffer",
|
||||||
|
"Pointer to foreign pixels",
|
||||||
|
G_PARAM_READWRITE );
|
||||||
|
g_object_class_install_property( gobject_class,
|
||||||
|
PROP_FOREIGN_BUFFER, pspec );
|
||||||
|
vips_object_class_install_argument( vobject_class, pspec,
|
||||||
|
VIPS_ARGUMENT_SET_ONCE | VIPS_ARGUMENT_CONSTRUCT,
|
||||||
|
G_STRUCT_OFFSET( VipsImage, data ) );
|
||||||
|
|
||||||
/* Create signals.
|
/* Create signals.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -1015,6 +1118,14 @@ vips_image_class_init( VipsImageClass *class )
|
||||||
NULL, NULL,
|
NULL, NULL,
|
||||||
g_cclosure_marshal_VOID__VOID,
|
g_cclosure_marshal_VOID__VOID,
|
||||||
G_TYPE_NONE, 0 );
|
G_TYPE_NONE, 0 );
|
||||||
|
|
||||||
|
vips_image_signals[SIG_INVALIDATE] = g_signal_new( "invalidate",
|
||||||
|
G_TYPE_FROM_CLASS( class ),
|
||||||
|
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
|
||||||
|
G_STRUCT_OFFSET( VipsImageClass, invalidate ),
|
||||||
|
NULL, NULL,
|
||||||
|
g_cclosure_marshal_VOID__VOID,
|
||||||
|
G_TYPE_NONE, 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1029,7 +1140,6 @@ vips_image_init( VipsImage *image )
|
||||||
image->magic = im_amiMSBfirst() ? VIPS_MAGIC_SPARC : VIPS_MAGIC_INTEL;
|
image->magic = im_amiMSBfirst() ? VIPS_MAGIC_SPARC : VIPS_MAGIC_INTEL;
|
||||||
|
|
||||||
image->fd = -1; /* since 0 is stdout */
|
image->fd = -1; /* since 0 is stdout */
|
||||||
image->sizeof_header = IM_SIZEOF_HEADER;
|
|
||||||
image->sslock = g_mutex_new ();
|
image->sslock = g_mutex_new ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1113,6 +1223,39 @@ vips_image_written( VipsImage *image )
|
||||||
g_signal_emit( image, vips_image_signals[SIG_WRITTEN], 0 );
|
g_signal_emit( image, vips_image_signals[SIG_WRITTEN], 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
vips_image_invalidate( VipsImage *image )
|
||||||
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf( "vips_image_invalidate: " );
|
||||||
|
vips_object_print( object );
|
||||||
|
#endif /*DEBUG*/
|
||||||
|
|
||||||
|
g_signal_emit( image, vips_image_signals[SIG_INVALIDATE], 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *
|
||||||
|
vips_image_invalidate_all_cb( VipsImage *image )
|
||||||
|
{
|
||||||
|
vips_image_invalidate( image );
|
||||||
|
|
||||||
|
return( NULL );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* vips_image_invalidate_all:
|
||||||
|
* @image: #VipsImage to invalidate
|
||||||
|
*
|
||||||
|
* Invalidate all pixel caches on an @image and any derived images. The
|
||||||
|
* "invalidate" callback is triggered for all invalidated images.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
vips_image_invalidate_all( VipsImage *image )
|
||||||
|
{
|
||||||
|
(void) im__link_map( image,
|
||||||
|
(VSListMap2Fn) vips_image_invalidate_all_cb, NULL, NULL );
|
||||||
|
}
|
||||||
|
|
||||||
/* Attach a new time struct, if necessary, and reset it.
|
/* Attach a new time struct, if necessary, and reset it.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
|
@ -1202,20 +1345,62 @@ vips_image_posteval( VipsImage *image )
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* vips_image_open:
|
* vips_image_new:
|
||||||
|
* @mode: mode to open with
|
||||||
|
*
|
||||||
|
* vips_image_new() examines the mode string and creates an
|
||||||
|
* appropriate #VipsImage.
|
||||||
|
*
|
||||||
|
* <itemizedlist>
|
||||||
|
* <listitem>
|
||||||
|
* <para>
|
||||||
|
* <emphasis>"t"</emphasis>
|
||||||
|
* creates a temporary memory buffer image.
|
||||||
|
* </para>
|
||||||
|
* </listitem>
|
||||||
|
* <listitem>
|
||||||
|
* <para>
|
||||||
|
* <emphasis>"p"</emphasis>
|
||||||
|
* creates a "glue" descriptor you can use to join two image
|
||||||
|
* processing operations together.
|
||||||
|
* </para>
|
||||||
|
* </listitem>
|
||||||
|
* </itemizedlist>
|
||||||
|
*
|
||||||
|
* Returns: the image descriptor on success and NULL on error.
|
||||||
|
*/
|
||||||
|
VipsImage *
|
||||||
|
vips_image_new( const char *mode )
|
||||||
|
{
|
||||||
|
VipsImage *image;
|
||||||
|
|
||||||
|
image = VIPS_IMAGE( g_object_new( VIPS_TYPE_IMAGE, NULL ) );
|
||||||
|
g_object_set( image,
|
||||||
|
"mode", mode,
|
||||||
|
NULL );
|
||||||
|
if( vips_object_build( VIPS_OBJECT( image ) ) ) {
|
||||||
|
VIPS_UNREF( image );
|
||||||
|
return( NULL );
|
||||||
|
}
|
||||||
|
|
||||||
|
return( image );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* vips_image_new_from_file:
|
||||||
* @filename: file to open
|
* @filename: file to open
|
||||||
* @mode: mode to open with
|
* @mode: mode to open with
|
||||||
*
|
*
|
||||||
* vips_image_open() examines the mode string, and creates an appropriate
|
* vips_image_new_from_file() examines the mode string and creates an
|
||||||
* #VipsImage.
|
* appropriate #VipsImage.
|
||||||
*
|
*
|
||||||
* <itemizedlist>
|
* <itemizedlist>
|
||||||
* <listitem>
|
* <listitem>
|
||||||
* <para>
|
* <para>
|
||||||
* <emphasis>"r"</emphasis>
|
* <emphasis>"r"</emphasis>
|
||||||
* opens the named file for reading. If the file is not in the native
|
* opens the named file for reading. If the file is not in the native
|
||||||
* VIPS format for your machine, vips_image_open() automatically converts the
|
* VIPS format for your machine, vips_image_new_from_file()
|
||||||
* file for you in memory.
|
* automatically converts the file for you in memory.
|
||||||
*
|
*
|
||||||
* For some large files (eg. TIFF) this may
|
* For some large files (eg. TIFF) this may
|
||||||
* not be what you want, it can fill memory very quickly. Instead, you
|
* not be what you want, it can fill memory very quickly. Instead, you
|
||||||
|
@ -1223,7 +1408,7 @@ vips_image_posteval( VipsImage *image )
|
||||||
* API and control the loading process yourself. See
|
* API and control the loading process yourself. See
|
||||||
* #VipsBandFormat.
|
* #VipsBandFormat.
|
||||||
*
|
*
|
||||||
* vips_image_open() can read files in most formats.
|
* vips_image_new_from_file() can read files in most formats.
|
||||||
*
|
*
|
||||||
* Note that <emphasis>"r"</emphasis> mode works in at least two stages.
|
* Note that <emphasis>"r"</emphasis> mode works in at least two stages.
|
||||||
* It should return quickly and let you check header fields. It will
|
* It should return quickly and let you check header fields. It will
|
||||||
|
@ -1235,9 +1420,9 @@ vips_image_posteval( VipsImage *image )
|
||||||
* <emphasis>"rd"</emphasis>
|
* <emphasis>"rd"</emphasis>
|
||||||
* opens the named file for reading. If the uncompressed image is larger
|
* opens the named file for reading. If the uncompressed image is larger
|
||||||
* than a threshold and the file format does not support random access,
|
* than a threshold and the file format does not support random access,
|
||||||
* rather than uncompressing to memory, vips_image_open() will uncompress to a
|
* rather than uncompressing to memory, vips_image_new_from_file() will
|
||||||
* temporary disc file. This file will be automatically deleted when the
|
* uncompress to a temporary disc file. This file will be automatically
|
||||||
* IMAGE is closed.
|
* deleted when the IMAGE is closed.
|
||||||
*
|
*
|
||||||
* See im_system_image() for an explanation of how VIPS selects a
|
* See im_system_image() for an explanation of how VIPS selects a
|
||||||
* location for the temporary file.
|
* location for the temporary file.
|
||||||
|
@ -1264,7 +1449,7 @@ vips_image_posteval( VipsImage *image )
|
||||||
* suffix to determine the type to write -- for example:
|
* suffix to determine the type to write -- for example:
|
||||||
*
|
*
|
||||||
* |[
|
* |[
|
||||||
* vips_image_open( "fred.tif", "w" )
|
* vips_image_new_from_file( "fred.tif", "w" )
|
||||||
* ]|
|
* ]|
|
||||||
*
|
*
|
||||||
* will write in TIFF format.
|
* will write in TIFF format.
|
||||||
|
@ -1272,19 +1457,6 @@ vips_image_posteval( VipsImage *image )
|
||||||
* </listitem>
|
* </listitem>
|
||||||
* <listitem>
|
* <listitem>
|
||||||
* <para>
|
* <para>
|
||||||
* <emphasis>"t"</emphasis>
|
|
||||||
* creates a temporary memory buffer image.
|
|
||||||
* </para>
|
|
||||||
* </listitem>
|
|
||||||
* <listitem>
|
|
||||||
* <para>
|
|
||||||
* <emphasis>"p"</emphasis>
|
|
||||||
* creates a "glue" descriptor you can use to join two image
|
|
||||||
* processing operations together.
|
|
||||||
* </para>
|
|
||||||
* </listitem>
|
|
||||||
* <listitem>
|
|
||||||
* <para>
|
|
||||||
* <emphasis>"rw"</emphasis>
|
* <emphasis>"rw"</emphasis>
|
||||||
* opens the named file for reading and writing. This will only work for
|
* opens the named file for reading and writing. This will only work for
|
||||||
* VIPS files in a format native to your machine. It is only for
|
* VIPS files in a format native to your machine. It is only for
|
||||||
|
@ -1296,7 +1468,7 @@ vips_image_posteval( VipsImage *image )
|
||||||
* Returns: the image descriptor on success and NULL on error.
|
* Returns: the image descriptor on success and NULL on error.
|
||||||
*/
|
*/
|
||||||
VipsImage *
|
VipsImage *
|
||||||
vips_image_open( const char *filename, const char *mode )
|
vips_image_new_from_file( const char *filename, const char *mode )
|
||||||
{
|
{
|
||||||
VipsImage *image;
|
VipsImage *image;
|
||||||
|
|
||||||
|
@ -1314,7 +1486,7 @@ vips_image_open( const char *filename, const char *mode )
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* vips_image_open_raw:
|
* vips_image_new_from_file_raw:
|
||||||
* @filename: filename to open
|
* @filename: filename to open
|
||||||
* @xsize: image width
|
* @xsize: image width
|
||||||
* @ysize: image height
|
* @ysize: image height
|
||||||
|
@ -1327,98 +1499,70 @@ vips_image_open( const char *filename, const char *mode )
|
||||||
* It returns an 8-bit image with @bands bands. If the image is not 8-bit, use
|
* It returns an 8-bit image with @bands bands. If the image is not 8-bit, use
|
||||||
* im_copy_set() to transform the descriptor after loading it.
|
* im_copy_set() to transform the descriptor after loading it.
|
||||||
*
|
*
|
||||||
* See also: im_copy_set(), im_raw2vips(), vips_image_open().
|
* See also: im_copy_set(), im_raw2vips(), vips_image_new_from_file().
|
||||||
*
|
*
|
||||||
* Returns: the new #VipsImage, or %NULL on error.
|
* Returns: the new #VipsImage, or %NULL on error.
|
||||||
*/
|
*/
|
||||||
VipsImage *
|
VipsImage *
|
||||||
vips_image_open_raw( const char *filename,
|
vips_image_new_from_file_raw( const char *filename,
|
||||||
int xsize, int ysize, int bands, int offset )
|
int xsize, int ysize, int bands, int offset )
|
||||||
{
|
{
|
||||||
VipsImage *image;
|
VipsImage *image;
|
||||||
|
|
||||||
/* Check parameters.
|
image = VIPS_IMAGE( g_object_new( VIPS_TYPE_IMAGE, NULL ) );
|
||||||
*/
|
g_object_set( image,
|
||||||
if( xsize <= 0 || ysize <= 0 ||
|
"filename", filename,
|
||||||
bands <= 0 || offset <= 0 ) {
|
"mode", "a",
|
||||||
vips_error( "vips_image_open_raw",
|
"width", xsize,
|
||||||
"%s", _( "bad parameters" ) );
|
"height", ysize,
|
||||||
|
"bands", bands,
|
||||||
|
"sizeof_header", offset,
|
||||||
|
NULL );
|
||||||
|
if( vips_object_build( VIPS_OBJECT( image ) ) ) {
|
||||||
|
VIPS_UNREF( image );
|
||||||
return( NULL );
|
return( NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !(image = vips_image_open( filename, "p" )) )
|
return( image );
|
||||||
return( NULL );
|
|
||||||
|
|
||||||
if( (im->fd = im__open_image_file( name )) == -1 ) {
|
|
||||||
im_close( im );
|
|
||||||
return( NULL );
|
|
||||||
}
|
}
|
||||||
im->dtype = IM_OPENIN;
|
|
||||||
im->sizeof_header = offset;
|
|
||||||
|
|
||||||
/* Predict file size.
|
/**
|
||||||
|
* vips_image_new_from_memory:
|
||||||
|
* @buffer: start of memory area
|
||||||
|
* @xsize: image width
|
||||||
|
* @ysize: image height
|
||||||
|
* @bands: image bands (or bytes per pixel)
|
||||||
|
* @bandfmt: image format
|
||||||
|
*
|
||||||
|
* This function wraps an #IMAGE around a memory buffer. VIPS does not take
|
||||||
|
* responsibility for the area of memory, it's up to you to make sure it's
|
||||||
|
* freed when the image is closed. See for example im_add_close_callback().
|
||||||
|
*
|
||||||
|
* See also: im_binfile(), im_raw2vips(), im_open().
|
||||||
|
*
|
||||||
|
* Returns: the new #IMAGE, or %NULL on error.
|
||||||
*/
|
*/
|
||||||
psize = (gint64) xsize * ysize * bands + offset;
|
VipsImage *
|
||||||
|
vips_image_new_from_memory( void *buffer,
|
||||||
|
int xsize, int ysize, int bands, VipsBandFormat bandfmt )
|
||||||
|
{
|
||||||
|
VipsImage *image;
|
||||||
|
|
||||||
/* Read the real file length and check against what we think
|
image = VIPS_IMAGE( g_object_new( VIPS_TYPE_IMAGE, NULL ) );
|
||||||
* the size should be.
|
g_object_set( image,
|
||||||
*/
|
"foreign_buffer", buffer,
|
||||||
if( (rsize = im_file_length( im->fd )) == -1 ) {
|
"mode", "m",
|
||||||
im_close( im );
|
"width", xsize,
|
||||||
return( NULL );
|
"height", ysize,
|
||||||
}
|
"bands", bands,
|
||||||
im->file_length = rsize;
|
"format", bandfmt,
|
||||||
|
NULL );
|
||||||
/* Very common, so a special message.
|
if( vips_object_build( VIPS_OBJECT( image ) ) ) {
|
||||||
*/
|
VIPS_UNREF( image );
|
||||||
if( psize > rsize ) {
|
|
||||||
vips_error( "im_binfile", _( "unable to open %s: "
|
|
||||||
"file has been truncated" ), im->filename );
|
|
||||||
im_close( im );
|
|
||||||
return( NULL );
|
return( NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Just wierd. Only print a warning for this, since we should
|
return( image );
|
||||||
* still be able to process it without coredumps.
|
|
||||||
*/
|
|
||||||
if( psize < rsize )
|
|
||||||
im_warn( "im_binfile", _( "%s is longer than expected" ),
|
|
||||||
im->filename );
|
|
||||||
|
|
||||||
/* Set header fields.
|
|
||||||
*/
|
|
||||||
im->Xsize = xsize;
|
|
||||||
im->Ysize = ysize;
|
|
||||||
im->Bands = bands;
|
|
||||||
|
|
||||||
/* Set others to standard values.
|
|
||||||
*/
|
|
||||||
im->BandFmt = IM_BANDFMT_UCHAR;
|
|
||||||
im->Bbits = im_bits_of_fmt( im->BandFmt );
|
|
||||||
im->Coding = IM_CODING_NONE;
|
|
||||||
|
|
||||||
if( bands == 1 )
|
|
||||||
im->Type = IM_TYPE_B_W;
|
|
||||||
else if( bands == 3 )
|
|
||||||
im->Type = IM_TYPE_RGB;
|
|
||||||
else
|
|
||||||
im->Type = IM_TYPE_MULTIBAND;
|
|
||||||
|
|
||||||
im->Xres = 1.0;
|
|
||||||
im->Yres = 1.0;
|
|
||||||
|
|
||||||
im->Length = 0;
|
|
||||||
im->Compression = 0;
|
|
||||||
im->Level = 0;
|
|
||||||
|
|
||||||
im->Xoffset = 0;
|
|
||||||
im->Yoffset = 0;
|
|
||||||
|
|
||||||
/* Init others too.
|
|
||||||
*/
|
|
||||||
im->dhint = IM_THINSTRIP;
|
|
||||||
|
|
||||||
return( im );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -902,7 +902,7 @@ im__writehist( IMAGE *im )
|
||||||
/* Open the filename, read the header, some sanity checking.
|
/* Open the filename, read the header, some sanity checking.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
vips_open_input( VipsImage *image )
|
vips_image_open_input( VipsImage *image )
|
||||||
{
|
{
|
||||||
/* We don't use im->sizeof_header here, but we know we're reading a
|
/* We don't use im->sizeof_header here, but we know we're reading a
|
||||||
* VIPS image anyway.
|
* VIPS image anyway.
|
||||||
|
|
Loading…
Reference in New Issue