/** * im_fgrey: * @out: output image * @xsize: image size * @ysize: image size * * Create a one-band float image with the left-most column zero and the * right-most 1. Intermediate pixels are a linear ramp. * * See also: im_grey(), im_make_xy(), im_identity(). * * Returns: 0 on success, -1 on error */ int im_fgrey( IMAGE *out, const int xsize, const int ysize ) { /* Check args. */ if( xsize <=0 || ysize <= 0 ) { im_error( "im_fgrey", "%s", _( "bad size" ) ); return( -1 ); } if( im_poutcheck( out ) ) return( -1 ); /* Set image. */ im_initdesc( out, xsize, ysize, 1, IM_BBITS_FLOAT, IM_BANDFMT_FLOAT, IM_CODING_NONE, IM_TYPE_B_W, 1.0, 1.0, 0, 0 ); /* Set hints - ANY is ok with us. */ if( im_demand_hint( out, IM_ANY, NULL ) ) return( -1 ); /* Generate image. */ if( im_generate( out, NULL, fgrey_gen, NULL, NULL, NULL ) ) return( -1 ); return( 0 ); }
/** * im_gaussnoise: * @out: output image * @x: output width * @y: output height * @mean: average value in output * @sigma: standard deviation in output * * Make a one band float image of gaussian noise with the specified * distribution. The noise distribution is created by averaging 12 random * numbers with the appropriate weights. * * See also: im_addgnoise(), im_make_xy(), im_text(), im_black(). * * Returns: 0 on success, -1 on error */ int im_gaussnoise( IMAGE *out, int x, int y, double mean, double sigma ) { GnoiseInfo *gin; if( x <= 0 || y <= 0 ) { im_error( "im_gaussnoise", "%s", _( "bad parameter" ) ); return( -1 ); } if( im_poutcheck( out ) ) return( -1 ); im_initdesc( out, x, y, 1, IM_BBITS_FLOAT, IM_BANDFMT_FLOAT, IM_CODING_NONE, IM_TYPE_B_W, 1.0, 1.0, 0, 0 ); if( im_demand_hint( out, IM_ANY, NULL ) ) return( -1 ); /* Save parameters. */ if( !(gin = IM_NEW( out, GnoiseInfo )) ) return( -1 ); gin->mean = mean; gin->sigma = sigma; if( im_generate( out, NULL, gnoise_gen, NULL, gin, NULL ) ) return( -1 ); return( 0 ); }
/** * im_buildlut: * @input: input mask * @output: output image * * This operation builds a lookup table from a set of points. Intermediate * values are generated by piecewise linear interpolation. * * For example, consider this 2 x 2 matrix of (x, y) coordinates: * * <tgroup cols='2' align='left' colsep='1' rowsep='1'> * <tbody> * <row> * <entry>0</entry> * <entry>0</entry> * </row> * <row> * <entry>255</entry> * <entry>100</entry> * </row> * </tbody> * </tgroup> * * We then generate: * * <tgroup cols='2' align='left' colsep='1' rowsep='1'> * <thead> * <row> * <entry>Index</entry> * <entry>Value</entry> * </row> * </thead> * <tbody> * <row> * <entry>0</entry> * <entry>0</entry> * </row> * <row> * <entry>1</entry> * <entry>0.4</entry> * </row> * <row> * <entry>...</entry> * <entry>etc. by linear interpolation</entry> * </row> * <row> * <entry>255</entry> * <entry>100</entry> * </row> * </tbody> * </tgroup> * * This is then written as the output image, with the left column giving the * index in the image to place the value. * * The (x, y) points don't need to be sorted: we do that. You can have * several Ys, each becomes a band in the output LUT. You don't need to * start at zero, any integer will do, including negatives. * * See also: im_identity(), im_invertlut(). * * Returns: 0 on success, -1 on error */ int im_buildlut( DOUBLEMASK *input, IMAGE *output ) { State state; if( !input || input->xsize < 2 || input->ysize < 1 ) { im_error( "im_buildlut", "%s", _( "bad input matrix size" ) ); return( -1 ); } if( build_state( &state, input ) || buildlut( &state ) ) { free_state( &state ); return( -1 ); } im_initdesc( output, state.lut_size, 1, input->xsize - 1, IM_BBITS_DOUBLE, IM_BANDFMT_DOUBLE, IM_CODING_NONE, IM_TYPE_HISTOGRAM, 1.0, 1.0, 0, 0 ); if( im_setupout( output ) || im_writeline( 0, output, (PEL *) state.buf ) ) { free_state( &state ); return( -1 ); } free_state( &state ); return( 0 ); }
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 ); }
static int hist_write( IMAGE *out, Histogram *hist ) { if( im_cp_descv( out, hist->index, hist->value, NULL ) ) return( -1 ); im_initdesc( out, hist->mx + 1, 1, hist->value->Bands, IM_BBITS_DOUBLE, IM_BANDFMT_DOUBLE, IM_CODING_NONE, IM_TYPE_HISTOGRAM, 1.0, 1.0, 0, 0 ); if( im_setupout( out ) ) return( -1 ); if( im_writeline( 0, out, (PEL *) hist->bins ) ) return( -1 ); return( 0 ); }
/** * im_mask2vips: * @in: input mask * @out: output image * * Write a one-band, %IM_BANDFMT_DOUBLE image to @out based on mask @in. * * See also: im_vips2mask(). * * Returns: 0 on success, -1 on error */ int im_mask2vips( DOUBLEMASK *in, IMAGE *out ) { int x, y; double *buf, *p, *q; /* Check the mask. */ if( !in || !in->coeff ) { im_error( "im_mask2vips", "%s", _( "bad input mask" ) ); return( -1 ); } /* Make the output image. */ im_initdesc( out, in->xsize, in->ysize, 1, IM_BBITS_DOUBLE, IM_BANDFMT_DOUBLE, IM_CODING_NONE, IM_TYPE_B_W, 1.0, 1.0, 0, 0 ); if( im_setupout( out ) ) return( -1 ); /* Make an output buffer. */ if( !(buf = IM_ARRAY( out, in->xsize, double )) ) return( -1 ); /* Write! */ for( p = in->coeff, y = 0; y < out->Ysize; y++ ) { q = buf; for( x = 0; x < out->Xsize; x++ ) *q++ = *p++; if( im_writeline( y, out, (void *) buf ) ) return( -1 ); } return( 0 ); }
int im_fzone( IMAGE *image, int size ) { int x, y; int i, j; float *buf; const int size2 = size/2; /* Check args. */ if( im_outcheck( image ) ) return( -1 ); if( size <= 0 || (size % 2) != 0 ) { im_error( "im_zone", "%s", _( "size must be even and positive" ) ); return( -1 ); } /* Set up output image. */ im_initdesc( image, size, size, 1, IM_BBITS_FLOAT, IM_BANDFMT_FLOAT, IM_CODING_NONE, IM_TYPE_B_W, 1.0, 1.0, 0, 0 ); if( im_setupout( image ) ) return( -1 ); /* Create output buffer. */ if( !(buf = IM_ARRAY( image, size, float )) ) return( -1 ); /* Make zone plate. */ for( y = 0, j = -size2; j < size2; j++, y++ ) { for( x = 0, i = -size2; i < size2; i++, x++ ) buf[x] = cos( (IM_PI / size) * (i * i + j * j) ); if( im_writeline( y, image, (PEL *) buf ) ) return( -1 ); } return( 0 ); }
static int lgrab_capture( LGrab *lg, IMAGE *im ) { int x, y; unsigned char *line; if( lgrab_capturen( lg ) ) return( -1 ); if( im_outcheck( im ) ) return( -1 ); im_initdesc( im, lg->c_width, lg->c_height, 3, IM_BBITS_BYTE, IM_BANDFMT_UCHAR, IM_CODING_NONE, IM_TYPE_MULTIBAND, 1.0, 1.0, 0, 0 ); if( im_setupout( im ) ) return( -1 ); if( !(line = IM_ARRAY( im, IM_IMAGE_SIZEOF_LINE( im ), unsigned char )) ) return( -1 ); for( y = 0; y < lg->c_height; y++ ) { unsigned char *p = (unsigned char *) lg->capture_buffer + y * IM_IMAGE_SIZEOF_LINE( im ); unsigned char *q = line; for( x = 0; x < lg->c_width; x++ ) { q[0] = p[2]; q[1] = p[1]; q[2] = p[0]; p += 3; q += 3; } if( im_writeline( y, im, line ) ) return( -1 ); } return( 0 ); }
static int read_header( FILE *fp, IMAGE *out, int *bits, int *ascii, int *msb_first ) { int width, height, bands, fmt, type; int index; char buf[IM_MAX_THING]; /* ppm types. */ static char *magic_names[] = { "P1", /* pbm ... 1 band 1 bit, ascii */ "P2", /* pgm ... 1 band many bit, ascii */ "P3", /* ppm ... 3 band many bit, ascii */ "P4", /* pbm ... 1 band 1 bit, binary */ "P5", /* pgm ... 1 band 8 bit, binary */ "P6", /* ppm ... 3 band 8 bit, binary */ "PF", /* pfm ... 3 band 32 bit, binary */ "Pf" /* pfm ... 1 band 32 bit, binary */ }; /* Characteristics, indexed by ppm type. */ static int lookup_bits[] = { 1, 8, 8, 1, 8, 8, 32, 32 }; static int lookup_bands[] = { 1, 1, 3, 1, 1, 3, 3, 1 }; static int lookup_ascii[] = { 1, 1, 1, 0, 0, 0, 0, 0 }; /* Read in the magic number. */ buf[0] = fgetc( fp ); buf[1] = fgetc( fp ); buf[2] = '\0'; for( index = 0; index < IM_NUMBER( magic_names ); index++ ) if( strcmp( magic_names[index], buf ) == 0 ) break; if( index == IM_NUMBER( magic_names ) ) { im_error( "im_ppm2vips", "%s", _( "bad magic number" ) ); return( -1 ); } *bits = lookup_bits[index]; bands = lookup_bands[index]; *ascii = lookup_ascii[index]; /* Default ... can be changed below for PFM images. */ *msb_first = 0; /* Read in size. */ if( read_int( fp, &width ) || read_int( fp, &height ) ) return( -1 ); /* Read in max value / scale for >1 bit images. */ if( *bits > 1 ) { if( index == 6 || index == 7 ) { float scale; if( read_float( fp, &scale ) ) return( -1 ); /* Scale > 0 means big-endian. */ *msb_first = scale > 0; im_meta_set_double( out, "pfm-scale", fabs( scale ) ); } else { int max_value; if( read_int( fp, &max_value ) ) return( -1 ); if( max_value > 255 ) *bits = 16; if( max_value > 65535 ) *bits = 32; } } /* For binary images, there is always exactly 1 more whitespace * character before the data starts. */ if( !*ascii && !isspace( fgetc( fp ) ) ) { im_error( "im_ppm2vips", "%s", _( "not whitespace before start of binary data" ) ); return( -1 ); } /* Choose a VIPS bandfmt. */ switch( *bits ) { case 1: case 8: fmt = IM_BANDFMT_UCHAR; break; case 16: fmt = IM_BANDFMT_USHORT; break; case 32: if( index == 6 || index == 7 ) fmt = IM_BANDFMT_FLOAT; else fmt = IM_BANDFMT_UINT; break; default: g_assert( 0 ); } if( bands == 1 ) { if( fmt == IM_BANDFMT_USHORT ) type = IM_TYPE_GREY16; else type = IM_TYPE_B_W; } else { if( fmt == IM_BANDFMT_USHORT ) type = IM_TYPE_RGB16; else if( fmt == IM_BANDFMT_UINT ) type = IM_TYPE_RGB; else type = IM_TYPE_sRGB; } im_initdesc( out, width, height, bands, (*bits == 1) ? 8 : *bits, fmt, IM_CODING_NONE, type, 1.0, 1.0, 0, 0 ); return( 0 ); }
int im_histnD( IMAGE *in, IMAGE *out, int bins ) { int max_val; Histogram *mhist; int x, y, z, i; unsigned int *obuffer; /* Check images. PIO from in, WIO to out. */ if( im_pincheck( in ) || im_outcheck( out ) ) return( -1 ); if( in->Coding != IM_CODING_NONE ) { im_error( "im_histnD", _( " uncoded images only" ) ); return( -1 ); } if( in->BandFmt != IM_BANDFMT_UCHAR && in->BandFmt != IM_BANDFMT_USHORT ) { im_error( "im_histnD", _( " unsigned 8 or 16 bit images only" ) ); return( -1 ); } max_val = in->BandFmt == IM_BANDFMT_UCHAR ? 256 : 65536; if( bins < 1 || bins > max_val ) { im_error( "im_histnD", _( " bins out of range [1,%d]" ), max_val ); return( -1 ); } /* Build main hist we accumulate to. */ if( !(mhist = build_hist( in, out, bins )) ) return( -1 ); /* Accumulate data. */ if( im_iterate( in, build_subhist, find_hist, merge_subhist, mhist, NULL ) ) return( -1 ); /* Make the output image. */ if( im_cp_desc( out, in ) ) return( -1 ); im_initdesc( out, bins, in->Bands > 1 ? bins : 1, in->Bands > 2 ? bins : 1, IM_BBITS_INT, IM_BANDFMT_UINT, IM_CODING_NONE, IM_TYPE_HISTOGRAM, 1.0, 1.0, 0, 0 ); if( im_setupout( out ) ) return( -1 ); /* Interleave to output buffer. */ if( !(obuffer = IM_ARRAY( out, IM_IMAGE_N_ELEMENTS( out ), unsigned int )) ) return( -1 ); for( y = 0; y < out->Ysize; y++ ) { for( i = 0, x = 0; x < out->Xsize; x++ ) for( z = 0; z < out->Bands; z++, i++ ) obuffer[i] = mhist->data[z][y][x]; if( im_writeline( y, out, (PEL *) obuffer ) ) return( -1 ); } return( 0 ); }
/** * im_simcontr: * @out: output image * @xsize: image size * @ysize: image size * * Creates a pattern showing the similtaneous constrast effect. * * See also: im_eye(). * * Returns: 0 on success, -1 on error */ int im_simcontr( IMAGE *out, int xsize, int ysize ) { int x, y; unsigned char *line1, *line2, *cpline; /* Check input args */ if( im_outcheck( out ) ) return( -1 ); /* Set now image properly */ im_initdesc(out, xsize, ysize, 1, IM_BBITS_BYTE, IM_BANDFMT_UCHAR, IM_CODING_NONE, IM_TYPE_B_W, 1.0, 1.0, 0, 0 ); /* Set up image checking whether the output is a buffer or a file */ if (im_setupout( out ) == -1 ) return( -1 ); /* Create data */ line1 = (unsigned char *)calloc((unsigned)xsize, sizeof(char)); line2 = (unsigned char *)calloc((unsigned)xsize, sizeof(char)); if ( (line1 == NULL) || (line2 == NULL) ) { im_error( "im_simcontr", "%s", _( "calloc failed") ); return(-1); } cpline = line1; for (x=0; x<xsize; x++) *cpline++ = (PEL)255; cpline = line1; for (x=0; x<xsize/2; x++) *cpline++ = (PEL)0; cpline = line2; for (x=0; x<xsize; x++) *cpline++ = (PEL)255; cpline = line2; for (x=0; x<xsize/8; x++) *cpline++ = (PEL)0; for (x=0; x<xsize/4; x++) *cpline++ = (PEL)128; for (x=0; x<xsize/8; x++) *cpline++ = (PEL)0; for (x=0; x<xsize/8; x++) *cpline++ = (PEL)255; for (x=0; x<xsize/4; x++) *cpline++ = (PEL)128; for (y=0; y<ysize/4; y++) { if ( im_writeline( y, out, (PEL *)line1 ) == -1 ) { free ( (char *)line1 ); free ( (char *)line2 ); return( -1 ); } } for (y=ysize/4; y<(ysize/4+ysize/2); y++) { if ( im_writeline( y, out, (PEL *)line2 ) == -1 ) { free ( (char *)line1 ); free ( (char *)line2 ); return( -1 ); } } for (y=(ysize/4 + ysize/2); y<ysize; y++) { if ( im_writeline( y, out, (PEL *)line1 ) == -1 ) { free ( (char *)line1 ); free ( (char *)line2 ); return( -1 ); } } free ( (char *)line1 ); free ( (char *)line2 ); return(0); }
/* Plot image. */ static int plot( IMAGE *in, IMAGE *out ) { double max; int tsize; int xsize; int ysize; if( im_incheck( in ) || im_poutcheck( out ) ) return( -1 ); /* Find range we will plot. */ if( im_max( in, &max ) ) return( -1 ); g_assert( max >= 0 ); if( in->BandFmt == IM_BANDFMT_UCHAR ) tsize = 256; else tsize = ceil( max ); /* Make sure we don't make a zero height image. */ if( tsize == 0 ) tsize = 1; if( in->Xsize == 1 ) { /* Vertical graph. */ xsize = tsize; ysize = in->Ysize; } else { /* Horizontal graph. */ xsize = in->Xsize; ysize = tsize; } /* Set image. */ im_initdesc( out, xsize, ysize, in->Bands, IM_BBITS_BYTE, IM_BANDFMT_UCHAR, IM_CODING_NONE, IM_TYPE_HISTOGRAM, 1.0, 1.0, 0, 0 ); /* Set hints - ANY is ok with us. */ if( im_demand_hint( out, IM_ANY, NULL ) ) return( -1 ); /* Generate image. */ if( in->Xsize == 1 ) { if( im_generate( out, NULL, make_vert_gen, NULL, in, NULL ) ) return( -1 ); } else { if( im_generate( out, NULL, make_horz_gen, NULL, in, NULL ) ) return( -1 ); } return( 0 ); }
/** * im_sines: * @out: output image * @xsize: image size * @ysize: image size * @horfreq: horizontal frequency * @verfreq: vertical frequency * * im_sines() creates a float one band image of the a sine waveform in two * dimensions. * * The number of horizontal and vertical spatial frequencies are * determined by the variables @horfreq and @verfreq respectively. The * function is useful for creating displayable sine waves and * square waves in two dimensions. * * If horfreq and verfreq are integers the resultant image is periodical * and therfore the Fourier transform doesnot present spikes * * See also: im_grey(), im_make_xy(). * * Returns: 0 on success, -1 on error */ int im_sines( IMAGE *out, int xsize, int ysize, double horfreq, double verfreq ) { int x, y; float *line, *cpline; int size; double cons, factor; double theta_rad, costheta, sintheta, ysintheta; /* Check input args */ if( im_outcheck( out ) ) return( -1 ); if ( xsize <= 0 || ysize <= 0 ) { im_error( "im_sines", "%s", _( "wrong sizes") ); return(-1); } /* Set now out properly */ im_initdesc(out, xsize, ysize, 1, IM_BBITS_FLOAT, IM_BANDFMT_FLOAT, IM_CODING_NONE, IM_TYPE_B_W, 1.0, 1.0, 0, 0); /* Set up out checking whether the output is a buffer or a file */ if (im_setupout( out ) == -1 ) return( -1 ); /* Create data */ size = out->Xsize; if ( (line=(float *)calloc((unsigned)size, sizeof(float))) == NULL ) { im_error( "im_sines", "%s", _( "calloc failed") ); return(-1); } /* make angle in rad */ if (horfreq == 0) theta_rad = IM_PI/2.0; else theta_rad = atan(verfreq/horfreq); costheta = cos(theta_rad); sintheta = sin(theta_rad); factor = sqrt ((double)(horfreq*horfreq + verfreq*verfreq)); cons = factor * IM_PI * 2.0/(double)out->Xsize; /* There is a bug (rounding error ?) for horfreq=0, *so do this calculation independantly */ if ( horfreq != 0 ) { for (y=0; y<out->Ysize; y++) { ysintheta = y * sintheta; cpline = line; for (x=0; x<out->Xsize; x++) *cpline++ = (float)(cos(cons*(x*costheta-ysintheta))); if ( im_writeline( y, out, (PEL *)line ) == -1 ) { free ( (char *)line ); return( -1 ); } } } else { for (y=0; y<out->Ysize; y++) { cpline = line; ysintheta = cos (- cons * y * sintheta); for (x=0; x<out->Xsize; x++) *cpline++ = (float)ysintheta; if ( im_writeline( y, out, (PEL *)line ) == -1 ) { free ( (char *)line ); return( -1 ); } } } free ( (char *)line ); return(0); }
/* Read a cinfo to a VIPS image. Set invert_pels if the pixel reader needs to * do 255-pel. */ static int read_jpeg_header( struct jpeg_decompress_struct *cinfo, IMAGE *out, gboolean *invert_pels, int shrink ) { jpeg_saved_marker_ptr p; int type; /* Capture app2 sections here for assembly. */ void *app2_data[MAX_APP2_SECTIONS] = { 0 }; int app2_data_length[MAX_APP2_SECTIONS] = { 0 }; int data_length; int i; /* Read JPEG header. libjpeg will set out_color_space sanely for us * for YUV YCCK etc. */ jpeg_read_header( cinfo, TRUE ); cinfo->scale_denom = shrink; cinfo->scale_num = 1; jpeg_calc_output_dimensions( cinfo ); *invert_pels = FALSE; switch( cinfo->out_color_space ) { case JCS_GRAYSCALE: type = IM_TYPE_B_W; break; case JCS_CMYK: type = IM_TYPE_CMYK; /* Photoshop writes CMYK JPEG inverted :-( Maybe this is a * way to spot photoshop CMYK JPGs. */ if( cinfo->saw_Adobe_marker ) *invert_pels = TRUE; break; case JCS_RGB: default: type = IM_TYPE_sRGB; break; } /* Set VIPS header. */ im_initdesc( out, cinfo->output_width, cinfo->output_height, cinfo->output_components, IM_BBITS_BYTE, IM_BANDFMT_UCHAR, IM_CODING_NONE, type, 1.0, 1.0, 0, 0 ); /* Interlaced jpegs need lots of memory to read, so our caller needs * to know. */ (void) im_meta_set_int( out, "jpeg-multiscan", jpeg_has_multiple_scans( cinfo ) ); /* Look for EXIF and ICC profile. */ for( p = cinfo->marker_list; p; p = p->next ) { switch( p->marker ) { case JPEG_APP0 + 1: /* EXIF data. */ #ifdef DEBUG printf( "read_jpeg_header: seen %d bytes of APP1\n", p->data_length ); #endif /*DEBUG*/ if( read_exif( out, p->data, p->data_length ) ) return( -1 ); break; case JPEG_APP0 + 2: /* ICC profile. */ #ifdef DEBUG printf( "read_jpeg_header: seen %d bytes of APP2\n", p->data_length ); #endif /*DEBUG*/ if( p->data_length > 14 && im_isprefix( "ICC_PROFILE", (char *) p->data ) ) { /* cur_marker numbers from 1, according to * spec. */ int cur_marker = p->data[12] - 1; if( cur_marker >= 0 && cur_marker < MAX_APP2_SECTIONS ) { app2_data[cur_marker] = p->data + 14; app2_data_length[cur_marker] = p->data_length - 14; } } break; default: #ifdef DEBUG printf( "read_jpeg_header: seen %d bytes of data\n", p->data_length ); #endif /*DEBUG*/ break; } } /* Assemble ICC sections. */ data_length = 0; for( i = 0; i < MAX_APP2_SECTIONS && app2_data[i]; i++ ) data_length += app2_data_length[i]; if( data_length ) { unsigned char *data; int p; #ifdef DEBUG printf( "read_jpeg_header: assembled %d byte ICC profile\n", data_length ); #endif /*DEBUG*/ if( !(data = im_malloc( NULL, data_length )) ) return( -1 ); p = 0; for( i = 0; i < MAX_APP2_SECTIONS && app2_data[i]; i++ ) { memcpy( data + p, app2_data[i], app2_data_length[i] ); p += app2_data_length[i]; } if( im_meta_set_blob( out, IM_META_ICC_NAME, (im_callback_fn) im_free, data, data_length ) ) { im_free( data ); return( -1 ); } } return( 0 ); }
/* Read a PNG file (header) into a VIPS (header). */ static int png2vips( Read *read, int header_only ) { int bands, bpp, type; if( setjmp( read->pPng->jmpbuf ) ) return( -1 ); png_init_io( read->pPng, read->fp ); png_read_info( read->pPng, read->pInfo ); /* png_get_channels() gives us 1 band for palette images ... so look * at colour_type for output bands. */ switch( read->pInfo->color_type ) { case PNG_COLOR_TYPE_PALETTE: bands = 3; /* Don't know if this is really correct. If there are * transparent pixels, assume we're going to output RGBA. */ if( read->pInfo->num_trans ) bands = 4; break; case PNG_COLOR_TYPE_GRAY: bands = 1; break; case PNG_COLOR_TYPE_GRAY_ALPHA: bands = 2; break; case PNG_COLOR_TYPE_RGB: bands = 3; break; case PNG_COLOR_TYPE_RGB_ALPHA: bands = 4; break; default: im_error( "im_png2vips", "%s", _( "unsupported color type" ) ); return( -1 ); } /* 8 or 16 bit. */ bpp = read->pInfo->bit_depth > 8 ? 2 : 1; if( bpp > 1 ) { if( bands < 3 ) type = IM_TYPE_GREY16; else type = IM_TYPE_RGB16; } else { if( bands < 3 ) type = IM_TYPE_B_W; else type = IM_TYPE_sRGB; } /* Expand palette images. */ if( read->pInfo->color_type == PNG_COLOR_TYPE_PALETTE ) png_set_expand( read->pPng ); /* Expand <8 bit images to full bytes. */ if( read->pInfo->bit_depth < 8 ) { png_set_packing( read->pPng ); png_set_shift( read->pPng, &(read->pInfo->sig_bit) ); } /* If we're an INTEL byte order machine and this is 16bits, we need * to swap bytes. */ if( read->pInfo->bit_depth > 8 && !im_amiMSBfirst() ) png_set_swap( read->pPng ); /* Set VIPS header. */ im_initdesc( read->out, read->pInfo->width, read->pInfo->height, bands, bpp == 1 ? IM_BBITS_BYTE : IM_BBITS_SHORT, bpp == 1 ? IM_BANDFMT_UCHAR : IM_BANDFMT_USHORT, IM_CODING_NONE, type, 1.0, 1.0, 0, 0 ); if( !header_only ) { if( png_set_interlace_handling( read->pPng ) > 1 ) { if( png2vips_interlace( read ) ) return( -1 ); } else { if( png2vips_noninterlace( read ) ) 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 ); }
/** * im_tone_build_range: * @out: output image * @in_max: input range * @out_max: output range * @Lb: black-point [0-100] * @Lw: white-point [0-100] * @Ps: shadow point (eg. 0.2) * @Pm: mid-tone point (eg. 0.5) * @Ph: highlight point (eg. 0.8) * @S: shadow adjustment (+/- 30) * @M: mid-tone adjustment (+/- 30) * @H: highlight adjustment (+/- 30) * * im_tone_build_range() generates a tone curve for the adjustment of image * levels. It is mostly designed for adjusting the L* part of a LAB image in * way suitable for print work, but you can use it for other things too. * * The curve is an unsigned 16-bit image with (@in_max + 1) entries, * each in the range [0, @out_max]. * * @Lb, @Lw are expressed as 0-100, as in LAB colour space. You * specify the scaling for the input and output images with the @in_max and * @out_max parameters. * * See also: im_ismonotonic(), im_tone_map(), im_tone_analyse(). * * Returns: 0 on success, -1 on error */ int im_tone_build_range( IMAGE *out, int in_max, int out_max, double Lb, double Lw, double Ps, double Pm, double Ph, double S, double M, double H ) { ToneShape *ts; unsigned short lut[65536]; int i; /* Check args. */ if( !(ts = IM_NEW( out, ToneShape )) || im_outcheck( out ) ) return( -1 ); if( in_max < 0 || in_max > 65535 || out_max < 0 || out_max > 65535 ) { im_error( "im_tone_build", "%s", _( "bad in_max, out_max parameters" ) ); return( -1 ); } if( Lb < 0 || Lb > 100 || Lw < 0 || Lw > 100 || Lb > Lw ) { im_error( "im_tone_build", "%s", _( "bad Lb, Lw parameters" ) ); return( -1 ); } if( Ps < 0.0 || Ps > 1.0 ) { im_error( "im_tone_build", "%s", _( "Ps not in range [0.0,1.0]" ) ); return( -1 ); } if( Pm < 0.0 || Pm > 1.0 ) { im_error( "im_tone_build", "%s", _( "Pm not in range [0.0,1.0]" ) ); return( -1 ); } if( Ph < 0.0 || Ph > 1.0 ) { im_error( "im_tone_build", "%s", _( "Ph not in range [0.0,1.0]" ) ); return( -1 ); } if( S < -30 || S > 30 ) { im_error( "im_tone_build", "%s", _( "S not in range [-30,+30]" ) ); return( -1 ); } if( M < -30 || M > 30 ) { im_error( "im_tone_build", "%s", _( "M not in range [-30,+30]" ) ); return( -1 ); } if( H < -30 || H > 30 ) { im_error( "im_tone_build", "%s", _( "H not in range [-30,+30]" ) ); return( -1 ); } /* Note params. */ ts->Lb = Lb; ts->Lw = Lw; ts->Ps = Ps; ts->Pm = Pm; ts->Ph = Ph; ts->S = S; ts->M = M; ts->H = H; /* Note derived params. */ ts->Ls = Lb + Ps * (Lw - Lb); ts->Lm = Lb + Pm * (Lw - Lb); ts->Lh = Lb + Ph * (Lw - Lb); /* Generate curve. */ for( i = 0; i <= in_max; i++ ) { int v = (out_max / 100.0) * tone_curve( ts, 100.0 * i / in_max ); if( v < 0 ) v = 0; else if( v > out_max ) v = out_max; lut[i] = v; } /* Make the output image. */ im_initdesc( out, in_max + 1, 1, 1, IM_BBITS_SHORT, IM_BANDFMT_USHORT, IM_CODING_NONE, IM_TYPE_HISTOGRAM, 1.0, 1.0, 0, 0 ); if( im_setupout( out ) ) return( -1 ); if( im_writeline( 0, out, (VipsPel *) lut ) ) return( -1 ); return( 0 ); }