stuff
This commit is contained in:
parent
d2a0d4468f
commit
74b0bf80ad
@ -360,10 +360,11 @@ typedef struct im__IMAGE {
|
|||||||
GSList *preclosefns; /* list of pre-close callbacks */
|
GSList *preclosefns; /* list of pre-close callbacks */
|
||||||
GSList *invalidatefns; /* list of invalidate callbacks */
|
GSList *invalidatefns; /* list of invalidate callbacks */
|
||||||
|
|
||||||
/* Set this to indicate a truncated file. We've been able to read the
|
/* Record the file length here. We use this to stop ourselves mapping
|
||||||
* header, but don't try reading outside the file size.
|
* things beyond the end of the file in the case that the file has
|
||||||
|
* been truncated.
|
||||||
*/
|
*/
|
||||||
int nodata;
|
size_t file_length;
|
||||||
} IMAGE;
|
} IMAGE;
|
||||||
|
|
||||||
/* Only define if IM_ENABLE_DEPRECATED is set.
|
/* Only define if IM_ENABLE_DEPRECATED is set.
|
||||||
|
@ -83,7 +83,6 @@ IMAGE *
|
|||||||
im_binfile( const char *name, int xs, int ys, int bands, int offset )
|
im_binfile( const char *name, int xs, int ys, int bands, int offset )
|
||||||
{
|
{
|
||||||
IMAGE *im;
|
IMAGE *im;
|
||||||
gint64 length;
|
|
||||||
gint64 psize;
|
gint64 psize;
|
||||||
|
|
||||||
/* Check parameters.
|
/* Check parameters.
|
||||||
@ -112,14 +111,14 @@ im_binfile( const char *name, int xs, int ys, int bands, int offset )
|
|||||||
/* Read the file length and check against what we think
|
/* Read the file length and check against what we think
|
||||||
* the size should be.
|
* the size should be.
|
||||||
*/
|
*/
|
||||||
if( (length = im_file_length( im->fd )) == -1 ) {
|
if( (im->file_length = im_file_length( im->fd )) == -1 ) {
|
||||||
im_close( im );
|
im_close( im );
|
||||||
return( NULL );
|
return( NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Very common, so special message.
|
/* Very common, so special message.
|
||||||
*/
|
*/
|
||||||
if( psize > length ) {
|
if( psize > im->file_length ) {
|
||||||
im_error( "im_binfile", _( "unable to open %s: "
|
im_error( "im_binfile", _( "unable to open %s: "
|
||||||
"file has been truncated" ), im->filename );
|
"file has been truncated" ), im->filename );
|
||||||
im_close( im );
|
im_close( im );
|
||||||
@ -129,7 +128,7 @@ im_binfile( const char *name, int xs, int ys, int bands, int offset )
|
|||||||
/* Just wierd. Only print a warning for this, since we should
|
/* Just wierd. Only print a warning for this, since we should
|
||||||
* still be able to process it without coredumps.
|
* still be able to process it without coredumps.
|
||||||
*/
|
*/
|
||||||
if( psize < length )
|
if( psize < im->file_length )
|
||||||
im_warn( "im_binfile", _( "%s is longer than expected" ),
|
im_warn( "im_binfile", _( "%s is longer than expected" ),
|
||||||
im->filename );
|
im->filename );
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
* 9/8/08
|
* 9/8/08
|
||||||
* - lock global image list (thanks lee)
|
* - lock global image list (thanks lee)
|
||||||
* 19/3/09
|
* 19/3/09
|
||||||
* - add nodata
|
* - add file_length
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -170,7 +170,7 @@ im_init( const char *filename )
|
|||||||
im->preclosefns = NULL;
|
im->preclosefns = NULL;
|
||||||
im->invalidatefns = NULL;
|
im->invalidatefns = NULL;
|
||||||
|
|
||||||
im->nodata = 0;
|
im->file_length = 0;
|
||||||
|
|
||||||
if( !(im->filename = im_strdup( NULL, filename )) ) {
|
if( !(im->filename = im_strdup( NULL, filename )) ) {
|
||||||
im_close( im );
|
im_close( im );
|
||||||
|
@ -210,7 +210,6 @@ im__munmap( void *start, size_t length )
|
|||||||
int
|
int
|
||||||
im_mapfile( IMAGE *im )
|
im_mapfile( IMAGE *im )
|
||||||
{
|
{
|
||||||
gint64 length;
|
|
||||||
struct stat st;
|
struct stat st;
|
||||||
mode_t m;
|
mode_t m;
|
||||||
|
|
||||||
@ -219,15 +218,14 @@ im_mapfile( IMAGE *im )
|
|||||||
/* Check the size of the file; if it is less than 64 bytes, then flag
|
/* Check the size of the file; if it is less than 64 bytes, then flag
|
||||||
* an error.
|
* an error.
|
||||||
*/
|
*/
|
||||||
if( (length = im_file_length( im->fd )) == -1 )
|
g_assert( im->file_length > 0 );
|
||||||
return( -1 );
|
|
||||||
if( fstat( im->fd, &st ) == -1 ) {
|
if( fstat( im->fd, &st ) == -1 ) {
|
||||||
im_error( "im_mapfile",
|
im_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( length < 64 ) {
|
if( im->file_length < 64 ) {
|
||||||
im_error( "im_mapfile",
|
im_error( "im_mapfile",
|
||||||
"%s", _( "file is less than 64 bytes" ) );
|
"%s", _( "file is less than 64 bytes" ) );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
@ -238,13 +236,10 @@ im_mapfile( IMAGE *im )
|
|||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !(im->baseaddr = im__mmap( im->fd, 0, length, 0 )) )
|
if( !(im->baseaddr = im__mmap( im->fd, 0, im->file_length, 0 )) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
/* im__mmap() will fail for >2GB, so this is safe even for large
|
im->length = im->file_length;
|
||||||
* files.
|
|
||||||
*/
|
|
||||||
im->length = length;
|
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
@ -254,7 +249,6 @@ im_mapfile( IMAGE *im )
|
|||||||
int
|
int
|
||||||
im_mapfilerw( IMAGE *im )
|
im_mapfilerw( IMAGE *im )
|
||||||
{
|
{
|
||||||
gint64 length;
|
|
||||||
struct stat st;
|
struct stat st;
|
||||||
mode_t m;
|
mode_t m;
|
||||||
|
|
||||||
@ -263,27 +257,23 @@ im_mapfilerw( IMAGE *im )
|
|||||||
/* Check the size of the file if it is less than 64 bytes return
|
/* Check the size of the file if it is less than 64 bytes return
|
||||||
* make also sure that it is a regular file
|
* make also sure that it is a regular file
|
||||||
*/
|
*/
|
||||||
if( (length = im_file_length( im->fd )) == -1 )
|
g_assert( im->file_length > 0 );
|
||||||
return( -1 );
|
|
||||||
if( fstat( im->fd, &st ) == -1 ) {
|
if( fstat( im->fd, &st ) == -1 ) {
|
||||||
im_error( "im_mapfilerw",
|
im_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( length < 64 || !S_ISREG( m ) ) {
|
if( im->file_length < 64 || !S_ISREG( m ) ) {
|
||||||
im_error( "im_mapfile",
|
im_error( "im_mapfile",
|
||||||
"%s", _( "unable to read data" ) );
|
"%s", _( "unable to read data" ) );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !(im->baseaddr = im__mmap( im->fd, 1, length, 0 )) )
|
if( !(im->baseaddr = im__mmap( im->fd, 1, im->file_length, 0 )) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
/* im__mmap() will fail for >2GB, so this is safe even for large
|
im->length = im->file_length;
|
||||||
* files.
|
|
||||||
*/
|
|
||||||
im->length = length;
|
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
@ -325,14 +325,12 @@ read_chunk( int fd, gint64 offset, size_t length )
|
|||||||
int
|
int
|
||||||
im__has_extension_block( IMAGE *im )
|
im__has_extension_block( IMAGE *im )
|
||||||
{
|
{
|
||||||
gint64 length;
|
|
||||||
gint64 psize;
|
gint64 psize;
|
||||||
|
|
||||||
psize = im__image_pixel_length( im );
|
psize = im__image_pixel_length( im );
|
||||||
if( (length = im_file_length( im->fd )) == -1 )
|
g_assert( im->file_length > 0 );
|
||||||
return( 0 );
|
|
||||||
|
|
||||||
return( length - psize > 0 );
|
return( im->file_length - psize > 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read everything after the pixels into memory.
|
/* Read everything after the pixels into memory.
|
||||||
@ -340,29 +338,27 @@ im__has_extension_block( IMAGE *im )
|
|||||||
void *
|
void *
|
||||||
im__read_extension_block( IMAGE *im, int *size )
|
im__read_extension_block( IMAGE *im, int *size )
|
||||||
{
|
{
|
||||||
gint64 length;
|
|
||||||
gint64 psize;
|
gint64 psize;
|
||||||
void *buf;
|
void *buf;
|
||||||
|
|
||||||
psize = im__image_pixel_length( im );
|
psize = im__image_pixel_length( im );
|
||||||
if( (length = im_file_length( im->fd )) == -1 )
|
g_assert( im->file_length > 0 );
|
||||||
return( NULL );
|
if( im->file_length - psize > 10 * 1024 * 1024 ) {
|
||||||
if( length - psize > 10 * 1024 * 1024 ) {
|
|
||||||
im_error( "im_readhist",
|
im_error( "im_readhist",
|
||||||
"%s", _( "more than a 10 megabytes of XML? "
|
"%s", _( "more than a 10 megabytes of XML? "
|
||||||
"sufferin' succotash!" ) );
|
"sufferin' succotash!" ) );
|
||||||
return( NULL );
|
return( NULL );
|
||||||
}
|
}
|
||||||
if( length - psize == 0 )
|
if( im->file_length - psize == 0 )
|
||||||
return( NULL );
|
return( NULL );
|
||||||
if( !(buf = read_chunk( im->fd, psize, length - psize )) )
|
if( !(buf = read_chunk( im->fd, psize, im->file_length - psize )) )
|
||||||
return( NULL );
|
return( NULL );
|
||||||
if( size )
|
if( size )
|
||||||
*size = length - psize;
|
*size = im->file_length - psize;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf( "im__read_extension_block: read %d bytes from %s\n",
|
printf( "im__read_extension_block: read %d bytes from %s\n",
|
||||||
(int) (length - psize), im->filename );
|
(int) (im->file_length - psize), im->filename );
|
||||||
printf( "data: \"%s\"\n", (char *) buf );
|
printf( "data: \"%s\"\n", (char *) buf );
|
||||||
#endif /*DEBUG*/
|
#endif /*DEBUG*/
|
||||||
|
|
||||||
@ -896,7 +892,6 @@ im__read_header( IMAGE *image )
|
|||||||
*/
|
*/
|
||||||
unsigned char header[IM_SIZEOF_HEADER];
|
unsigned char header[IM_SIZEOF_HEADER];
|
||||||
|
|
||||||
gint64 length;
|
|
||||||
gint64 psize;
|
gint64 psize;
|
||||||
|
|
||||||
image->dtype = IM_OPENIN;
|
image->dtype = IM_OPENIN;
|
||||||
@ -913,13 +908,11 @@ im__read_header( IMAGE *image )
|
|||||||
/* Predict and check the file size.
|
/* Predict and check the file size.
|
||||||
*/
|
*/
|
||||||
psize = im__image_pixel_length( image );
|
psize = im__image_pixel_length( image );
|
||||||
if( (length = im_file_length( image->fd )) == -1 )
|
if( (image->file_length = im_file_length( image->fd )) == -1 )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
if( psize > length ) {
|
if( psize > image->file_length )
|
||||||
im_warn( "im_openin", _( "unable to read data for \"%s\", %s" ),
|
im_warn( "im_openin", _( "unable to read data for \"%s\", %s" ),
|
||||||
image->filename, _( "file has been truncated" ) );
|
image->filename, _( "file has been truncated" ) );
|
||||||
image->nodata = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set demand style. Allow the most permissive sort.
|
/* Set demand style. Allow the most permissive sort.
|
||||||
*/
|
*/
|
||||||
@ -960,9 +953,13 @@ im_openin( IMAGE *image )
|
|||||||
if( im__read_header( image ) )
|
if( im__read_header( image ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
|
/* Make sure we can map the whole thing without running over the VM
|
||||||
|
* limit or running out of file.
|
||||||
|
*/
|
||||||
size = (gint64) IM_IMAGE_SIZEOF_LINE( image ) * image->Ysize +
|
size = (gint64) IM_IMAGE_SIZEOF_LINE( image ) * image->Ysize +
|
||||||
image->sizeof_header;
|
image->sizeof_header;
|
||||||
if( size < im__mmap_limit && !image->nodata ) {
|
if( size < im__mmap_limit &&
|
||||||
|
image->file_length >= size ) {
|
||||||
if( im_mapfile( image ) )
|
if( im_mapfile( image ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
image->data = image->baseaddr + image->sizeof_header;
|
image->data = image->baseaddr + image->sizeof_header;
|
||||||
|
@ -219,15 +219,6 @@ im_window_set( im_window_t *window, int top, int height )
|
|||||||
gint64 start, end, pagestart;
|
gint64 start, end, pagestart;
|
||||||
size_t length, pagelength;
|
size_t length, pagelength;
|
||||||
|
|
||||||
/* Make sure this image has data.
|
|
||||||
*/
|
|
||||||
if( window->im->nodata ) {
|
|
||||||
im_error( "im_window_set",
|
|
||||||
_( "unable to read data for \"%s\", %s" ),
|
|
||||||
window->im->filename, _( "file has been truncated" ) );
|
|
||||||
return( -1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Calculate start and length for our window.
|
/* Calculate start and length for our window.
|
||||||
*/
|
*/
|
||||||
start = window->im->sizeof_header +
|
start = window->im->sizeof_header +
|
||||||
@ -238,6 +229,15 @@ im_window_set( im_window_t *window, int top, int height )
|
|||||||
end = start + length;
|
end = start + length;
|
||||||
pagelength = end - pagestart;
|
pagelength = end - pagestart;
|
||||||
|
|
||||||
|
/* Make sure we have enough file.
|
||||||
|
*/
|
||||||
|
if( end > window->im->file_length ) {
|
||||||
|
im_error( "im_window_set",
|
||||||
|
_( "unable to read data for \"%s\", %s" ),
|
||||||
|
window->im->filename, _( "file has been truncated" ) );
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
|
||||||
if( !(baseaddr = im__mmap( window->im->fd, 0, pagelength, pagestart )) )
|
if( !(baseaddr = im__mmap( window->im->fd, 0, pagelength, pagestart )) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user