stuff
This commit is contained in:
parent
6a745c5264
commit
c6418893eb
@ -35,6 +35,8 @@
|
||||
- im_max()/im_min() are now convenience functions
|
||||
- im_maxpos_avg() handles complex and multi-band images
|
||||
- added im_point(), rewrite im_point_bilinear() in terms of this
|
||||
- close callbacks now happen *after* images have closed resources (such as
|
||||
open files) ... this lets them delete temps and stuff. Expect breakage :(
|
||||
- added vips_interpolate_get_window_offset()
|
||||
|
||||
25/3/09 started 7.18.0
|
||||
|
44
TODO
44
TODO
@ -1,4 +1,48 @@
|
||||
- look at im_remainderconst_vec()
|
||||
|
||||
put that functionality into something like im__cast_and_call(), then share
|
||||
with im_andimage_const_vec()
|
||||
|
||||
working in im__arith_binary_const()
|
||||
|
||||
|
||||
- experimenting with
|
||||
|
||||
png_set_shift( read->pPng, 2 );
|
||||
|
||||
in im_png2vips.c
|
||||
|
||||
test image in gmail
|
||||
|
||||
|
||||
- Joe's new def
|
||||
|
||||
|
||||
- we have im_andimage(), but im_and_vec(), argh
|
||||
|
||||
shouldn't it be im_andimageconst_vec()? won't we have C++ problems the way
|
||||
things are?
|
||||
|
||||
|
||||
|
||||
Something like:
|
||||
|
||||
const char *im_system_image( IMAGE *in, const char *command, char **log );
|
||||
|
||||
Actions:
|
||||
|
||||
- create two empty temporary files
|
||||
- write the image to the first
|
||||
- call system() on the expanded command
|
||||
- capture stdout/stderr into log
|
||||
- delete the temp input file
|
||||
- return the output filename, or NULL if the command failed (log is still
|
||||
returned in this case)
|
||||
|
||||
The caller would open the output file, either with im_open(), or with it's
|
||||
own system (nip2 has it's own open file thing to give progress feedback and
|
||||
use disc for format conversion), and be responsible for deleting the temp
|
||||
output file at some point.
|
||||
|
||||
|
||||
- 1-bit PNG read is broken?
|
||||
|
@ -44,9 +44,7 @@
|
||||
|
||||
/**
|
||||
* SECTION: arithmetic
|
||||
* @short_description: operations which perform pixel arithmetic, trig, log,
|
||||
* statistics
|
||||
*
|
||||
* @short_description: operations which perform pixel arithmetic, trig, log, statistics
|
||||
* @see_also: <link linkend="VIPS-iofuncs">iofuncs</link>
|
||||
* @stability: Stable
|
||||
* @include: vips/vips.h
|
||||
|
@ -25,6 +25,9 @@
|
||||
* - im__cast_and_call() no longer sets bbits for you
|
||||
* - add gtkdoc comments
|
||||
* - remove separate complex case, just double size
|
||||
* 11/9/09
|
||||
* - im__cast_and_call() becomes im__arith_binary()
|
||||
* - more of operation scaffold moved inside
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -151,7 +154,7 @@ static int bandfmt_largest[6][6] = {
|
||||
|
||||
/* For two formats, find one which can represent the full range of both.
|
||||
*/
|
||||
VipsBandFmt
|
||||
static VipsBandFmt
|
||||
im__format_common( IMAGE *in1, IMAGE *in2 )
|
||||
{
|
||||
if( im_iscomplex( in1 ) || im_iscomplex( in2 ) ) {
|
||||
@ -206,16 +209,43 @@ im__bandup( IMAGE *in, IMAGE *out, int n )
|
||||
return( im_gbandjoin( bands, out, n ) );
|
||||
}
|
||||
|
||||
/* Cast in1 and in2 up to a common type and number of bands, then call the
|
||||
* function. Also used by subtract, multiply, divide, etc.
|
||||
/* The common part of most binary arithmetic, relational and boolean
|
||||
* operators. We:
|
||||
*
|
||||
* - check in and out
|
||||
* - cast in1 and in2 up to a common format
|
||||
* - cast the common format to the output format with the supplied table
|
||||
* - equalise bands
|
||||
* - run the supplied buffer operation
|
||||
*/
|
||||
int
|
||||
im__cast_and_call( IMAGE *in1, IMAGE *in2, IMAGE *out,
|
||||
im__arith_binary( const char *name,
|
||||
IMAGE *in1, IMAGE *in2, IMAGE *out,
|
||||
int format_table[10],
|
||||
im_wrapmany_fn fn, void *a )
|
||||
{
|
||||
VipsBandFmt fmt;
|
||||
IMAGE *t[5];
|
||||
|
||||
if( im_piocheck( in1, out ) ||
|
||||
im_pincheck( in2 ) ||
|
||||
im_check_bands_1orn( name, in1, in2 ) ||
|
||||
im_check_uncoded( name, in1 ) ||
|
||||
im_check_uncoded( name, in2 ) )
|
||||
return( -1 );
|
||||
|
||||
if( im_cp_descv( out, in1, in2, NULL ) )
|
||||
return( -1 );
|
||||
|
||||
/* What number of bands will we write?
|
||||
*/
|
||||
out->Bands = IM_MAX( in1->Bands, in2->Bands );
|
||||
|
||||
/* What output type will we write? int, float or complex.
|
||||
*/
|
||||
out->BandFmt = format_table[im__format_common( in1, in2 )];
|
||||
out->Bbits = im_bits_of_fmt( out->BandFmt );
|
||||
|
||||
if( im_open_local_array( out, t, 4, "type cast:1", "p" ) )
|
||||
return( -1 );
|
||||
|
||||
@ -331,33 +361,9 @@ static int bandfmt_add[10] = {
|
||||
*/
|
||||
int
|
||||
im_add( IMAGE *in1, IMAGE *in2, IMAGE *out )
|
||||
{
|
||||
if( im_piocheck( in1, out ) ||
|
||||
im_pincheck( in2 ) ||
|
||||
im_check_bands_1orn( "im_add", in1, in2 ) ||
|
||||
im_check_uncoded( "im_add", in1 ) ||
|
||||
im_check_uncoded( "im_add", in2 ) )
|
||||
return( -1 );
|
||||
|
||||
if( im_cp_descv( out, in1, in2, NULL ) )
|
||||
return( -1 );
|
||||
|
||||
/* What number of bands will we write?
|
||||
*/
|
||||
out->Bands = IM_MAX( in1->Bands, in2->Bands );
|
||||
|
||||
/* What output type will we write? int, float or complex.
|
||||
*/
|
||||
out->BandFmt = bandfmt_add[im__format_common( in1, in2 )];
|
||||
out->Bbits = im_bits_of_fmt( out->BandFmt );
|
||||
|
||||
/* And process!
|
||||
*/
|
||||
if( im__cast_and_call( in1, in2, out,
|
||||
(im_wrapmany_fn) add_buffer, NULL ) )
|
||||
return( -1 );
|
||||
|
||||
/* Success!
|
||||
*/
|
||||
return( 0 );
|
||||
{
|
||||
return( im__arith_binary( "im_add",
|
||||
in1, in2, out,
|
||||
bandfmt_add,
|
||||
(im_wrapmany_fn) add_buffer, NULL ) );
|
||||
}
|
||||
|
@ -271,32 +271,8 @@ static int bandfmt_divide[10] = {
|
||||
int
|
||||
im_divide( IMAGE *in1, IMAGE *in2, IMAGE *out )
|
||||
{
|
||||
if( im_piocheck( in1, out ) ||
|
||||
im_pincheck( in2 ) ||
|
||||
im_check_bands_1orn( "im_divide", in1, in2 ) ||
|
||||
im_check_uncoded( "im_divide", in1 ) ||
|
||||
im_check_uncoded( "im_divide", in2 ) )
|
||||
return( -1 );
|
||||
|
||||
if( im_cp_descv( out, in1, in2, NULL ) )
|
||||
return( -1 );
|
||||
|
||||
/* What number of bands will we write?
|
||||
*/
|
||||
out->Bands = IM_MAX( in1->Bands, in2->Bands );
|
||||
|
||||
/* What output type will we write? int, float or complex.
|
||||
*/
|
||||
out->BandFmt = bandfmt_divide[im__format_common( in1, in2 )];
|
||||
out->Bbits = im_bits_of_fmt( out->BandFmt );
|
||||
|
||||
/* And process!
|
||||
*/
|
||||
if( im__cast_and_call( in1, in2, out,
|
||||
(im_wrapmany_fn) divide_buffer, NULL ) )
|
||||
return( -1 );
|
||||
|
||||
/* Success!
|
||||
*/
|
||||
return( 0 );
|
||||
return( im__arith_binary( "im_divide",
|
||||
in1, in2, out,
|
||||
bandfmt_divide,
|
||||
(im_wrapmany_fn) divide_buffer, NULL ) );
|
||||
}
|
||||
|
@ -246,32 +246,8 @@ static int bandfmt_multiply[10] = {
|
||||
int
|
||||
im_multiply( IMAGE *in1, IMAGE *in2, IMAGE *out )
|
||||
{
|
||||
if( im_piocheck( in1, out ) ||
|
||||
im_pincheck( in2 ) ||
|
||||
im_check_bands_1orn( "im_multiply", in1, in2 ) ||
|
||||
im_check_uncoded( "im_multiply", in1 ) ||
|
||||
im_check_uncoded( "im_multiply", in2 ) )
|
||||
return( -1 );
|
||||
|
||||
if( im_cp_descv( out, in1, in2, NULL ) )
|
||||
return( -1 );
|
||||
|
||||
/* What number of bands will we write?
|
||||
*/
|
||||
out->Bands = IM_MAX( in1->Bands, in2->Bands );
|
||||
|
||||
/* What output type will we write? int, float or complex.
|
||||
*/
|
||||
out->BandFmt = bandfmt_multiply[im__format_common( in1, in2 )];
|
||||
out->Bbits = im_bits_of_fmt( out->BandFmt );
|
||||
|
||||
/* And process!
|
||||
*/
|
||||
if( im__cast_and_call( in1, in2, out,
|
||||
(im_wrapmany_fn) multiply_buffer, NULL ) )
|
||||
return( -1 );
|
||||
|
||||
/* Success!
|
||||
*/
|
||||
return( 0 );
|
||||
return( im__arith_binary( "im_multiply",
|
||||
in1, in2, out,
|
||||
bandfmt_multiply,
|
||||
(im_wrapmany_fn) multiply_buffer, NULL ) );
|
||||
}
|
||||
|
@ -160,39 +160,85 @@ static int bandfmt_remainder[10] = {
|
||||
*/
|
||||
int
|
||||
im_remainder( IMAGE *in1, IMAGE *in2, IMAGE *out )
|
||||
{
|
||||
if( im_piocheck( in1, out ) ||
|
||||
im_pincheck( in2 ) ||
|
||||
im_check_bands_1orn( "im_remainder", in1, in2 ) ||
|
||||
im_check_uncoded( "im_remainder", in1 ) ||
|
||||
im_check_uncoded( "im_remainder", in2 ) ||
|
||||
im_check_noncomplex( "im_remainder", in1 ) ||
|
||||
im_check_noncomplex( "im_remainder", in2 ) )
|
||||
{
|
||||
return( im__arith_binary( "im_remainder",
|
||||
in1, in2, out,
|
||||
bandfmt_remainder,
|
||||
(im_wrapmany_fn) remainder_buffer, NULL ) );
|
||||
}
|
||||
|
||||
/* Cast a vector of double to a vector of TYPE.
|
||||
*/
|
||||
#define CAST( TYPE ) { \
|
||||
TYPE *tq = (TYPE *) q; \
|
||||
\
|
||||
for( i = 0; i < n; i++ ) \
|
||||
tq[i] = (TYPE) p[i]; \
|
||||
}
|
||||
|
||||
/* Make a pixel of output type from a realvec.
|
||||
*/
|
||||
static PEL *
|
||||
make_pixel( IMAGE *out, int n, double *p )
|
||||
{
|
||||
PEL *q;
|
||||
int i;
|
||||
|
||||
g_assert( n == out->Bands );
|
||||
|
||||
if( !(q = IM_ARRAY( out, IM_IMAGE_SIZEOF_PEL( out ), PEL )) )
|
||||
return( NULL );
|
||||
|
||||
switch( out->BandFmt ) {
|
||||
case IM_BANDFMT_CHAR: CAST( signed char ); break;
|
||||
case IM_BANDFMT_UCHAR: CAST( unsigned char ); break;
|
||||
case IM_BANDFMT_SHORT: CAST( signed short ); break;
|
||||
case IM_BANDFMT_USHORT: CAST( unsigned short ); break;
|
||||
case IM_BANDFMT_INT: CAST( signed int ); break;
|
||||
case IM_BANDFMT_UINT: CAST( unsigned int ); break;
|
||||
|
||||
default:
|
||||
g_assert( 0 );
|
||||
}
|
||||
|
||||
return( q );
|
||||
}
|
||||
|
||||
int
|
||||
im__arith_binary_const( const char *name,
|
||||
IMAGE *in, IMAGE *out, int n, double *c,
|
||||
int format_table[10],
|
||||
im_wrapone_fn fn, void *a )
|
||||
{
|
||||
int i;
|
||||
PEL *vector;
|
||||
|
||||
if( im_piocheck( in, out ) ||
|
||||
im_check_vector( name, n, in ) ||
|
||||
im_check_uncoded( name, in ) )
|
||||
return( -1 );
|
||||
|
||||
if( im_cp_descv( out, in1, in2, NULL ) )
|
||||
if( im_cp_desc( out, in ) )
|
||||
return( -1 );
|
||||
|
||||
/* What number of bands will we write?
|
||||
*/
|
||||
out->Bands = IM_MAX( in1->Bands, in2->Bands );
|
||||
|
||||
/* What output type will we write? Same as LHS type.
|
||||
*/
|
||||
out->BandFmt = bandfmt_remainder[im__format_common( in1, in2 )];
|
||||
out->BandFmt = format_table[in->BandFmt];
|
||||
out->Bbits = im_bits_of_fmt( out->BandFmt );
|
||||
|
||||
/* And process!
|
||||
/* Cast vector to output type.
|
||||
*/
|
||||
if( im__cast_and_call( in1, in2, out,
|
||||
(im_wrapmany_fn) remainder_buffer, NULL ) )
|
||||
|
||||
/*
|
||||
need to handle case where vector == 1 but bands == (eg.) 3
|
||||
*/
|
||||
|
||||
if( !(vector = make_pixel( out, n, c )) )
|
||||
return( -1 );
|
||||
|
||||
if( im_wrapone( in, out, fn, a, vector ) )
|
||||
return( -1 );
|
||||
|
||||
/* Success!
|
||||
*/
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
|
||||
/* Parameters saved here.
|
||||
*/
|
||||
typedef struct _Remainderconst {
|
||||
|
@ -238,32 +238,8 @@ static int bandfmt_subtract[10] = {
|
||||
int
|
||||
im_subtract( IMAGE *in1, IMAGE *in2, IMAGE *out )
|
||||
{
|
||||
if( im_piocheck( in1, out ) ||
|
||||
im_pincheck( in2 ) ||
|
||||
im_check_bands_1orn( "im_subtract", in1, in2 ) ||
|
||||
im_check_uncoded( "im_subtract", in1 ) ||
|
||||
im_check_uncoded( "im_subtract", in2 ) )
|
||||
return( -1 );
|
||||
|
||||
if( im_cp_descv( out, in1, in2, NULL ) )
|
||||
return( -1 );
|
||||
|
||||
/* What number of bands will we write?
|
||||
*/
|
||||
out->Bands = IM_MAX( in1->Bands, in2->Bands );
|
||||
|
||||
/* What output type will we write? int, float or complex.
|
||||
*/
|
||||
out->BandFmt = bandfmt_subtract[im__format_common( in1, in2 )];
|
||||
out->Bbits = im_bits_of_fmt( out->BandFmt );
|
||||
|
||||
/* And process!
|
||||
*/
|
||||
if( im__cast_and_call( in1, in2, out,
|
||||
(im_wrapmany_fn) subtract_buffer, NULL ) )
|
||||
return( -1 );
|
||||
|
||||
/* Success!
|
||||
*/
|
||||
return( 0 );
|
||||
return( im__arith_binary( "im_subtract",
|
||||
in1, in2, out,
|
||||
bandfmt_subtract,
|
||||
(im_wrapmany_fn) subtract_buffer, NULL ) );
|
||||
}
|
||||
|
@ -40,6 +40,9 @@
|
||||
* layer if operator names are turned on
|
||||
* 30/6/04
|
||||
* - now cast float/complex args to int
|
||||
* 11/9/09
|
||||
* - use new im__cast_and__call()
|
||||
* - therefore now supports 1-band $op n-band
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -75,7 +78,6 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <vips/vips.h>
|
||||
|
||||
@ -83,102 +85,13 @@
|
||||
#include <dmalloc.h>
|
||||
#endif /*WITH_DMALLOC*/
|
||||
|
||||
/* Save a bit of typing.
|
||||
*/
|
||||
#define UC IM_BANDFMT_UCHAR
|
||||
#define C IM_BANDFMT_CHAR
|
||||
#define US IM_BANDFMT_USHORT
|
||||
#define S IM_BANDFMT_SHORT
|
||||
#define UI IM_BANDFMT_UINT
|
||||
#define I IM_BANDFMT_INT
|
||||
#define F IM_BANDFMT_FLOAT
|
||||
#define M IM_BANDFMT_COMPLEX
|
||||
#define D IM_BANDFMT_DOUBLE
|
||||
#define DM IM_BANDFMT_DPCOMPLEX
|
||||
|
||||
/* Type conversions for boolean.
|
||||
*/
|
||||
static int iformat[10][10] = {
|
||||
/* UC C US S UI I F M D DM */
|
||||
/* UC */ { UC, C, US, S, UI, I, I, I, I, I },
|
||||
/* C */ { C, C, S, S, I, I, I, I, I, I },
|
||||
/* US */ { US, S, US, S, UI, I, I, I, I, I },
|
||||
/* S */ { S, S, S, S, I, I, I, I, I, I },
|
||||
/* UI */ { UI, I, UI, I, UI, I, I, I, I, I },
|
||||
/* I */ { I, I, I, I, I, I, I, I, I, I },
|
||||
/* F */ { I, I, I, I, I, I, I, I, I, I },
|
||||
/* M */ { I, I, I, I, I, I, I, I, I, I },
|
||||
/* D */ { I, I, I, I, I, I, I, I, I, I },
|
||||
/* DM */ { I, I, I, I, I, I, I, I, I, I }
|
||||
};
|
||||
|
||||
/* Check args. Cast inputs to matching integer format.
|
||||
*/
|
||||
static int
|
||||
check( IMAGE **in, IMAGE *out )
|
||||
{
|
||||
int i, n;
|
||||
int fmt;
|
||||
|
||||
/* Count args.
|
||||
*/
|
||||
for( n = 0; in[n]; n++ ) {
|
||||
if( in[n]->Coding != IM_CODING_NONE ) {
|
||||
im_error( "boolean",
|
||||
"%s", _( "uncoded images only" ) );
|
||||
return( -1 );
|
||||
}
|
||||
}
|
||||
|
||||
/* Check sizes match.
|
||||
*/
|
||||
for( i = 1; i < n; i++ )
|
||||
if( in[0]->Bands != in[i]->Bands ||
|
||||
in[0]->Xsize != in[i]->Xsize ||
|
||||
in[0]->Ysize != in[i]->Ysize ) {
|
||||
im_error( "boolean",
|
||||
"%s", _( "images differ in size" ) );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
/* Calculate type conversion ... just 1ary and 2ary.
|
||||
*/
|
||||
switch( n ) {
|
||||
case 1:
|
||||
fmt = iformat[0][in[0]->BandFmt];
|
||||
break;
|
||||
|
||||
case 2:
|
||||
fmt = iformat[in[1]->BandFmt][in[0]->BandFmt];
|
||||
break;
|
||||
|
||||
default:
|
||||
assert( FALSE );
|
||||
}
|
||||
|
||||
for( i = 0; i < n; i++ ) {
|
||||
IMAGE *t = im_open_local( out, "check-1", "p" );
|
||||
|
||||
if( !t || im_clip2fmt( in[i], t, fmt ) )
|
||||
return( -1 );
|
||||
in[i] = t;
|
||||
}
|
||||
|
||||
/* Prepare the output image.
|
||||
*/
|
||||
if( im_cp_desc_array( out, in ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/* A selection of main loops. As with im_add(), only implement monotype
|
||||
* operations. TYPE is some integer type, signed or unsigned.
|
||||
/* A selection of main loops. Only implement monotype operations, ie. input
|
||||
* type == output type. Float types are cast to int before we come here.
|
||||
*/
|
||||
#define AND2( TYPE ) { \
|
||||
TYPE *tq = (TYPE *) q; \
|
||||
TYPE *tp1 = (TYPE *) p1; \
|
||||
TYPE *tp2 = (TYPE *) p2; \
|
||||
TYPE *tp1 = (TYPE *) p[0]; \
|
||||
TYPE *tp2 = (TYPE *) p[1]; \
|
||||
\
|
||||
for( x = 0; x < ne; x++ ) \
|
||||
tq[x] = tp1[x] & tp2[x]; \
|
||||
@ -186,8 +99,8 @@ check( IMAGE **in, IMAGE *out )
|
||||
|
||||
#define OR2( TYPE ) { \
|
||||
TYPE *tq = (TYPE *) q; \
|
||||
TYPE *tp1 = (TYPE *) p1; \
|
||||
TYPE *tp2 = (TYPE *) p2; \
|
||||
TYPE *tp1 = (TYPE *) p[0]; \
|
||||
TYPE *tp2 = (TYPE *) p[1]; \
|
||||
\
|
||||
for( x = 0; x < ne; x++ ) \
|
||||
tq[x] = tp1[x] | tp2[x]; \
|
||||
@ -195,8 +108,8 @@ check( IMAGE **in, IMAGE *out )
|
||||
|
||||
#define EOR2( TYPE ) { \
|
||||
TYPE *tq = (TYPE *) q; \
|
||||
TYPE *tp1 = (TYPE *) p1; \
|
||||
TYPE *tp2 = (TYPE *) p2; \
|
||||
TYPE *tp1 = (TYPE *) p[0]; \
|
||||
TYPE *tp2 = (TYPE *) p[1]; \
|
||||
\
|
||||
for( x = 0; x < ne; x++ ) \
|
||||
tq[x] = tp1[x] ^ tp2[x]; \
|
||||
@ -237,11 +150,9 @@ check( IMAGE **in, IMAGE *out )
|
||||
static void
|
||||
and_buffer( PEL **p, PEL *q, int n, IMAGE *im )
|
||||
{
|
||||
const int ne = n * im->Bands;
|
||||
|
||||
int x;
|
||||
int bands = im->Bands;
|
||||
int ne = n * bands;
|
||||
PEL *p1 = p[0];
|
||||
PEL *p2 = p[1];
|
||||
|
||||
switch( im->BandFmt ) {
|
||||
case IM_BANDFMT_CHAR: AND2( signed char ); break;
|
||||
@ -252,20 +163,18 @@ and_buffer( PEL **p, PEL *q, int n, IMAGE *im )
|
||||
case IM_BANDFMT_UINT: AND2( unsigned int ); break;
|
||||
|
||||
default:
|
||||
error_exit( "im_and: internal error" );
|
||||
g_assert( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
or_buffer( PEL **p, PEL *q, int n, IMAGE *in1 )
|
||||
or_buffer( PEL **p, PEL *q, int n, IMAGE *im )
|
||||
{
|
||||
int x;
|
||||
int bands = in1->Bands;
|
||||
int ne = n * bands;
|
||||
PEL *p1 = p[0];
|
||||
PEL *p2 = p[1];
|
||||
const int ne = n * im->Bands;
|
||||
|
||||
switch( in1->BandFmt ) {
|
||||
int x;
|
||||
|
||||
switch( im->BandFmt ) {
|
||||
case IM_BANDFMT_CHAR: OR2( signed char ); break;
|
||||
case IM_BANDFMT_UCHAR: OR2( unsigned char ); break;
|
||||
case IM_BANDFMT_SHORT: OR2( signed short ); break;
|
||||
@ -274,20 +183,18 @@ or_buffer( PEL **p, PEL *q, int n, IMAGE *in1 )
|
||||
case IM_BANDFMT_UINT: OR2( unsigned int ); break;
|
||||
|
||||
default:
|
||||
error_exit( "im_or: internal error" );
|
||||
g_assert( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
eor_buffer( PEL **p, PEL *q, int n, IMAGE *in1 )
|
||||
{
|
||||
int x;
|
||||
int bands = in1->Bands;
|
||||
int ne = n * bands;
|
||||
PEL *p1 = p[0];
|
||||
PEL *p2 = p[1];
|
||||
const int ne = n * im->Bands;
|
||||
|
||||
switch( in1->BandFmt ) {
|
||||
int x;
|
||||
|
||||
switch( im->BandFmt ) {
|
||||
case IM_BANDFMT_CHAR: EOR2( signed char ); break;
|
||||
case IM_BANDFMT_UCHAR: EOR2( unsigned char ); break;
|
||||
case IM_BANDFMT_SHORT: EOR2( signed short ); break;
|
||||
@ -296,7 +203,7 @@ eor_buffer( PEL **p, PEL *q, int n, IMAGE *in1 )
|
||||
case IM_BANDFMT_UINT: EOR2( unsigned int ); break;
|
||||
|
||||
default:
|
||||
error_exit( "im_eor: internal error" );
|
||||
g_assert( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
@ -315,7 +222,7 @@ andconst_buffer( PEL *p, PEL *q, int n, IMAGE *in, PEL *c )
|
||||
case IM_BANDFMT_UINT: ANDCONST( unsigned int ); break;
|
||||
|
||||
default:
|
||||
error_exit( "im_andconst: internal error" );
|
||||
g_assert( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
@ -334,7 +241,7 @@ orconst_buffer( PEL *p, PEL *q, int n, IMAGE *in, PEL *c )
|
||||
case IM_BANDFMT_UINT: ORCONST( unsigned int ); break;
|
||||
|
||||
default:
|
||||
error_exit( "im_orconst: internal error" );
|
||||
g_assert( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
@ -353,94 +260,53 @@ eorconst_buffer( PEL *p, PEL *q, int n, IMAGE *in, PEL *c )
|
||||
case IM_BANDFMT_UINT: EORCONST( unsigned int ); break;
|
||||
|
||||
default:
|
||||
error_exit( "im_eorconst: internal error" );
|
||||
g_assert( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
/* Save a bit of typing.
|
||||
*/
|
||||
#define UC IM_BANDFMT_UCHAR
|
||||
#define C IM_BANDFMT_CHAR
|
||||
#define US IM_BANDFMT_USHORT
|
||||
#define S IM_BANDFMT_SHORT
|
||||
#define UI IM_BANDFMT_UINT
|
||||
#define I IM_BANDFMT_INT
|
||||
|
||||
/* Type conversions for boolean.
|
||||
*/
|
||||
static int bandfmt_bool[10] = {
|
||||
/* UC C US S UI I F X D DX */
|
||||
UC, C, US, S, UI, I, I, I, I, I },
|
||||
};
|
||||
|
||||
/* The above, wrapped up as im_*() functions.
|
||||
*/
|
||||
int
|
||||
im_andimage( IMAGE *in1, IMAGE *in2, IMAGE *out )
|
||||
{
|
||||
IMAGE *invec[3];
|
||||
|
||||
/* Check images.
|
||||
*/
|
||||
invec[0] = in1; invec[1] = in2; invec[2] = NULL;
|
||||
if( check( invec, out ) )
|
||||
return( -1 );
|
||||
|
||||
/* Process!
|
||||
*/
|
||||
if( im_wrapmany( invec, out, (im_wrapmany_fn) and_buffer, out, NULL ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
return( im__arith_binary( "im_andimage",
|
||||
in1, in2, out,
|
||||
bandfmt_bool,
|
||||
(im_wrapmany_fn) and_buffer, NULL ) );
|
||||
}
|
||||
|
||||
int
|
||||
im_orimage( IMAGE *in1, IMAGE *in2, IMAGE *out )
|
||||
{
|
||||
IMAGE *invec[3];
|
||||
|
||||
invec[0] = in1; invec[1] = in2; invec[2] = NULL;
|
||||
if( check( invec, out ) )
|
||||
return( -1 );
|
||||
|
||||
if( im_wrapmany( invec, out, (im_wrapmany_fn) or_buffer, out, NULL ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
{
|
||||
return( im__arith_binary( "im_orimage",
|
||||
in1, in2, out,
|
||||
bandfmt_bool,
|
||||
(im_wrapmany_fn) or_buffer, NULL ) );
|
||||
}
|
||||
|
||||
int
|
||||
im_eorimage( IMAGE *in1, IMAGE *in2, IMAGE *out )
|
||||
{
|
||||
IMAGE *invec[3];
|
||||
|
||||
invec[0] = in1; invec[1] = in2; invec[2] = NULL;
|
||||
if( check( invec, out ) )
|
||||
return( -1 );
|
||||
|
||||
if( im_wrapmany( invec, out, (im_wrapmany_fn) eor_buffer, out, NULL ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/* Cast a vector of double to a vector of TYPE.
|
||||
*/
|
||||
#define CAST( TYPE ) { \
|
||||
TYPE *tq = (TYPE *) q; \
|
||||
\
|
||||
for( i = 0; i < out->Bands; i++ ) \
|
||||
tq[i] = (TYPE) p[i]; \
|
||||
}
|
||||
|
||||
/* Make a pixel of output type from a realvec.
|
||||
*/
|
||||
static PEL *
|
||||
make_pixel( IMAGE *out, int fmt, double *p )
|
||||
{
|
||||
PEL *q;
|
||||
int i;
|
||||
|
||||
if( !(q = IM_ARRAY( out, IM_IMAGE_SIZEOF_PEL( out ), PEL )) )
|
||||
return( NULL );
|
||||
|
||||
switch( fmt ) {
|
||||
case IM_BANDFMT_CHAR: CAST( signed char ); break;
|
||||
case IM_BANDFMT_UCHAR: CAST( unsigned char ); break;
|
||||
case IM_BANDFMT_SHORT: CAST( signed short ); break;
|
||||
case IM_BANDFMT_USHORT: CAST( unsigned short ); break;
|
||||
case IM_BANDFMT_INT: CAST( signed int ); break;
|
||||
case IM_BANDFMT_UINT: CAST( unsigned int ); break;
|
||||
|
||||
default:
|
||||
error_exit( "make_pixel: internal error" );
|
||||
}
|
||||
|
||||
return( q );
|
||||
return( im__arith_binary( "im_eorimage",
|
||||
in1, in2, out,
|
||||
bandfmt_bool,
|
||||
(im_wrapmany_fn) eor_buffer, NULL ) );
|
||||
}
|
||||
|
||||
int
|
||||
@ -594,8 +460,7 @@ shiftleft_buffer( PEL *p, PEL *q, int len, IMAGE *in, int n )
|
||||
case IM_BANDFMT_INT: SHIFTL( signed int ); break;
|
||||
|
||||
default:
|
||||
error_exit( "im_shiftleft: internal error" );
|
||||
/*NOTREACHED*/
|
||||
g_assert( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
@ -641,8 +506,7 @@ shiftright_buffer( PEL *p, PEL *q, int len, IMAGE *in, int n )
|
||||
case IM_BANDFMT_INT: SHIFTR( signed int ); break;
|
||||
|
||||
default:
|
||||
error_exit( "im_shiftright: internal error" );
|
||||
/*NOTREACHED*/
|
||||
g_assert( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -283,8 +283,10 @@ png2vips( Read *read, int header_only )
|
||||
|
||||
/* Expand <8 bit images to full bytes.
|
||||
*/
|
||||
if( read->pInfo->bit_depth < 8 )
|
||||
if( read->pInfo->bit_depth < 8 ) {
|
||||
png_set_packing( read->pPng );
|
||||
png_set_shift( read->pPng, 2 );
|
||||
}
|
||||
|
||||
/* If we're an INTEL byte order machine and this is 16bits, we need
|
||||
* to swap bytes.
|
||||
|
@ -131,9 +131,10 @@ char *im__gslist_gvalue_get( const GSList *list );
|
||||
|
||||
void im__buffer_init( void );
|
||||
|
||||
int im__cast_and_call( IMAGE *in1, IMAGE *in2, IMAGE *out,
|
||||
int im__arith_binary( const char *name,
|
||||
IMAGE *in1, IMAGE *in2, IMAGE *out,
|
||||
int format_table[10],
|
||||
im_wrapmany_fn fn, void *a );
|
||||
VipsBandFmt im__format_common( IMAGE *in1, IMAGE *in2 );
|
||||
int im__math( const char *name, IMAGE *in, IMAGE *out, im_wrapone_fn gen );
|
||||
int im__value( IMAGE *im, double *value );
|
||||
typedef int (*im__wrapscan_fn)( void *p, int n, void *seq, void *a, void *b );
|
||||
|
Loading…
Reference in New Issue
Block a user