static int mat2vips_get_header( matvar_t *var, IMAGE *im ) { int width, height, bands, format, type; int i; width = 1; height = 1; bands = 1; switch( var->rank ) { case 3: bands = var->dims[2]; case 2: height = var->dims[1]; case 1: width = var->dims[0]; break; default: im_error( "im_mat2vips", _( "unsupported rank %d\n" ), var->rank ); return( -1 ); } if( bands > 1 ) type = IM_TYPE_MULTIBAND; else type = IM_TYPE_B_W; for( i = 0; i < IM_NUMBER( mat2vips_formats ); i++ ) if( mat2vips_formats[i][0] == var->class_type ) break; if( i == IM_NUMBER( mat2vips_formats ) ) { im_error( "im_mat2vips", _( "unsupported class type %d\n" ), var->class_type ); return( -1 ); } format = mat2vips_formats[i][1]; im_initdesc( im, width, height, bands, im_bits_of_fmt( format ), format, IM_CODING_NONE, type, 1.0, 1.0, 0, 0 ); return( 0 ); }
void im_initdesc( IMAGE *image, int xsize, int ysize, int bands, int bandbits, int bandfmt, int coding, int type, float xres, float yres, int xo, int yo ) { image->Xsize = xsize; image->Ysize = ysize; image->Bands = bands; /* bandbits is deprecated ... set to whatever the format requires. */ image->Bbits = im_bits_of_fmt( bandfmt ); image->BandFmt = bandfmt; image->Coding = coding; image->Type = type; image->Xres = xres; image->Yres = yres; image->Xoffset = xo; image->Yoffset = yo; }
/** * im_binfile: * @name: filename to open * @xsize: image width * @ysize: image height * @bands: image bands (or bytes per pixel) * @offset: bytes to skip at start of file * * This function maps the named file and returns an #IMAGE you can use to * read it. * * 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. * * See also: im_copy_set(), im_raw2vips(), im_open(). * * Returns: the new #IMAGE, or NULL on error. */ IMAGE * im_binfile( const char *name, int xsize, int ysize, int bands, int offset ) { IMAGE *im; gint64 psize; gint64 rsize; /* Check parameters. */ if( xsize <= 0 || ysize <= 0 || bands <= 0 ) { im_error( "im_binfile", "%s", _( "bad parameters" ) ); return( NULL ); } /* Make new output image for us. */ if( !(im = im_init( name )) ) 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. */ psize = (gint64) xsize * ysize * bands + offset; /* Read the real file length and check against what we think * the size should be. */ if( (rsize = im_file_length( im->fd )) == -1 ) { im_close( im ); return( NULL ); } im->file_length = rsize; /* Very common, so special message. */ if( psize > rsize ) { im_error( "im_binfile", _( "unable to open %s: " "file has been truncated" ), im->filename ); im_close( im ); return( NULL ); } /* Just wierd. Only print a warning for this, since we should * 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 ); }
/** * im_generate: * @im: generate this image * @start: start sequences with this function * @generate: generate pixels with this function * @stop: stop sequences with this function * @a: user data * @b: user data * * Generates an image. The action depends on the image type. * * For images opened with "p", im_generate() just attaches the * start/generate/stop callbacks and returns. * * For "t" images, memory is allocated for the whole image and it is entirely * generated using vips_sink(). * * For "w" images, memory for a few scanlines is allocated and * vips_sink_disc() used to generate the image in small chunks. As each * chunk is generated, it is written to disc. * * See also: vips_sink(), im_open(), im_prepare(), im_wrapone(). * * Returns: 0 on success, or -1 on error. */ int im_generate( IMAGE *im, im_start_fn start, im_generate_fn generate, im_stop_fn stop, void *a, void *b ) { int res; g_assert( !im_image_sanity( im ) ); if( !im->hint_set ) { im_error( "im_generate", "%s", _( "im_demand_hint() not set" ) ); return( -1 ); } if( im->Xsize <= 0 || im->Ysize <= 0 || im->Bands <= 0 ) { im_error( "im_generate", "%s", _( "bad dimensions" ) ); return( -1 ); } /* We don't use this, but make sure it's set in case any old binaries * are expectiing it. */ im->Bbits = im_bits_of_fmt( im->BandFmt ); /* Look at output type to decide our action. */ switch( im->dtype ) { case IM_PARTIAL: /* Output to partial image. Just attach functions and return. */ if( im->generate || im->start || im->stop ) { im_error( "im_generate", "%s", _( "func already attached" ) ); return( -1 ); } im->start = start; im->generate = generate; im->stop = stop; im->client1 = a; im->client2 = b; #ifdef DEBUG_IO printf( "im_generate: attaching partial callbacks\n" ); #endif /*DEBUG_IO*/ break; case IM_SETBUF: case IM_SETBUF_FOREIGN: case IM_MMAPINRW: case IM_OPENOUT: /* Eval now .. sanity check. */ if( im->generate || im->start || im->stop ) { im_error( "im_generate", "%s", _( "func already attached" ) ); return( -1 ); } /* Get output ready. */ if( im_setupout( im ) ) return( -1 ); /* Attach callbacks. */ im->start = start; im->generate = generate; im->stop = stop; im->client1 = a; im->client2 = b; if( im->dtype == IM_OPENOUT ) res = vips_sink_disc( im, (VipsRegionWrite) write_vips, NULL ); else res = vips_sink_memory( im ); /* Error? */ if( res ) return( -1 ); break; default: /* Not a known output style. */ im_error( "im_generate", _( "unable to output to a %s image" ), im_dtype2char( im->dtype ) ); return( -1 ); } /* Successful write: trigger "written". */ if( im__trigger_callbacks( im->writtenfns ) ) return( -1 ); return( 0 ); }
static int vips_fits_get_header( VipsFits *fits, VipsImage *out ) { int status; int bitpix; int width, height, bands, format, type; int keysexist; int i; status = 0; if( fits_get_img_paramll( fits->fptr, 10, &bitpix, &fits->naxis, fits->naxes, &status ) ) { vips_fits_error( status ); return( -1 ); } #ifdef VIPS_DEBUG VIPS_DEBUG_MSG( "naxis = %d\n", fits->naxis ); for( i = 0; i < fits->naxis; i++ ) VIPS_DEBUG_MSG( "%d) %lld\n", i, fits->naxes[i] ); #endif /*VIPS_DEBUG*/ width = 1; height = 1; bands = 1; switch( fits->naxis ) { /* If you add more dimensions here, adjust data read below. See also * the definition of MAX_DIMENSIONS above. */ case 10: case 9: case 8: case 7: case 6: case 5: case 4: for( i = fits->naxis; i > 3; i-- ) if( fits->naxes[i - 1] != 1 ) { im_error( "fits", "%s", _( "dimensions above 3 " "must be size 1" ) ); return( -1 ); } case 3: bands = fits->naxes[2]; case 2: height = fits->naxes[1]; case 1: width = fits->naxes[0]; break; default: im_error( "fits", _( "bad number of axis %d" ), fits->naxis ); return( -1 ); } /* Are we in one-band mode? */ if( fits->band_select != -1 ) bands = 1; /* Get image format. We want the 'raw' format of the image, our caller * can convert using the meta info if they want. */ for( i = 0; i < VIPS_NUMBER( fits2vips_formats ); i++ ) if( fits2vips_formats[i][0] == bitpix ) break; if( i == VIPS_NUMBER( fits2vips_formats ) ) { im_error( "fits", _( "unsupported bitpix %d\n" ), bitpix ); return( -1 ); } format = fits2vips_formats[i][1]; fits->datatype = fits2vips_formats[i][2]; if( bands == 1 ) { if( format == VIPS_FORMAT_USHORT ) type = VIPS_INTERPRETATION_GREY16; else type = VIPS_INTERPRETATION_B_W; } else if( bands == 3 ) { if( format == VIPS_FORMAT_USHORT ) type = VIPS_INTERPRETATION_RGB16; else type = VIPS_INTERPRETATION_RGB; } else type = VIPS_INTERPRETATION_MULTIBAND; im_initdesc( out, width, height, bands, im_bits_of_fmt( format ), format, VIPS_CODING_NONE, type, 1.0, 1.0, 0, 0 ); /* Read all keys into meta. */ if( fits_get_hdrspace( fits->fptr, &keysexist, NULL, &status ) ) { vips_fits_error( status ); return( -1 ); } for( i = 0; i < keysexist; i++ ) { char record[81]; char vipsname[100]; if( fits_read_record( fits->fptr, i + 1, record, &status ) ) { vips_fits_error( status ); return( -1 ); } VIPS_DEBUG_MSG( "fits2vips: setting meta on vips image:\n" ); VIPS_DEBUG_MSG( " record == \"%s\"\n", record ); /* FITS lets keys repeat. For example, HISTORY appears many * times, each time with a fresh line of history attached. We * have to include the key index in the vips name we assign. */ im_snprintf( vipsname, 100, "fits-%d", i ); if( im_meta_set_string( out, vipsname, record ) ) return( -1 ); } return( 0 ); }
int main( int argc, char **argv ) { GOptionContext *context; GError *error = NULL; IMAGE *im; unsigned char header[IM_SIZEOF_HEADER]; if( im_init_world( argv[0] ) ) error_exit( "%s", _( "unable to start VIPS" ) ); textdomain( GETTEXT_PACKAGE ); setlocale( LC_ALL, "" ); context = g_option_context_new( _( "vipsfile - edit vipsfile header" ) ); g_option_context_add_main_entries( context, entries, GETTEXT_PACKAGE ); g_option_context_add_group( context, im_get_option_group() ); if( !g_option_context_parse( context, &argc, &argv, &error ) ) { if( error ) { fprintf( stderr, "%s\n", error->message ); g_error_free( error ); } exit( -1 ); } if( argc != 2 ) { fprintf( stderr, _( "usage: %s [OPTION...] vipsfile\n" ), g_get_prgname() ); exit( -1 ); } if( !(im = im_init( argv[1] )) || (im->fd = im__open_image_file( im->filename )) == -1 ) error_exit( _( "could not open image %s" ), argv[1] ); if( read( im->fd, header, IM_SIZEOF_HEADER ) != IM_SIZEOF_HEADER || im__read_header_bytes( im, header ) ) error_exit( _( "could not read VIPS header for %s" ), im->filename ); if( xsize ) parse_pint( xsize, &im->Xsize ); if( ysize ) parse_pint( ysize, &im->Ysize ); if( bands ) parse_pint( bands, &im->Bands ); if( format ) { if( (im->BandFmt = im_char2BandFmt( format )) < 0 ) error_exit( _( "bad format %s" ), format ); im->Bbits = im_bits_of_fmt( im->BandFmt ); } if( type ) { if( (im->Type = im_char2Type( type )) < 0 ) error_exit( _( "bad type %s" ), type ); } if( coding ) { if( (im->Coding = im_char2Coding( coding )) < 0 ) error_exit( _( "bad coding %s" ), coding ); } if( xres ) im->Xres = atof( xres ); if( yres ) im->Yres = atof( yres ); if( xoffset ) im->Xoffset = atoi( xoffset ); if( yoffset ) im->Yoffset = atoi( yoffset ); if( lseek( im->fd, 0, SEEK_SET ) == (off_t) -1 ) error_exit( _( "could not seek on %s" ), im->filename ); if( im__write_header_bytes( im, header ) || im__write( im->fd, header, IM_SIZEOF_HEADER ) ) error_exit( _( "could not write to %s" ), im->filename ); if( setext ) { char *xml; unsigned int size; if( !(xml = im__file_read( stdin, "stdin", &size )) ) error_exit( "%s", _( "could not get ext data" ) ); /* Strip trailing whitespace ... we can get stray \n at the * end, eg. "echo | edvips --setext fred.v". */ while( size > 0 && isspace( xml[size - 1] ) ) size -= 1; if( im__write_extension_block( im, xml, size ) ) error_exit( "%s", _( "could not set extension" ) ); im_free( xml ); } im_close( im ); vips_shutdown(); return( 0 ); }
int main( int argc, char **argv ) { GOptionContext *context; GOptionGroup *main_group; GError *error = NULL; IMAGE *im; unsigned char header[IM_SIZEOF_HEADER]; if( VIPS_INIT( argv[0] ) ) vips_error_exit( "%s", _( "unable to start VIPS" ) ); textdomain( GETTEXT_PACKAGE ); setlocale( LC_ALL, "" ); context = g_option_context_new( _( "vipsedit - edit vips file header" ) ); main_group = g_option_group_new( NULL, NULL, NULL, NULL, NULL ); g_option_group_add_entries( main_group, entries ); vips_add_option_entries( main_group ); g_option_group_set_translation_domain( main_group, GETTEXT_PACKAGE ); g_option_context_set_main_group( context, main_group ); if( !g_option_context_parse( context, &argc, &argv, &error ) ) { if( error ) { fprintf( stderr, "%s\n", error->message ); g_error_free( error ); } exit( -1 ); } if( argc != 2 ) { fprintf( stderr, _( "usage: %s [OPTION...] vips-file\n" ), g_get_prgname() ); exit( -1 ); } if( !(im = im_init( argv[1] )) || (im->fd = im__open_image_file( im->filename )) == -1 ) error_exit( _( "could not open image %s" ), argv[1] ); if( read( im->fd, header, IM_SIZEOF_HEADER ) != IM_SIZEOF_HEADER || im__read_header_bytes( im, header ) ) error_exit( _( "could not read VIPS header for %s" ), im->filename ); if( endian ) { if( strcmp( endian, "little" ) == 0 ) im->magic = VIPS_MAGIC_INTEL; else if( strcmp( endian, "big" ) == 0 ) im->magic = VIPS_MAGIC_SPARC; else error_exit( _( "bad endian-ness %s, " "should be 'big' or 'little'" ), endian ); } if( xsize ) parse_pint( xsize, &im->Xsize ); if( ysize ) parse_pint( ysize, &im->Ysize ); if( bands ) parse_pint( bands, &im->Bands ); if( format ) { VipsBandFormat f; if( (f = im_char2BandFmt( format )) < 0 ) error_exit( _( "bad format %s" ), format ); im->BandFmt = f; im->Bbits = im_bits_of_fmt( f ); } if( interpretation ) { VipsInterpretation i; if( (i = im_char2Type( interpretation )) < 0 ) error_exit( _( "bad interpretation %s" ), interpretation ); im->Type = i; } if( coding ) { VipsCoding c; if( (c = im_char2Coding( coding )) < 0 ) error_exit( _( "bad coding %s" ), coding ); im->Coding = c; } if( xres ) im->Xres = atof( xres ); if( yres ) im->Yres = atof( yres ); if( xoffset ) im->Xoffset = atoi( xoffset ); if( yoffset ) im->Yoffset = atoi( yoffset ); if( lseek( im->fd, 0, SEEK_SET ) == (off_t) -1 ) error_exit( _( "could not seek on %s" ), im->filename ); if( im__write_header_bytes( im, header ) || im__write( im->fd, header, IM_SIZEOF_HEADER ) ) error_exit( _( "could not write to %s" ), im->filename ); if( setext ) { char *xml; size_t size; if( !(xml = im__file_read( stdin, "stdin", &size )) ) error_exit( "%s", _( "could not get ext data" ) ); /* Strip trailing whitespace ... we can get stray \n at the * end, eg. "echo | editvips --setext fred.v". */ while( size > 0 && isspace( xml[size - 1] ) ) size -= 1; if( im__write_extension_block( im, xml, size ) ) error_exit( "%s", _( "could not set extension" ) ); im_free( xml ); } im_close( im ); vips_shutdown(); return( 0 ); }