/* Print overflows, if any. */ static int lut_end( LutInfo *st ) { if( st->overflow ) im_warn( "im_maplut", _( "%d overflows detected" ), st->overflow ); return( 0 ); }
static void set_vips_resolution( IMAGE *im, ExifData *ed ) { double xres, yres; int unit; if( get_entry_rational( ed, EXIF_TAG_X_RESOLUTION, &xres ) || get_entry_rational( ed, EXIF_TAG_Y_RESOLUTION, &yres ) || get_entry_short( ed, EXIF_TAG_RESOLUTION_UNIT, &unit ) ) { im_warn( "im_jpeg2vips", "%s", _( "error reading resolution" ) ); return; } switch( unit ) { case 2: /* In inches. */ xres /= 25.4; yres /= 25.4; break; case 3: /* In cm. */ xres /= 10.0; yres /= 10.0; break; default: im_warn( "im_jpeg2vips", "%s", _( "bad resolution unit" ) ); return; } im->Xres = xres; im->Yres = yres; }
/* End of evaluation --- print overflows and underflows. */ static int conv_destroy( Conv *conv ) { /* Print underflow/overflow count. */ if( conv->overflow || conv->underflow ) im_warn( "im_convsep", _( "%d overflows and %d underflows " "detected" ), conv->overflow, conv->underflow ); if( conv->mask ) { (void) im_free_imask( conv->mask ); conv->mask = NULL; } return( 0 ); }
/* Find stats on an area of an IMAGE ... consider only pixels for which the * mask is true. */ static DOUBLEMASK * find_image_stats( IMAGE *in, IMAGE *mask, Rect *area ) { DOUBLEMASK *stats; IMAGE *t[4]; gint64 count; /* Extract area, build black image, mask out pixels we want. */ if( im_open_local_array( in, t, 4, "find_image_stats", "p" ) || extract_rect( in, t[0], area ) || im_black( t[1], t[0]->Xsize, t[0]->Ysize, t[0]->Bands ) || im_clip2fmt( t[1], t[2], t[0]->BandFmt ) || im_ifthenelse( mask, t[0], t[2], t[3] ) ) return( NULL ); /* Get stats from masked image. */ if( !(stats = local_mask( in, im_stats( t[3] ) )) ) return( NULL ); /* Number of non-zero pixels in mask. */ if( count_nonzero( mask, &count ) ) return( NULL ); /* And scale masked average to match. */ stats->coeff[4] *= (double) count / ((double) mask->Xsize * mask->Ysize); /* Yuk! Zap the deviation column with the pixel count. Used later to * determine if this is likely to be a significant overlap. */ stats->coeff[5] = count; #ifdef DEBUG if( count == 0 ) im_warn( "global_balance", _( "empty overlap!" ) ); #endif /*DEBUG*/ return( stats ); }
/** * im_binfile: * @name: filename to open * @xsize: image width * @ysize: image height * @bands: image bands (or bytes per pixel) * @offset: bytes to skip at start of file * * This function maps the named file and returns an #IMAGE you can use to * read it. * * It returns an 8-bit image with @bands bands. If the image is not 8-bit, use * im_copy_set() to transform the descriptor after loading it. * * See also: im_copy_set(), im_raw2vips(), im_open(). * * Returns: the new #IMAGE, or NULL on error. */ IMAGE * im_binfile( const char *name, int xsize, int ysize, int bands, int offset ) { IMAGE *im; gint64 psize; gint64 rsize; /* Check parameters. */ if( xsize <= 0 || ysize <= 0 || bands <= 0 ) { im_error( "im_binfile", "%s", _( "bad parameters" ) ); return( NULL ); } /* Make new output image for us. */ if( !(im = im_init( name )) ) return( NULL ); if( (im->fd = im__open_image_file( name )) == -1 ) { im_close( im ); return( NULL ); } im->dtype = IM_OPENIN; im->sizeof_header = offset; /* Predict file size. */ psize = (gint64) xsize * ysize * bands + offset; /* Read the real file length and check against what we think * the size should be. */ if( (rsize = im_file_length( im->fd )) == -1 ) { im_close( im ); return( NULL ); } im->file_length = rsize; /* Very common, so special message. */ if( psize > rsize ) { im_error( "im_binfile", _( "unable to open %s: " "file has been truncated" ), im->filename ); im_close( im ); return( NULL ); } /* Just wierd. Only print a warning for this, since we should * still be able to process it without coredumps. */ if( psize < rsize ) im_warn( "im_binfile", _( "%s is longer than expected" ), im->filename ); /* Set header fields. */ im->Xsize = xsize; im->Ysize = ysize; im->Bands = bands; /* Set others to standard values. */ im->BandFmt = IM_BANDFMT_UCHAR; im->Bbits = im_bits_of_fmt( im->BandFmt ); im->Coding = IM_CODING_NONE; if( bands == 1 ) im->Type = IM_TYPE_B_W; else if( bands == 3 ) im->Type = IM_TYPE_RGB; else im->Type = IM_TYPE_MULTIBAND; im->Xres = 1.0; im->Yres = 1.0; im->Length = 0; im->Compression = 0; im->Level = 0; im->Xoffset = 0; im->Yoffset = 0; /* Init others too. */ im->dhint = IM_THINSTRIP; return( im ); }
/* Measure into array. */ static int measure_patches( IMAGE *im, double *coeff, int left, int top, int width, int height, int u, int v, int *sel, int nsel ) { IMAGE *tmp; int patch; int i, j; int m, n; double avg, dev; int x, y, w, h; /* How large are the patches we are to measure? */ double pw = (double) width / (double) u; double ph = (double) height / (double) v; /* Set up sub to be the size we need for a patch. */ w = (pw + 1) / 2; h = (ph + 1) / 2; /* Loop through sel, picking out areas to measure. */ for( j = 0, patch = 0; patch < nsel; patch++ ) { /* Sanity check. Is the patch number sensible? */ if( sel[patch] <= 0 || sel[patch] > u * v ) { im_error( "im_measure", _( "patch %d is out of range" ), sel[patch] ); return( 1 ); } /* Patch coordinates. */ m = (sel[patch] - 1) % u; n = (sel[patch] - 1) / u; /* Move sub to correct position. */ x = left + m * pw + (pw + 2) / 4; y = top + n * ph + (ph + 2) / 4; /* Loop through bands. */ for( i = 0; i < im->Bands; i++, j++ ) { /* Make temp buffer to extract to. */ if( !(tmp = im_open( "patch", "t" )) ) return( -1 ); /* Extract and measure. */ if( im_extract_areabands( im, tmp, x, y, w, h, i, 1 ) || im_avg( tmp, &avg ) || im_deviate( tmp, &dev ) ) { im_close( tmp ); return( -1 ); } im_close( tmp ); /* Is the deviation large compared with the average? * This could be a clue that our parameters have * caused us to miss the patch. Look out for averages * <0, or averages near zero (can get these if use * im_measure() on IM_TYPE_LAB images). */ if( dev * 5 > fabs( avg ) && fabs( avg ) > 3 ) im_warn( "im_measure", _( "patch %d, band %d: " "avg = %g, sdev = %g" ), patch, i, avg, dev ); /* Save results. */ coeff[j] = avg; } } return( 0 ); }
/* Read a JPEG file into a VIPS image. */ static int jpeg2vips( const char *name, IMAGE *out, gboolean header_only ) { char filename[FILENAME_MAX]; char mode[FILENAME_MAX]; char *p, *q; int shrink; struct jpeg_decompress_struct cinfo; ErrorManager eman; FILE *fp; int result; gboolean invert_pels; gboolean fail_on_warn; /* By default, we ignore any warnings. We want to get as much of * the user's data as we can. */ fail_on_warn = FALSE; /* Parse the filename. */ im_filename_split( name, filename, mode ); p = &mode[0]; shrink = 1; if( (q = im_getnextoption( &p )) ) { shrink = atoi( q ); if( shrink != 1 && shrink != 2 && shrink != 4 && shrink != 8 ) { im_error( "im_jpeg2vips", _( "bad shrink factor %d" ), shrink ); return( -1 ); } } if( (q = im_getnextoption( &p )) ) { if( im_isprefix( "fail", q ) ) fail_on_warn = TRUE; } /* Make jpeg dcompression object. */ cinfo.err = jpeg_std_error( &eman.pub ); eman.pub.error_exit = new_error_exit; eman.pub.output_message = new_output_message; eman.fp = NULL; if( setjmp( eman.jmp ) ) { /* Here for longjmp() from new_error_exit(). */ jpeg_destroy_decompress( &cinfo ); return( -1 ); } jpeg_create_decompress( &cinfo ); /* Make input. */ if( !(fp = im__file_open_read( filename, NULL, FALSE )) ) return( -1 ); eman.fp = fp; jpeg_stdio_src( &cinfo, fp ); /* Need to read in APP1 (EXIF metadata) and APP2 (ICC profile). */ jpeg_save_markers( &cinfo, JPEG_APP0 + 1, 0xffff ); jpeg_save_markers( &cinfo, JPEG_APP0 + 2, 0xffff ); /* Convert! */ result = read_jpeg_header( &cinfo, out, &invert_pels, shrink ); if( !header_only && !result ) result = read_jpeg_image( &cinfo, out, invert_pels ); /* Close and tidy. */ fclose( fp ); eman.fp = NULL; jpeg_destroy_decompress( &cinfo ); if( eman.pub.num_warnings != 0 ) { if( fail_on_warn ) { im_error( "im_jpeg2vips", "%s", im_error_buffer() ); result = -1; } else { im_warn( "im_jpeg2vips", _( "read gave %ld warnings" ), eman.pub.num_warnings ); im_warn( "im_jpeg2vips", "%s", im_error_buffer() ); } } return( result ); }