move ppm save into the class
no separate save function now
This commit is contained in:
parent
7a047f5332
commit
17b994419b
@ -16,7 +16,6 @@ libforeign_la_SOURCES = \
|
||||
radiance.c \
|
||||
radload.c \
|
||||
radsave.c \
|
||||
ppm.c \
|
||||
ppmload.c \
|
||||
ppmsave.c \
|
||||
csv.c \
|
||||
|
@ -1135,22 +1135,7 @@ build_scan_properties( VipsImage *image )
|
||||
char *date;
|
||||
int i;
|
||||
|
||||
#ifdef HAVE_DATE_TIME_FORMAT_ISO8601
|
||||
{
|
||||
GDateTime *now;
|
||||
|
||||
now = g_date_time_new_now_local();
|
||||
date = g_date_time_format_iso8601( now );
|
||||
g_date_time_unref( now );
|
||||
}
|
||||
#else /*!HAVE_DATE_TIME_FORMAT_ISO8601*/
|
||||
{
|
||||
GTimeVal now;
|
||||
|
||||
g_get_current_time( &now );
|
||||
date = g_time_val_to_iso8601( &now );
|
||||
}
|
||||
#endif /*HAVE_DATE_TIME_FORMAT_ISO8601*/
|
||||
date = vips__get_iso8601();
|
||||
|
||||
vips_dbuf_init( &dbuf );
|
||||
vips_dbuf_writef( &dbuf, "<?xml version=\"1.0\"?>\n" );
|
||||
|
@ -1993,7 +1993,7 @@ vips_foreign_operation_init( void )
|
||||
extern GType vips_foreign_save_rad_stream_get_type( void );
|
||||
extern GType vips_foreign_load_mat_get_type( void );
|
||||
extern GType vips_foreign_load_ppm_file_get_type( void );
|
||||
extern GType vips_foreign_save_ppm_get_type( void );
|
||||
extern GType vips_foreign_save_ppm_file_get_type( void );
|
||||
extern GType vips_foreign_load_png_get_type( void );
|
||||
extern GType vips_foreign_load_png_buffer_get_type( void );
|
||||
extern GType vips_foreign_load_png_stream_get_type( void );
|
||||
@ -2077,7 +2077,7 @@ vips_foreign_operation_init( void )
|
||||
|
||||
#ifdef HAVE_PPM
|
||||
vips_foreign_load_ppm_file_get_type();
|
||||
vips_foreign_save_ppm_get_type();
|
||||
vips_foreign_save_ppm_file_get_type();
|
||||
#endif /*HAVE_PPM*/
|
||||
|
||||
#ifdef HAVE_RADIANCE
|
||||
|
@ -1,330 +0,0 @@
|
||||
/* Read a ppm file.
|
||||
*
|
||||
|
||||
* 4/2/10
|
||||
* - gtkdoc
|
||||
|
||||
* 13/11/19
|
||||
* - redone with streams
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 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>
|
||||
|
||||
#ifdef HAVE_PPM
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <vips/vips.h>
|
||||
#include <vips/internal.h>
|
||||
|
||||
#include "pforeign.h"
|
||||
|
||||
struct _Write;
|
||||
|
||||
typedef int (*write_fn)( struct _Write *write, VipsPel *p );
|
||||
|
||||
/* What we track during a PPM write.
|
||||
*/
|
||||
typedef struct _Write {
|
||||
VipsImage *in;
|
||||
VipsStreamo *streamo;
|
||||
write_fn fn;
|
||||
} Write;
|
||||
|
||||
static void
|
||||
write_destroy( Write *write )
|
||||
{
|
||||
if( write->streamo )
|
||||
vips_streamo_finish( write->streamo );
|
||||
VIPS_UNREF( write->streamo );
|
||||
|
||||
vips_free( write );
|
||||
}
|
||||
|
||||
static Write *
|
||||
write_new( VipsImage *in, VipsStreamo *streamo )
|
||||
{
|
||||
Write *write;
|
||||
|
||||
if( !(write = VIPS_NEW( NULL, Write )) )
|
||||
return( NULL );
|
||||
|
||||
write->in = in;
|
||||
write->streamo = streamo;
|
||||
g_object_ref( streamo );
|
||||
write->fn = NULL;
|
||||
|
||||
return( write );
|
||||
}
|
||||
|
||||
static int
|
||||
write_ppm_line_ascii( Write *write, VipsPel *p )
|
||||
{
|
||||
const int sk = VIPS_IMAGE_SIZEOF_PEL( write->in );
|
||||
int x, k;
|
||||
|
||||
for( x = 0; x < write->in->Xsize; x++ ) {
|
||||
for( k = 0; k < write->in->Bands; k++ ) {
|
||||
switch( write->in->BandFmt ) {
|
||||
case VIPS_FORMAT_UCHAR:
|
||||
vips_streamo_writef( write->streamo,
|
||||
"%d ", p[k] );
|
||||
break;
|
||||
|
||||
case VIPS_FORMAT_USHORT:
|
||||
vips_streamo_writef( write->streamo,
|
||||
"%d ", ((unsigned short *) p)[k] );
|
||||
break;
|
||||
|
||||
case VIPS_FORMAT_UINT:
|
||||
vips_streamo_writef( write->streamo,
|
||||
"%d ", ((unsigned int *) p)[k] );
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
}
|
||||
|
||||
p += sk;
|
||||
}
|
||||
|
||||
if( vips_streamo_writef( write->streamo, "\n" ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static int
|
||||
write_ppm_line_ascii_squash( Write *write, VipsPel *p )
|
||||
{
|
||||
int x;
|
||||
|
||||
for( x = 0; x < write->in->Xsize; x++ )
|
||||
vips_streamo_writef( write->streamo, "%d ", p[x] ? 0 : 1 );
|
||||
|
||||
if( vips_streamo_writef( write->streamo, "\n" ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static int
|
||||
write_ppm_line_binary( Write *write, VipsPel *p )
|
||||
{
|
||||
if( vips_streamo_write( write->streamo,
|
||||
p, VIPS_IMAGE_SIZEOF_LINE( write->in ) ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static int
|
||||
write_ppm_line_binary_squash( Write *write, VipsPel *p )
|
||||
{
|
||||
int x;
|
||||
int bits;
|
||||
int n_bits;
|
||||
|
||||
bits = 0;
|
||||
n_bits = 0;
|
||||
for( x = 0; x < write->in->Xsize; x++ ) {
|
||||
bits = VIPS_LSHIFT_INT( bits, 1 );
|
||||
n_bits += 1;
|
||||
bits |= p[x] ? 0 : 1;
|
||||
|
||||
if( n_bits == 8 ) {
|
||||
if( VIPS_STREAMO_PUTC( write->streamo, bits ) )
|
||||
return( -1 );
|
||||
|
||||
bits = 0;
|
||||
n_bits = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Flush any remaining bits in this line.
|
||||
*/
|
||||
if( n_bits &&
|
||||
VIPS_STREAMO_PUTC( write->streamo, bits ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static int
|
||||
write_ppm_block( VipsRegion *region, VipsRect *area, void *a )
|
||||
{
|
||||
Write *write = (Write *) a;
|
||||
int i;
|
||||
|
||||
for( i = 0; i < area->height; i++ ) {
|
||||
VipsPel *p = VIPS_REGION_ADDR( region, 0, area->top + i );
|
||||
|
||||
if( write->fn( write, p ) )
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static int
|
||||
write_ppm( Write *write, gboolean ascii, gboolean squash )
|
||||
{
|
||||
VipsImage *in = write->in;
|
||||
|
||||
char *magic;
|
||||
time_t timebuf;
|
||||
|
||||
magic = "unset";
|
||||
if( in->BandFmt == VIPS_FORMAT_FLOAT && in->Bands == 3 )
|
||||
magic = "PF";
|
||||
else if( in->BandFmt == VIPS_FORMAT_FLOAT && in->Bands == 1 )
|
||||
magic = "Pf";
|
||||
else if( in->Bands == 1 && ascii && squash )
|
||||
magic = "P1";
|
||||
else if( in->Bands == 1 && ascii )
|
||||
magic = "P2";
|
||||
else if( in->Bands == 1 && !ascii && squash )
|
||||
magic = "P4";
|
||||
else if( in->Bands == 1 && !ascii )
|
||||
magic = "P5";
|
||||
else if( in->Bands == 3 && ascii )
|
||||
magic = "P3";
|
||||
else if( in->Bands == 3 && !ascii )
|
||||
magic = "P6";
|
||||
else
|
||||
g_assert_not_reached();
|
||||
|
||||
vips_streamo_writef( write->streamo, "%s\n", magic );
|
||||
time( &timebuf );
|
||||
vips_streamo_writef( write->streamo,
|
||||
"#vips2ppm - %s\n", ctime( &timebuf ) );
|
||||
vips_streamo_writef( write->streamo, "%d %d\n", in->Xsize, in->Ysize );
|
||||
|
||||
if( !squash )
|
||||
switch( in->BandFmt ) {
|
||||
case VIPS_FORMAT_UCHAR:
|
||||
vips_streamo_writef( write->streamo,
|
||||
"%d\n", UCHAR_MAX );
|
||||
break;
|
||||
|
||||
case VIPS_FORMAT_USHORT:
|
||||
vips_streamo_writef( write->streamo,
|
||||
"%d\n", USHRT_MAX );
|
||||
break;
|
||||
|
||||
case VIPS_FORMAT_UINT:
|
||||
vips_streamo_writef( write->streamo,
|
||||
"%d\n", UINT_MAX );
|
||||
break;
|
||||
|
||||
case VIPS_FORMAT_FLOAT:
|
||||
{
|
||||
double scale;
|
||||
|
||||
if( vips_image_get_double( in, "pfm-scale", &scale ) )
|
||||
scale = 1;
|
||||
if( !vips_amiMSBfirst() )
|
||||
scale *= -1;
|
||||
vips_streamo_writef( write->streamo,
|
||||
"%g\n", scale );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
if( squash )
|
||||
write->fn = ascii ?
|
||||
write_ppm_line_ascii_squash :
|
||||
write_ppm_line_binary_squash;
|
||||
else
|
||||
write->fn = ascii ?
|
||||
write_ppm_line_ascii :
|
||||
write_ppm_line_binary;
|
||||
|
||||
if( vips_sink_disc( write->in, write_ppm_block, write ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int
|
||||
vips__ppm_save_stream( VipsImage *in, VipsStreamo *streamo,
|
||||
gboolean ascii, gboolean squash )
|
||||
{
|
||||
Write *write;
|
||||
|
||||
if( vips_check_uintorf( "vips2ppm", in ) ||
|
||||
vips_check_bands_1or3( "vips2ppm", in ) ||
|
||||
vips_check_uncoded( "vips2ppm", in ) ||
|
||||
vips_image_pio_input( in ) )
|
||||
return( -1 );
|
||||
|
||||
if( ascii &&
|
||||
in->BandFmt == VIPS_FORMAT_FLOAT ) {
|
||||
g_warning( "%s",
|
||||
_( "float images must be binary -- disabling ascii" ) );
|
||||
ascii = FALSE;
|
||||
}
|
||||
|
||||
/* One bit images must come from a 8 bit, one band source.
|
||||
*/
|
||||
if( squash &&
|
||||
(in->Bands != 1 ||
|
||||
in->BandFmt != VIPS_FORMAT_UCHAR) ) {
|
||||
g_warning( "%s",
|
||||
_( "can only squash 1 band uchar images -- "
|
||||
"disabling squash" ) );
|
||||
squash = FALSE;
|
||||
}
|
||||
|
||||
if( !(write = write_new( in, streamo )) )
|
||||
return( -1 );
|
||||
|
||||
if( write_ppm( write, ascii, squash ) ) {
|
||||
write_destroy( write );
|
||||
return( -1 );
|
||||
}
|
||||
write_destroy( write );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#endif /*HAVE_PPM*/
|
@ -62,6 +62,12 @@
|
||||
|
||||
*/
|
||||
|
||||
/* TODO
|
||||
*
|
||||
* - make partial
|
||||
* - only use mmap on filename streams?
|
||||
*/
|
||||
|
||||
/*
|
||||
#define DEBUG
|
||||
*/
|
||||
@ -147,110 +153,32 @@ vips_foreign_load_ppm_is_a_stream( VipsStreami *streami )
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
/* The largest number/field/whatever we can read.
|
||||
*/
|
||||
#define MAX_THING (80)
|
||||
|
||||
/* After this, the next getc will be the first char of the next line (or EOF).
|
||||
*/
|
||||
static int
|
||||
skip_line( VipsStreamib *streamib )
|
||||
{
|
||||
int ch;
|
||||
|
||||
while( (ch = VIPS_STREAMIB_GETC( streamib )) != '\n' &&
|
||||
ch != EOF )
|
||||
;
|
||||
|
||||
if( ch == EOF )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/* After this, the next getc will be the first char of the next block of
|
||||
* non-whitespace (or EOF).
|
||||
*/
|
||||
static int
|
||||
skip_white_space( VipsStreamib *streamib )
|
||||
{
|
||||
int ch;
|
||||
|
||||
while( isspace( ch = VIPS_STREAMIB_GETC( streamib ) ) )
|
||||
;
|
||||
VIPS_STREAMIB_UNGETC( streamib );
|
||||
|
||||
/* # skip comments too.
|
||||
*/
|
||||
if( ch == '#' &&
|
||||
(skip_line( streamib ) ||
|
||||
skip_white_space( streamib )) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/* After this, the next getc will be the first char of the next block of
|
||||
* whitespace (or EOF). buf will be filled with up to length bytes, and
|
||||
* null-terminated.
|
||||
*
|
||||
* If the first getc is whitespace, stop instantly and return nothing.
|
||||
*/
|
||||
static int
|
||||
read_non_white_space( VipsStreamib *streamib, char *buf, int length )
|
||||
get_int( VipsStreamib *streamib, int *i )
|
||||
{
|
||||
int ch;
|
||||
int i;
|
||||
const char *txt;
|
||||
|
||||
for( i = 0; i < length - 1 &&
|
||||
!isspace( ch = VIPS_STREAMIB_GETC( streamib ) ) &&
|
||||
ch != EOF; i++ )
|
||||
buf[i] = ch;
|
||||
buf[i] = '\0';
|
||||
if( vips_streamib_skip_whitespace( streamib ) ||
|
||||
!(txt = vips_streamib_get_non_whitespace( streamib )) )
|
||||
return( -1 );
|
||||
|
||||
/* If we stopped before seeing any whitespace, skip to the end of the
|
||||
* block of non-whitespace.
|
||||
*/
|
||||
if( !isspace( ch ) )
|
||||
while( !isspace( ch = VIPS_STREAMIB_GETC( streamib ) ) &&
|
||||
ch != EOF )
|
||||
;
|
||||
|
||||
/* If we finally stopped on whitespace, step back one so the next get
|
||||
* will be whitespace (or EOF).
|
||||
*/
|
||||
if( isspace( ch ) )
|
||||
VIPS_STREAMIB_UNGETC( streamib );
|
||||
*i = atoi( txt );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static int
|
||||
read_int( VipsStreamib *streamib, int *i )
|
||||
get_float( VipsStreamib *streamib, float *f )
|
||||
{
|
||||
char buf[MAX_THING];
|
||||
const char *txt;
|
||||
|
||||
if( skip_white_space( streamib ) )
|
||||
if( vips_streamib_skip_whitespace( streamib ) ||
|
||||
!(txt = vips_streamib_get_non_whitespace( streamib )) )
|
||||
return( -1 );
|
||||
|
||||
read_non_white_space( streamib, buf, MAX_THING );
|
||||
*i = atoi( buf );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static int
|
||||
read_float( VipsStreamib *streamib, float *f )
|
||||
{
|
||||
char buf[MAX_THING];
|
||||
|
||||
if( skip_white_space( streamib ) )
|
||||
return( -1 );
|
||||
|
||||
read_non_white_space( streamib, buf, MAX_THING );
|
||||
/* We don't want the locale str -> float conversion.
|
||||
*/
|
||||
*f = g_ascii_strtod( buf, NULL );
|
||||
*f = g_ascii_strtod( txt, NULL );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
@ -289,6 +217,9 @@ vips_foreign_load_ppm_parse_header( VipsForeignLoadPpm *ppm )
|
||||
1, 1, 1, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
if( vips_streami_rewind( ppm->streami ) )
|
||||
return( -1 );
|
||||
|
||||
/* Read in the magic number.
|
||||
*/
|
||||
buf[0] = VIPS_STREAMIB_GETC( ppm->streamib );
|
||||
@ -312,8 +243,8 @@ vips_foreign_load_ppm_parse_header( VipsForeignLoadPpm *ppm )
|
||||
|
||||
/* Read in size.
|
||||
*/
|
||||
if( read_int( ppm->streamib, &ppm->width ) ||
|
||||
read_int( ppm->streamib, &ppm->height ) )
|
||||
if( get_int( ppm->streamib, &ppm->width ) ||
|
||||
get_int( ppm->streamib, &ppm->height ) )
|
||||
return( -1 );
|
||||
|
||||
/* Read in max value / scale for >1 bit images.
|
||||
@ -321,7 +252,7 @@ vips_foreign_load_ppm_parse_header( VipsForeignLoadPpm *ppm )
|
||||
if( ppm->bits > 1 ) {
|
||||
if( ppm->index == 6 ||
|
||||
ppm->index == 7 ) {
|
||||
if( read_float( ppm->streamib, &ppm->scale ) )
|
||||
if( get_float( ppm->streamib, &ppm->scale ) )
|
||||
return( -1 );
|
||||
|
||||
/* Scale > 0 means big-endian.
|
||||
@ -329,7 +260,7 @@ vips_foreign_load_ppm_parse_header( VipsForeignLoadPpm *ppm )
|
||||
ppm->msb_first = ppm->scale > 0;
|
||||
}
|
||||
else {
|
||||
if( read_int( ppm->streamib, &ppm->max_value ) )
|
||||
if( get_int( ppm->streamib, &ppm->max_value ) )
|
||||
return( -1 );
|
||||
|
||||
if( ppm->max_value > 255 )
|
||||
@ -445,6 +376,8 @@ vips_foreign_load_ppm_header( VipsForeignLoad *load )
|
||||
|
||||
vips_foreign_load_ppm_set_image( ppm, load->out );
|
||||
|
||||
vips_streami_minimise( ppm->streami );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
@ -499,7 +432,7 @@ load_1bit_ascii( VipsForeignLoadPpm *ppm, VipsImage *image )
|
||||
for( x = 0; x < image->Xsize; x++ ) {
|
||||
int val;
|
||||
|
||||
if( read_int( ppm->streamib, &val ) )
|
||||
if( get_int( ppm->streamib, &val ) )
|
||||
return( -1 );
|
||||
|
||||
if( val )
|
||||
@ -567,7 +500,7 @@ load_ascii( VipsForeignLoadPpm *ppm, VipsImage *image )
|
||||
for( x = 0; x < image->Xsize * image->Bands; x++ ) {
|
||||
int val;
|
||||
|
||||
if( read_int( ppm->streamib, &val ) )
|
||||
if( get_int( ppm->streamib, &val ) )
|
||||
return( -1 );
|
||||
|
||||
switch( image->BandFmt ) {
|
||||
@ -620,9 +553,12 @@ vips_foreign_load_ppm_load( VipsForeignLoad *load )
|
||||
else
|
||||
loader = load_ascii;
|
||||
|
||||
if( loader( ppm, load->real ) )
|
||||
if( vips_streami_decode( ppm->streami ) ||
|
||||
loader( ppm, load->real ) )
|
||||
return( -1 );
|
||||
|
||||
vips_streami_minimise( ppm->streami );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
|
@ -46,44 +46,292 @@
|
||||
#include <string.h>
|
||||
|
||||
#include <vips/vips.h>
|
||||
#include <vips/internal.h>
|
||||
|
||||
#include "pforeign.h"
|
||||
|
||||
#ifdef HAVE_PPM
|
||||
|
||||
typedef struct _VipsForeignSavePpm VipsForeignSavePpm;
|
||||
|
||||
typedef int (*VipsSavePpmFn)( VipsForeignSavePpm *, VipsImage *, VipsPel * );
|
||||
|
||||
typedef struct _VipsForeignSavePpm {
|
||||
VipsForeignSave parent_object;
|
||||
|
||||
char *filename;
|
||||
VipsStreamo *streamo;
|
||||
gboolean ascii;
|
||||
gboolean squash;
|
||||
|
||||
VipsSavePpmFn fn;
|
||||
} VipsForeignSavePpm;
|
||||
|
||||
typedef VipsForeignSaveClass VipsForeignSavePpmClass;
|
||||
|
||||
G_DEFINE_TYPE( VipsForeignSavePpm, vips_foreign_save_ppm,
|
||||
G_DEFINE_ABSTRACT_TYPE( VipsForeignSavePpm, vips_foreign_save_ppm,
|
||||
VIPS_TYPE_FOREIGN_SAVE );
|
||||
|
||||
static void
|
||||
vips_foreign_save_ppm_dispose( GObject *gobject )
|
||||
{
|
||||
VipsForeignSavePpm *ppm = (VipsForeignSavePpm *) gobject;
|
||||
|
||||
if( ppm->streamo )
|
||||
vips_streamo_finish( ppm->streamo );
|
||||
VIPS_UNREF( ppm->streamo );
|
||||
|
||||
G_OBJECT_CLASS( vips_foreign_save_ppm_parent_class )->
|
||||
dispose( gobject );
|
||||
}
|
||||
|
||||
static int
|
||||
vips_foreign_save_ppm_line_ascii( VipsForeignSavePpm *ppm,
|
||||
VipsImage *image, VipsPel *p )
|
||||
{
|
||||
const int n_elements = image->Xsize * image->Bands;
|
||||
|
||||
int i;
|
||||
|
||||
for( i = 0; i < n_elements; i++ ) {
|
||||
switch( image->BandFmt ) {
|
||||
case VIPS_FORMAT_UCHAR:
|
||||
vips_streamo_writef( ppm->streamo,
|
||||
"%d ", p[i] );
|
||||
break;
|
||||
|
||||
case VIPS_FORMAT_USHORT:
|
||||
vips_streamo_writef( ppm->streamo,
|
||||
"%d ", ((unsigned short *) p)[i] );
|
||||
break;
|
||||
|
||||
case VIPS_FORMAT_UINT:
|
||||
vips_streamo_writef( ppm->streamo,
|
||||
"%d ", ((unsigned int *) p)[i] );
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
}
|
||||
|
||||
if( vips_streamo_writes( ppm->streamo, "\n" ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static int
|
||||
vips_foreign_save_ppm_line_ascii_squash( VipsForeignSavePpm *ppm,
|
||||
VipsImage *image, VipsPel *p )
|
||||
{
|
||||
int x;
|
||||
|
||||
for( x = 0; x < image->Xsize; x++ )
|
||||
vips_streamo_writef( ppm->streamo, "%d ", p[x] ? 0 : 1 );
|
||||
|
||||
if( vips_streamo_writes( ppm->streamo, "\n" ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static int
|
||||
vips_foreign_save_ppm_line_binary( VipsForeignSavePpm *ppm,
|
||||
VipsImage *image, VipsPel *p )
|
||||
{
|
||||
if( vips_streamo_write( ppm->streamo,
|
||||
p, VIPS_IMAGE_SIZEOF_LINE( image ) ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static int
|
||||
vips_foreign_save_ppm_line_binary_squash( VipsForeignSavePpm *ppm,
|
||||
VipsImage *image, VipsPel *p )
|
||||
{
|
||||
int x;
|
||||
int bits;
|
||||
int n_bits;
|
||||
|
||||
bits = 0;
|
||||
n_bits = 0;
|
||||
for( x = 0; x < image->Xsize; x++ ) {
|
||||
bits = VIPS_LSHIFT_INT( bits, 1 );
|
||||
n_bits += 1;
|
||||
bits |= p[x] ? 0 : 1;
|
||||
|
||||
if( n_bits == 8 ) {
|
||||
if( VIPS_STREAMO_PUTC( ppm->streamo, bits ) )
|
||||
return( -1 );
|
||||
|
||||
bits = 0;
|
||||
n_bits = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Flush any remaining bits in this line.
|
||||
*/
|
||||
if( n_bits &&
|
||||
VIPS_STREAMO_PUTC( ppm->streamo, bits ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static int
|
||||
vips_foreign_save_ppm_block( VipsRegion *region, VipsRect *area, void *a )
|
||||
{
|
||||
VipsForeignSavePpm *ppm = (VipsForeignSavePpm *) a;
|
||||
VipsImage *image = region->im;
|
||||
int i;
|
||||
|
||||
for( i = 0; i < area->height; i++ ) {
|
||||
VipsPel *p = VIPS_REGION_ADDR( region, 0, area->top + i );
|
||||
|
||||
if( ppm->fn( ppm, image, p ) )
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static int
|
||||
vips_foreign_save_ppm( VipsForeignSavePpm *ppm, VipsImage *image )
|
||||
{
|
||||
char *magic;
|
||||
char *date;
|
||||
|
||||
magic = "unset";
|
||||
if( image->BandFmt == VIPS_FORMAT_FLOAT &&
|
||||
image->Bands == 3 )
|
||||
magic = "PF";
|
||||
else if( image->BandFmt == VIPS_FORMAT_FLOAT &&
|
||||
image->Bands == 1 )
|
||||
magic = "Pf";
|
||||
else if( image->Bands == 1 &&
|
||||
ppm->ascii &&
|
||||
ppm->squash )
|
||||
magic = "P1";
|
||||
else if( image->Bands == 1 &&
|
||||
ppm->ascii )
|
||||
magic = "P2";
|
||||
else if( image->Bands == 1 &&
|
||||
!ppm->ascii &&
|
||||
ppm->squash )
|
||||
magic = "P4";
|
||||
else if( image->Bands == 1 &&
|
||||
!ppm->ascii )
|
||||
magic = "P5";
|
||||
else if( image->Bands == 3 &&
|
||||
ppm->ascii )
|
||||
magic = "P3";
|
||||
else if( image->Bands == 3 &&
|
||||
!ppm->ascii )
|
||||
magic = "P6";
|
||||
else
|
||||
g_assert_not_reached();
|
||||
|
||||
vips_streamo_writef( ppm->streamo, "%s\n", magic );
|
||||
date = vips__get_iso8601();
|
||||
vips_streamo_writef( ppm->streamo,
|
||||
"#vips2ppm - %s\n", date );
|
||||
g_free( date );
|
||||
vips_streamo_writef( ppm->streamo,
|
||||
"%d %d\n", image->Xsize, image->Ysize );
|
||||
|
||||
if( !ppm->squash )
|
||||
switch( image->BandFmt ) {
|
||||
case VIPS_FORMAT_UCHAR:
|
||||
vips_streamo_writef( ppm->streamo,
|
||||
"%d\n", UCHAR_MAX );
|
||||
break;
|
||||
|
||||
case VIPS_FORMAT_USHORT:
|
||||
vips_streamo_writef( ppm->streamo,
|
||||
"%d\n", USHRT_MAX );
|
||||
break;
|
||||
|
||||
case VIPS_FORMAT_UINT:
|
||||
vips_streamo_writef( ppm->streamo,
|
||||
"%d\n", UINT_MAX );
|
||||
break;
|
||||
|
||||
case VIPS_FORMAT_FLOAT:
|
||||
{
|
||||
double scale;
|
||||
char buf[G_ASCII_DTOSTR_BUF_SIZE];
|
||||
|
||||
if( vips_image_get_double( image,
|
||||
"pfm-scale", &scale ) )
|
||||
scale = 1;
|
||||
if( !vips_amiMSBfirst() )
|
||||
scale *= -1;
|
||||
/* Need to be locale independent.
|
||||
*/
|
||||
g_ascii_dtostr( buf, G_ASCII_DTOSTR_BUF_SIZE, scale );
|
||||
vips_streamo_writes( ppm->streamo, buf );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
if( ppm->squash )
|
||||
ppm->fn = ppm->ascii ?
|
||||
vips_foreign_save_ppm_line_ascii_squash :
|
||||
vips_foreign_save_ppm_line_binary_squash;
|
||||
else
|
||||
ppm->fn = ppm->ascii ?
|
||||
vips_foreign_save_ppm_line_ascii :
|
||||
vips_foreign_save_ppm_line_binary;
|
||||
|
||||
if( vips_sink_disc( image, vips_foreign_save_ppm_block, ppm ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static int
|
||||
vips_foreign_save_ppm_build( VipsObject *object )
|
||||
{
|
||||
VipsForeignSave *save = (VipsForeignSave *) object;
|
||||
VipsForeignSavePpm *ppm = (VipsForeignSavePpm *) object;
|
||||
|
||||
VipsStreamo *streamo;
|
||||
VipsImage *image;
|
||||
|
||||
if( VIPS_OBJECT_CLASS( vips_foreign_save_ppm_parent_class )->
|
||||
build( object ) )
|
||||
return( -1 );
|
||||
|
||||
if( !(streamo = vips_streamo_new_to_filename( ppm->filename )) )
|
||||
return( -1 );
|
||||
if( vips__ppm_save_stream( save->ready, streamo,
|
||||
ppm->ascii, ppm->squash ) ) {
|
||||
VIPS_UNREF( streamo );
|
||||
image = save->ready;
|
||||
if( vips_check_uintorf( "vips2ppm", image ) ||
|
||||
vips_check_bands_1or3( "vips2ppm", image ) ||
|
||||
vips_check_uncoded( "vips2ppm", image ) ||
|
||||
vips_image_pio_input( image ) )
|
||||
return( -1 );
|
||||
|
||||
if( ppm->ascii &&
|
||||
image->BandFmt == VIPS_FORMAT_FLOAT ) {
|
||||
g_warning( "%s",
|
||||
_( "float images must be binary -- disabling ascii" ) );
|
||||
ppm->ascii = FALSE;
|
||||
}
|
||||
VIPS_UNREF( streamo );
|
||||
|
||||
/* One bit images must come from a 8 bit, one band source.
|
||||
*/
|
||||
if( ppm->squash &&
|
||||
(image->Bands != 1 ||
|
||||
image->BandFmt != VIPS_FORMAT_UCHAR) ) {
|
||||
g_warning( "%s",
|
||||
_( "can only squash 1 band uchar images -- "
|
||||
"disabling squash" ) );
|
||||
ppm->squash = FALSE;
|
||||
}
|
||||
|
||||
if( vips_foreign_save_ppm( ppm, image ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
@ -114,11 +362,12 @@ vips_foreign_save_ppm_class_init( VipsForeignSavePpmClass *class )
|
||||
VipsForeignClass *foreign_class = (VipsForeignClass *) class;
|
||||
VipsForeignSaveClass *save_class = (VipsForeignSaveClass *) class;
|
||||
|
||||
gobject_class->dispose = vips_foreign_save_ppm_dispose;
|
||||
gobject_class->set_property = vips_object_set_property;
|
||||
gobject_class->get_property = vips_object_get_property;
|
||||
|
||||
object_class->nickname = "ppmsave";
|
||||
object_class->description = _( "save image to ppm file" );
|
||||
object_class->nickname = "ppmsave_base";
|
||||
object_class->description = _( "save to ppm" );
|
||||
object_class->build = vips_foreign_save_ppm_build;
|
||||
|
||||
foreign_class->suffs = vips__ppm_suffs;
|
||||
@ -126,13 +375,6 @@ vips_foreign_save_ppm_class_init( VipsForeignSavePpmClass *class )
|
||||
save_class->saveable = VIPS_SAVEABLE_RGB;
|
||||
save_class->format_table = bandfmt_ppm;
|
||||
|
||||
VIPS_ARG_STRING( class, "filename", 1,
|
||||
_( "Filename" ),
|
||||
_( "Filename to save to" ),
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
G_STRUCT_OFFSET( VipsForeignSavePpm, filename ),
|
||||
NULL );
|
||||
|
||||
VIPS_ARG_BOOL( class, "ascii", 10,
|
||||
_( "ASCII" ),
|
||||
_( "save as ascii" ),
|
||||
@ -146,6 +388,7 @@ vips_foreign_save_ppm_class_init( VipsForeignSavePpmClass *class )
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsForeignSavePpm, squash ),
|
||||
FALSE );
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
@ -153,6 +396,60 @@ vips_foreign_save_ppm_init( VipsForeignSavePpm *ppm )
|
||||
{
|
||||
}
|
||||
|
||||
typedef struct _VipsForeignSavePpmFile {
|
||||
VipsForeignSavePpm parent_object;
|
||||
|
||||
char *filename;
|
||||
} VipsForeignSavePpmFile;
|
||||
|
||||
typedef VipsForeignSavePpmClass VipsForeignSavePpmFileClass;
|
||||
|
||||
G_DEFINE_TYPE( VipsForeignSavePpmFile, vips_foreign_save_ppm_file,
|
||||
vips_foreign_save_ppm_get_type() );
|
||||
|
||||
static int
|
||||
vips_foreign_save_ppm_file_build( VipsObject *object )
|
||||
{
|
||||
VipsForeignSavePpm *ppm = (VipsForeignSavePpm *) object;
|
||||
VipsForeignSavePpmFile *file = (VipsForeignSavePpmFile *) object;
|
||||
|
||||
if( file->filename &&
|
||||
!(ppm->streamo =
|
||||
vips_streamo_new_to_filename( file->filename )) )
|
||||
return( -1 );
|
||||
|
||||
return( VIPS_OBJECT_CLASS( vips_foreign_save_ppm_file_parent_class )->
|
||||
build( object ) );
|
||||
}
|
||||
|
||||
static void
|
||||
vips_foreign_save_ppm_file_class_init( VipsForeignSavePpmFileClass *class )
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||
|
||||
gobject_class->set_property = vips_object_set_property;
|
||||
gobject_class->get_property = vips_object_get_property;
|
||||
|
||||
object_class->nickname = "ppmsave";
|
||||
object_class->description = _( "save image to ppm file" );
|
||||
object_class->build = vips_foreign_save_ppm_file_build;
|
||||
|
||||
VIPS_ARG_STRING( class, "filename", 1,
|
||||
_( "Filename" ),
|
||||
_( "Filename to save to" ),
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
G_STRUCT_OFFSET( VipsForeignSavePpmFile, filename ),
|
||||
NULL );
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
vips_foreign_save_ppm_file_init( VipsForeignSavePpmFile *file )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
#endif /*HAVE_PPM*/
|
||||
|
||||
/**
|
||||
|
@ -506,11 +506,11 @@ getheader( /* get header from file */
|
||||
)
|
||||
{
|
||||
for(;;) {
|
||||
const unsigned char *line;
|
||||
const char *line;
|
||||
|
||||
if( !(line = vips_streamib_get_line( streamib )) )
|
||||
return( -1 );
|
||||
if( strcmp( (char *) line, "" ) == 0 )
|
||||
if( strcmp( line, "" ) == 0 )
|
||||
/* Blank line. We've parsed the header successfully.
|
||||
*/
|
||||
break;
|
||||
@ -725,14 +725,14 @@ int
|
||||
vips__rad_israd( VipsStreami *streami )
|
||||
{
|
||||
VipsStreamib *streamib;
|
||||
const unsigned char *line;
|
||||
const char *line;
|
||||
int result;
|
||||
|
||||
/* Just test that the first line is the magic string.
|
||||
*/
|
||||
streamib = vips_streamib_new( streami );
|
||||
result = (line = vips_streamib_get_line( streamib )) &&
|
||||
strcmp( (char *) line, "#?RADIANCE" ) == 0;
|
||||
strcmp( line, "#?RADIANCE" ) == 0;
|
||||
VIPS_UNREF( streamib );
|
||||
|
||||
return( result );
|
||||
@ -832,7 +832,7 @@ static int
|
||||
rad2vips_get_header( Read *read, VipsImage *out )
|
||||
{
|
||||
VipsInterpretation interpretation;
|
||||
const unsigned char *line;
|
||||
const char *line;
|
||||
int width;
|
||||
int height;
|
||||
int i, j;
|
||||
@ -1082,7 +1082,7 @@ vips2rad_put_header( Write *write )
|
||||
{
|
||||
vips2rad_make_header( write );
|
||||
|
||||
vips_streamo_writef( write->streamo, "#?RADIANCE\n" );
|
||||
vips_streamo_writes( write->streamo, "#?RADIANCE\n" );
|
||||
vips_streamo_writef( write->streamo, "%s%s\n", FMTSTR, write->format );
|
||||
vips_streamo_writef( write->streamo, "%s%e\n", EXPOSSTR, write->expos );
|
||||
vips_streamo_writef( write->streamo,
|
||||
@ -1099,9 +1099,9 @@ vips2rad_put_header( Write *write )
|
||||
write->prims[GRN][CIEX], write->prims[GRN][CIEY],
|
||||
write->prims[BLU][CIEX], write->prims[BLU][CIEY],
|
||||
write->prims[WHT][CIEX], write->prims[WHT][CIEY] );
|
||||
vips_streamo_writef( write->streamo, "\n" );
|
||||
vips_streamo_writef( write->streamo,
|
||||
"%s", resolu2str( resolu_buf, &write->rs ) );
|
||||
vips_streamo_writes( write->streamo, "\n" );
|
||||
vips_streamo_writes( write->streamo,
|
||||
resolu2str( resolu_buf, &write->rs ) );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
@ -297,8 +297,10 @@ int vips_streamib_require( VipsStreamib *streamib, int require );
|
||||
#define VIPS_STREAMIB_PEEK( S ) ((S)->input_buffer + (S)->read_point)
|
||||
#define VIPS_STREAMIB_FETCH( S ) ((S)->input_buffer[(S)->read_point++])
|
||||
|
||||
const unsigned char *vips_streamib_get_line( VipsStreamib *streamib );
|
||||
unsigned char *vips_streamib_get_line_copy( VipsStreamib *streamib );
|
||||
const char *vips_streamib_get_line( VipsStreamib *streamib );
|
||||
char *vips_streamib_get_line_copy( VipsStreamib *streamib );
|
||||
const char *vips_streamib_get_non_whitespace( VipsStreamib *streamib );
|
||||
int vips_streamib_skip_whitespace( VipsStreamib *streamib );
|
||||
|
||||
#define VIPS_TYPE_STREAMIW (vips_streamiw_get_type())
|
||||
#define VIPS_STREAMIW( obj ) \
|
||||
@ -400,13 +402,12 @@ int vips_streamo_write( VipsStreamo *streamo, const void *data, size_t length );
|
||||
void vips_streamo_finish( VipsStreamo *streamo );
|
||||
|
||||
int vips_streamo_putc( VipsStreamo *streamo, int ch );
|
||||
|
||||
#define VIPS_STREAMO_PUTC( S, C ) ( \
|
||||
(S)->write_point <= VIPS_STREAMO_BUFFER_SIZE ? \
|
||||
((S)->output_buffer[(S)->write_point++] = (C), 0) : \
|
||||
vips_streamo_putc( (S), (C) ) \
|
||||
)
|
||||
|
||||
int vips_streamo_writes( VipsStreamo *streamo, const char *str );
|
||||
int vips_streamo_writef( VipsStreamo *streamo, const char *fmt, ... )
|
||||
__attribute__((format(printf, 2, 3)));
|
||||
|
||||
|
@ -344,6 +344,8 @@ guint32 vips__random_add( guint32 seed, int value );
|
||||
const char *vips__icc_dir( void );
|
||||
const char *vips__windows_prefix( void );
|
||||
|
||||
char *vips__get_iso8601( void );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /*__cplusplus*/
|
||||
|
@ -47,6 +47,7 @@
|
||||
#include <vips/intl.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
@ -326,11 +327,11 @@ vips_streamib_require( VipsStreamib *streamib, int require )
|
||||
* slower vips_streamib_get_line_copy().
|
||||
*
|
||||
* The return value is owned by @streamib and must not be freed. It
|
||||
* is valid until the next call to vips_streamib_get_line().
|
||||
* is valid until the next get call @streamib.
|
||||
*
|
||||
* Returns: the next line from the file, or NULL on EOF or read error.
|
||||
* Returns: the next line of text, or NULL on EOF or read error.
|
||||
*/
|
||||
const unsigned char *
|
||||
const char *
|
||||
vips_streamib_get_line( VipsStreamib *streamib )
|
||||
{
|
||||
int write_point;
|
||||
@ -379,7 +380,7 @@ vips_streamib_get_line( VipsStreamib *streamib )
|
||||
|
||||
VIPS_DEBUG_MSG( " %s\n", streamib->line );
|
||||
|
||||
return( streamib->line );
|
||||
return( (const char *) streamib->line );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -395,9 +396,9 @@ vips_streamib_get_line( VipsStreamib *streamib )
|
||||
* This is slower than vips_streamib_get_line(), but can work with lines of
|
||||
* any length.
|
||||
*
|
||||
* Returns: the next line from the file, or NULL on EOF or read error.
|
||||
* Returns: the next line of text, or NULL on EOF or read error.
|
||||
*/
|
||||
unsigned char *
|
||||
char *
|
||||
vips_streamib_get_line_copy( VipsStreamib *streamib )
|
||||
{
|
||||
static const unsigned char null = '\0';
|
||||
@ -406,7 +407,7 @@ vips_streamib_get_line_copy( VipsStreamib *streamib )
|
||||
|
||||
GByteArray *buffer;
|
||||
int ch;
|
||||
unsigned char *result;
|
||||
char *result;
|
||||
|
||||
buffer = g_byte_array_new();
|
||||
|
||||
@ -435,9 +436,87 @@ vips_streamib_get_line_copy( VipsStreamib *streamib )
|
||||
|
||||
g_byte_array_append( buffer, &null, 1 );
|
||||
|
||||
result = (unsigned char *) g_byte_array_free( buffer, FALSE );
|
||||
result = (char *) g_byte_array_free( buffer, FALSE );
|
||||
|
||||
VIPS_DEBUG_MSG( " %s\n", result );
|
||||
|
||||
return( result );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_streamib_get_non_whitespace:
|
||||
* @streamib: stream to operate on
|
||||
*
|
||||
* Fetch the next chunk of non-whitespace text from the stream, and
|
||||
* null-terminate it.
|
||||
*
|
||||
* After this, the next getc will be the first char of the next block of
|
||||
* whitespace (or EOF).
|
||||
*
|
||||
* If the first getc is whitespace, stop instantly and return the empty
|
||||
* string.
|
||||
*
|
||||
* If the item is longer than some arbitrary (but large) limit, it is
|
||||
* truncated.
|
||||
*
|
||||
* The return value is owned by @streamib and must not be freed. It
|
||||
* is valid until the next get call @streamib.
|
||||
*
|
||||
* Returns: the next block of non-whitespace, or NULL on EOF or read error.
|
||||
*/
|
||||
const char *
|
||||
vips_streamib_get_non_whitespace( VipsStreamib *streamib )
|
||||
{
|
||||
int ch;
|
||||
int i;
|
||||
|
||||
for( i = 0; i < VIPS_STREAMIB_BUFFER_SIZE &&
|
||||
!isspace( ch = VIPS_STREAMIB_GETC( streamib ) ) &&
|
||||
ch != EOF; i++ )
|
||||
streamib->line[i] = ch;
|
||||
streamib->line[i] = '\0';
|
||||
|
||||
/* If we stopped before seeing any whitespace, skip to the end of the
|
||||
* block of non-whitespace.
|
||||
*/
|
||||
if( !isspace( ch ) )
|
||||
while( !isspace( ch = VIPS_STREAMIB_GETC( streamib ) ) &&
|
||||
ch != EOF )
|
||||
;
|
||||
|
||||
/* If we finally stopped on whitespace, step back one so the next get
|
||||
* will be whitespace (or EOF).
|
||||
*/
|
||||
if( isspace( ch ) )
|
||||
VIPS_STREAMIB_UNGETC( streamib );
|
||||
|
||||
return( (const char *) streamib->line );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_streamib_skip_whitespace:
|
||||
* @streamib: stream to operate on
|
||||
*
|
||||
* After this, the next getc will be the first char of the next block of
|
||||
* non-whitespace (or EOF).
|
||||
*
|
||||
* Returns: 0 on success, -1 on error.
|
||||
*/
|
||||
int
|
||||
vips_streamib_skip_whitespace( VipsStreamib *streamib )
|
||||
{
|
||||
int ch;
|
||||
|
||||
while( isspace( ch = VIPS_STREAMIB_GETC( streamib ) ) )
|
||||
;
|
||||
VIPS_STREAMIB_UNGETC( streamib );
|
||||
|
||||
/* # skip comments too.
|
||||
*/
|
||||
if( ch == '#' &&
|
||||
(!vips_streamib_get_line( streamib ) ||
|
||||
vips_streamib_skip_whitespace( streamib )) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
@ -402,35 +402,6 @@ vips_streamo_finish( VipsStreamo *streamo )
|
||||
class->finish( streamo );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_streamo_writef:
|
||||
* @streamo: output stream to operate on
|
||||
* @fmt: <function>printf()</function>-style format string
|
||||
* @...: arguments to format string
|
||||
*
|
||||
* Format the string and write to @streamo.
|
||||
*
|
||||
* Returns: 0 on success, and -1 on error.
|
||||
*/
|
||||
int
|
||||
vips_streamo_writef( VipsStreamo *streamo, const char *fmt, ... )
|
||||
{
|
||||
va_list ap;
|
||||
char *line;
|
||||
int result;
|
||||
|
||||
va_start( ap, fmt );
|
||||
line = g_strdup_vprintf( fmt, ap );
|
||||
va_end( ap );
|
||||
|
||||
result = vips_streamo_write( streamo,
|
||||
(unsigned char *) line, strlen( line ) );
|
||||
|
||||
g_free( line );
|
||||
|
||||
return( result );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_streamo_putc:
|
||||
* @streamo: output stream to operate on
|
||||
@ -455,6 +426,50 @@ vips_streamo_putc( VipsStreamo *streamo, int ch )
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_streamo_writes:
|
||||
* @streamo: output stream to operate on
|
||||
* @str: string to write
|
||||
*
|
||||
* Write a null-terminated string to @streamo.
|
||||
*
|
||||
* Returns: 0 on success, and -1 on error.
|
||||
*/
|
||||
int
|
||||
vips_streamo_writes( VipsStreamo *streamo, const char *str )
|
||||
{
|
||||
return( vips_streamo_write( streamo,
|
||||
(unsigned char *) str, strlen( str ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_streamo_writef:
|
||||
* @streamo: output stream to operate on
|
||||
* @fmt: <function>printf()</function>-style format string
|
||||
* @...: arguments to format string
|
||||
*
|
||||
* Format the string and write to @streamo.
|
||||
*
|
||||
* Returns: 0 on success, and -1 on error.
|
||||
*/
|
||||
int
|
||||
vips_streamo_writef( VipsStreamo *streamo, const char *fmt, ... )
|
||||
{
|
||||
va_list ap;
|
||||
char *line;
|
||||
int result;
|
||||
|
||||
va_start( ap, fmt );
|
||||
line = g_strdup_vprintf( fmt, ap );
|
||||
va_end( ap );
|
||||
|
||||
result = vips_streamo_writes( streamo, line );
|
||||
|
||||
g_free( line );
|
||||
|
||||
return( result );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_streamo_write_amp:
|
||||
* @streamo: output stream to operate on
|
||||
|
@ -2024,3 +2024,28 @@ vips__windows_prefix( void )
|
||||
return( (const char *) g_once( &once,
|
||||
(GThreadFunc) vips__windows_prefix_once, NULL ) );
|
||||
}
|
||||
|
||||
char *
|
||||
vips__get_iso8601( void )
|
||||
{
|
||||
char *date;
|
||||
|
||||
#ifdef HAVE_DATE_TIME_FORMAT_ISO8601
|
||||
{
|
||||
GDateTime *now;
|
||||
|
||||
now = g_date_time_new_now_local();
|
||||
date = g_date_time_format_iso8601( now );
|
||||
g_date_time_unref( now );
|
||||
}
|
||||
#else /*!HAVE_DATE_TIME_FORMAT_ISO8601*/
|
||||
{
|
||||
GTimeVal now;
|
||||
|
||||
g_get_current_time( &now );
|
||||
date = g_time_val_to_iso8601( &now );
|
||||
}
|
||||
#endif /*HAVE_DATE_TIME_FORMAT_ISO8601*/
|
||||
|
||||
return( date );
|
||||
}
|
||||
|
@ -957,22 +957,7 @@ vips__xml_properties( VipsImage *image )
|
||||
VipsDbuf dbuf;
|
||||
char *date;
|
||||
|
||||
#ifdef HAVE_DATE_TIME_FORMAT_ISO8601
|
||||
{
|
||||
GDateTime *now;
|
||||
|
||||
now = g_date_time_new_now_local();
|
||||
date = g_date_time_format_iso8601( now );
|
||||
g_date_time_unref( now );
|
||||
}
|
||||
#else /*!HAVE_DATE_TIME_FORMAT_ISO8601*/
|
||||
{
|
||||
GTimeVal now;
|
||||
|
||||
g_get_current_time( &now );
|
||||
date = g_time_val_to_iso8601( &now );
|
||||
}
|
||||
#endif /*HAVE_DATE_TIME_FORMAT_ISO8601*/
|
||||
date = vips__get_iso8601();
|
||||
|
||||
vips_dbuf_init( &dbuf );
|
||||
vips_dbuf_writef( &dbuf, "<?xml version=\"1.0\"?>\n" );
|
||||
|
Loading…
x
Reference in New Issue
Block a user