| /* modify vips file header! - useful for setting resolution, coding... |
| very dangerous! |
| no way of setting non-used codes in variables like newxres |
| so need flags to show new parameter has been set.. boring |
| Copyright K.Martinez 30/6/93 |
| 29/7/93 JC |
| -format added |
| - ==0 added to strcmp! |
| 17/11/94 JC |
| - new header fields added |
| 21/10/04 |
| - more header updates |
| |
| 22/8/05 |
| - less-stupid-ified |
| 20/9/05 |
| - rewritten with glib option parser, ready for xml options to go in |
| |
| */ |
| |
| /* |
| |
| 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 <ctype.h> |
| #include <sys/types.h> |
| #include <unistd.h> |
| #include <locale.h> |
| |
| #include <vips/vips.h> |
| #include <vips/internal.h> |
| #include <vips/debug.h> |
| |
| /* We have to represent all header fields as char* so we can spot unset args |
| * safely. |
| */ |
| static char *xsize = NULL; |
| static char *ysize = NULL; |
| static char *bands = NULL; |
| static char *format = NULL; |
| static char *type = NULL; |
| static char *coding = NULL; |
| static char *xres = NULL; |
| static char *yres = NULL; |
| static char *xoffset = NULL; |
| static char *yoffset = NULL; |
| static gboolean setext = FALSE; |
| |
| static GOptionEntry entries[] = { |
| { "xsize", 'x', 0, G_OPTION_ARG_STRING, &xsize, |
| N_( "set Xsize to N" ), "N" }, |
| { "ysize", 'y', 0, G_OPTION_ARG_STRING, &ysize, |
| N_( "set Ysize to N" ), "N" }, |
| { "bands", 'b', 0, G_OPTION_ARG_STRING, &bands, |
| N_( "set Bands to N" ), "N" }, |
| { "format", 'f', 0, G_OPTION_ARG_STRING, &format, |
| N_( "set BandFmt to F (eg. IM_BANDFMT_UCHAR)" ), "F" }, |
| { "type", 't', 0, G_OPTION_ARG_STRING, &type, |
| N_( "set Type to T (eg. IM_TYPE_XYZ)" ), "T" }, |
| { "coding", 'c', 0, G_OPTION_ARG_STRING, &coding, |
| N_( "set Coding to C (eg. IM_CODING_LABQ)" ), "C" }, |
| { "xres", 'X', 0, G_OPTION_ARG_STRING, &xres, |
| N_( "set Xres to R pixels/mm" ), "R" }, |
| { "yres", 'Y', 0, G_OPTION_ARG_STRING, &yres, |
| N_( "set Yres to R pixels/mm" ), "R" }, |
| { "xoffset", 'u', 0, G_OPTION_ARG_STRING, &xoffset, |
| N_( "set Xoffset to N" ), "N" }, |
| { "yoffset", 'v', 0, G_OPTION_ARG_STRING, &yoffset, |
| N_( "set Yoffset to N" ), "N" }, |
| { "setext", 'e', 0, G_OPTION_ARG_NONE, &setext, |
| N_( "replace extension block with stdin" ), NULL }, |
| { NULL } |
| }; |
| |
| static void |
| parse_pint( char *arg, int *out ) |
| { |
| /* Might as well set an upper limit. |
| */ |
| *out = atoi( arg ); |
| if( *out <= 0 || *out > 1000000 ) |
| error_exit( _( "'%s' is not a positive integer" ), arg ); |
| } |
| |
| 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 ); |
| |
| return( 0 ); |
| } |
| |