| <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" |
| "http://www.w3.org/TR/html4/loose.dtd"> |
| <html > |
| <head><title>Core C API</title> |
| <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> |
| <meta name="generator" content="TeX4ht (http://www.cse.ohio-state.edu/~gurari/TeX4ht/)"> |
| <meta name="originator" content="TeX4ht (http://www.cse.ohio-state.edu/~gurari/TeX4ht/)"> |
| <!-- 3,html --> |
| <meta name="src" content="vipsmanual.tex"> |
| <meta name="date" content="2010-06-09 21:39:00"> |
| <link rel="stylesheet" type="text/css" href="vipsmanual.css"> |
| </head><body |
| > |
| <!--l. 1--><div class="crosslinks"><p class="noindent">[<a |
| href="vipsmanualse9.html" >next</a>] [<a |
| href="vipsmanualse7.html" >prev</a>] [<a |
| href="vipsmanualse7.html#tailvipsmanualse7.html" >prev-tail</a>] [<a |
| href="#tailvipsmanualse8.html">tail</a>] [<a |
| href="vipsmanualch2.html#vipsmanualse8.html" >up</a>] </p></div> |
| <h3 class="sectionHead"><span class="titlemark">2.2 </span> <a |
| id="x14-370002.2"></a>Core C API</h3> |
| <!--l. 3--><p class="noindent" >VIPS is built on top of several other libraries, two of which, |
| glib and gobject, are exposed at various points in the C |
| API. |
| <!--l. 6--><p class="indent" > You can read up on glib at the GTK+ website: |
| <div class="verbatim" id="verbatim-51"> |
| http://www.gtk.org |
| </div> |
| <!--l. 10--><p class="nopar" > |
| <!--l. 12--><p class="indent" > There’s also an excellent book by Matthias Warkus, <span |
| class="ptmri7t-">The</span> |
| <span |
| class="ptmri7t-">Official GNOME 2 Developer’s Guide</span>, which covers the |
| same material in a tutorial manner. |
| <!--l. 16--><p class="noindent" > |
| <h4 class="subsectionHead"><span class="titlemark">2.2.1 </span> <a |
| id="x14-380002.2.1"></a>Startup</h4> |
| <!--l. 18--><p class="noindent" >Before calling any VIPS function, you need to start VIPS |
| up: |
| |
| |
| |
| <div class="verbatim" id="verbatim-52"> |
| int im_init_world( const char ⋆argv0 ); |
| </div> |
| <!--l. 22--><p class="nopar" > |
| <!--l. 24--><p class="indent" > The <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">argv0</span></span></span> argument is the value of <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">argv[0]</span></span></span> your |
| program was passed by the host operating system. |
| VIPS uses this with <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_guess_prefix()</span></span></span> and |
| <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_guess_libdir()</span></span></span> to try to find various VIPS data |
| files. |
| <!--l. 29--><p class="indent" > If you don’t call this function, VIPS will call it for you |
| the first time you use a VIPS function. But it won’t be able |
| to get the <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">argv0</span></span></span> value for you, so it may not be able to find |
| it’s data files. |
| <!--l. 33--><p class="indent" > VIPS also offers the optional: |
| <div class="verbatim" id="verbatim-53"> |
| GOptionGroup ⋆im_get_option_group( void ); |
| </div> |
| <!--l. 37--><p class="nopar" > |
| <!--l. 39--><p class="indent" > You can use this with GOption to parse your program’s |
| command-line arguments. It adds several useful VIPS flags, |
| including <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">--vips-concurrency</span></span></span>. |
| <!--l. 42--><p class="indent" > Figure <a |
| href="#x14-380012">2.2<!--tex4ht:ref: fg:hello --></a> shows both these functions in use. Again, the |
| GOption stuff is optional and just lets VIPS add some flags |
| to your program. You do need the <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_init_world()</span></span></span> |
| though. |
| |
| |
| |
| <!--l. 47--><p class="indent" > <a |
| id="x14-380012"></a><hr class="float"><div class="float" |
| > |
| |
| |
| |
| |
| <div class="verbatim" id="verbatim-54"> |
| #include <stdio.h> |
|  <br />#include <vips/vips.h> |
|  <br /> |
|  <br />static gboolean print_stuff; |
|  <br /> |
|  <br />static GOptionEntry options[] = { |
|  <br />  { "print", 'p', 0, G_OPTION_ARG_NONE, &print_stuff, |
|  <br />    "print \"hello world!\"", NULL }, |
|  <br />  { NULL } |
|  <br />}; |
|  <br /> |
|  <br />int |
|  <br />main( int argc, char ⋆⋆argv ) |
|  <br />{ |
|  <br />  GOptionContext ⋆context; |
|  <br />  GError ⋆error = NULL; |
|  <br /> |
|  <br />  if( im_init_world( argv[0] ) ) |
|  <br />    error_exit( "unable to start VIPS" ); |
|  <br /> |
|  <br />  context = g_option_context_new( "- my program" ); |
|  <br />  g_option_context_add_main_entries( context, |
|  <br />    options, "main" ); |
|  <br />  g_option_context_add_group( context, im_get_option_group() ); |
|  <br />  if( !g_option_context_parse( context, &argc, &argv, &error ) ) { |
|  <br />    if( error ) { |
|  <br />      fprintf( stderr, "%s\n", error->message ); |
|  <br />      g_error_free( error ); |
|  <br />    } |
|  <br />    error_exit( "try \"%s --help\"", g_get_prgname() ); |
|  <br />  } |
|  <br />  g_option_context_free( context ); |
|  <br /> |
|  <br />  if( print_stuff ) |
|  <br />    printf( "hello, world!\n" ); |
|  <br /> |
|  <br />  return( 0 ); |
|  <br />} |
| </div> |
| <!--l. 86--><p class="nopar" > |
| <br /><div class="caption" |
| ><span class="id">Figure 2.2: </span><span |
| class="content">Hello World for VIPS</span></div><!--tex4ht:label?: x14-380012 --> |
| |
| |
| |
| |
| </div><hr class="endfloat" /> |
| <h4 class="subsectionHead"><span class="titlemark">2.2.2 </span> <a |
| id="x14-390002.2.2"></a>Image descriptors</h4> |
| <!--l. 93--><p class="noindent" >The base level of the VIPS I/O system provides <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">IMAGE</span></span></span> |
| descriptors. An image represented by a descriptor may |
| be an image file on disc, an area of memory that has |
| been allocated for the image, an output file, a delayed |
| computation, and so on. Programs need (usually) only know |
| that they have a descriptor, they do not see many of the |
| details. Figure <a |
| href="#x14-390013">2.3<!--tex4ht:ref: fg:image --></a> shows the definition of the <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">IMAGE</span></span></span> |
| descriptor. |
| |
| |
| |
| |
| <!--l. 101--><p class="indent" > <a |
| id="x14-390013"></a><hr class="float"><div class="float" |
| > |
| |
| |
| |
| |
| <div class="verbatim" id="verbatim-55"> |
| typedef struct { |
|  <br />    /⋆ Fields from image header. |
|  <br />     ⋆/ |
|  <br />    int Xsize;             /⋆ Pels per line ⋆/ |
|  <br />    int Ysize;             /⋆ Lines ⋆/ |
|  <br />    int Bands;             /⋆ Number of bands ⋆/ |
|  <br />    int Bbits;             /⋆ Bits per band ⋆/ |
|  <br />    int BandFmt;           /⋆ Band format ⋆/ |
|  <br />    int Coding;            /⋆ Coding type ⋆/ |
|  <br />    int Type;              /⋆ Type of file ⋆/ |
|  <br />    float XRes;            /⋆ Horizontal res in pels/mm ⋆/ |
|  <br />    float YRes;            /⋆ Vertical res in pels/mm  ⋆/ |
|  <br />    int Length;            /⋆ Obsolete (unused) ⋆/ |
|  <br />    short Compression;     /⋆ Obsolete (unused) ⋆/ |
|  <br />    short Level;           /⋆ Obsolete (unused) ⋆/ |
|  <br />    int Xoffset;           /⋆ Position of origin ⋆/ |
|  <br />    int Yoffset; |
|  <br /> |
|  <br />    /⋆ Derived fields that may be read by the user. |
|  <br />     ⋆/ |
|  <br />    char ⋆filename;        /⋆ File name ⋆/ |
|  <br />    im_time_t ⋆time;       /⋆ Timing for eval callback ⋆/ |
|  <br />    int kill;              /⋆ Set to non-zero to block eval ⋆/ |
|  <br /> |
|  <br />    ... and lots of other private fields used by VIPS for |
|  <br />    ... housekeeping. |
|  <br />} IMAGE; |
| </div> |
| <!--l. 129--><p class="nopar" > |
| <br /><div class="caption" |
| ><span class="id">Figure 2.3: </span><span |
| class="content">The <span |
| class="pcrr7t-">IMAGE </span>descriptor</span></div><!--tex4ht:label?: x14-390013 --> |
| |
| |
| |
| |
| </div><hr class="endfloat" /> |
| <!--l. 134--><p class="indent" > The first set of fields simply come from the image file |
| header: see <span |
| class="cmsy-10">§</span><a |
| href="vipsmanualse2.html#x7-80001.2.1">1.2.1<!--tex4ht:ref: sec:header --></a> for a full description of all the fields. The |
| next set are maintained for you by the VIPS I/O system. |
| <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">filename</span></span></span> is the name of the file that this image came |
| from. If you have attached an eval callback to this image, |
| <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">time</span></span></span> points to a set of timing statistics which can |
| be used by user-interfaces built on VIPS to provide |
| feedback about the progress of evaluation — see <span |
| class="cmsy-10">§</span><a |
| href="#x14-450002.2.8">2.2.8<!--tex4ht:ref: sec:eval --></a>. |
| Finally, if you set <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">kill</span></span></span> to non-zero, VIPS will block any |
| pipelines which use this descriptor as an intermediate. See |
| <span |
| class="cmsy-10">§</span><a |
| href="#x14-570002.2.12">2.2.12<!--tex4ht:ref: sec:block --></a>. |
| <!--l. 144--><p class="indent" > The remaining fields are private and are used by VIPS for |
| housekeeping. |
| <h4 class="subsectionHead"><span class="titlemark">2.2.3 </span> <a |
| id="x14-400002.2.3"></a>Header fields</h4> |
| <!--l. 149--><p class="noindent" >You can access header fields either directly (as <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im->Xsize</span></span></span>, |
| for example) or programmatically with <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_header_int()</span></span></span> |
| and friends. For example: |
| <div class="verbatim" id="verbatim-56"> |
| int i; |
|  <br /> |
|  <br />im_header_int( im, "Xsize", &i ); |
| </div> |
| <!--l. 157--><p class="nopar" > |
| <!--l. 159--><p class="indent" > There’s also <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_header_map()</span></span></span> to loop over header |
| fields, and <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_header_get_type</span></span></span> to test the type of |
| fields. These functions work for image meta fields as well, |
| see <span |
| class="cmsy-10">§</span><a |
| href="#x14-430002.2.6">2.2.6<!--tex4ht:ref: sec:meta --></a>. |
| <!--l. 163--><p class="noindent" > |
| <h4 class="subsectionHead"><span class="titlemark">2.2.4 </span> <a |
| id="x14-410002.2.4"></a>Opening and closing</h4> |
| <!--l. 166--><p class="noindent" >Descriptors are created with <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_open()</span></span></span>. You can also |
| read images with the format system: see <span |
| class="cmsy-10">§</span><a |
| href="vipsmanualse11.html#x17-740002.5">2.5<!--tex4ht:ref: sec:format --></a>. The two |
| APIs are complimentary, though <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_open()</span></span></span> is more |
| useful. |
| <!--l. 170--><p class="indent" > At the command-line, try: |
| |
| |
| |
| <div class="verbatim" id="verbatim-57"> |
| $ vips --list classes |
| </div> |
| <!--l. 174--><p class="nopar" > |
| <!--l. 176--><p class="indent" > /noindent to see a list of all the supported file formats. |
| <!--l. 179--><p class="indent" > <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_open()</span></span></span> takes a file name and a string representing |
| the mode with which the descriptor is to be opened: |
| <div class="verbatim" id="verbatim-58"> |
| IMAGE ⋆im_open( const char ⋆filename, |
|  <br />  const char ⋆mode ) |
| </div> |
| <!--l. 185--><p class="nopar" > |
| <!--l. 187--><p class="indent" > The possible values for mode are: |
| <dl class="description"><dt class="description"> |
| <span |
| class="pcrb7t-">"r"</span> </dt><dd |
| class="description">The file is opened read-only. If you open |
| a non-VIPS image, or a VIPS image written |
| on a machine with a different byte ordering, |
| <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_open()</span></span></span> will automatically convert it to |
| native VIPS format. If the underlying file does not |
| support random access (JPEG, for example), the |
| entire file will be converted in memory. |
| <!--l. 198--><p class="noindent" >VIPS can read images in many file formats. You |
| can control the details of the conversion with extra |
| characters embedded in the filename. For example: |
| |
| |
| |
| <div class="verbatim" id="verbatim-59"> |
| fred = im_open( "fred.tif:2", |
|  <br />  "r" ); |
| </div> |
| <!--l. 204--><p class="nopar" > |
| <!--l. 206--><p class="noindent" >will read page 2 of a multi-page TIFF. See the man |
| pages for details. |
| </dd><dt class="description"> |
| <span |
| class="pcrb7t-">"w"</span> </dt><dd |
| class="description">An <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">IMAGE</span></span></span> descriptor is created which, when written |
| to, will write pixels to disc in the specified file. Any |
| existing file of that name is deleted. |
| <!--l. 214--><p class="noindent" >VIPS looks at the filename suffix to determine the |
| save format. If there is no suffix, or the filename |
| ends in <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">".v"</span></span></span>, the image is written in VIPS native |
| format. |
| <!--l. 218--><p class="noindent" >If you want to control the details of the conversion to |
| the disc format (such as setting the Q factor for |
| a JPEG, for example), you embed extra control |
| characters in the filename. For example: |
| <div class="verbatim" id="verbatim-60"> |
| fred = im_open( "fred.jpg:95", |
|  <br />  "w" ); |
| </div> |
| <!--l. 225--><p class="nopar" > |
| <!--l. 227--><p class="noindent" >writes to <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">fred</span></span></span> will write a JPEG with Q 95. Again, |
| see the man pages for the conversion functions for |
| details. |
| </dd><dt class="description"> |
| <span |
| class="pcrb7t-">"t"</span> </dt><dd |
| class="description">As the <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">"w"</span></span></span> mode, but pels written to the descriptor |
| will be saved in a temporary memory buffer. |
| </dd><dt class="description"> |
| <span |
| class="pcrb7t-">"p"</span> </dt><dd |
| class="description">This creates a special partial image. Partial images |
| are used to join VIPS operations together, see |
| <span |
| class="cmsy-10">§</span><a |
| href="#x14-520002.2.12">2.2.12<!--tex4ht:ref: sec:joinup --></a>. |
| </dd><dt class="description"> |
| <span |
| class="pcrb7t-">"rw"</span> </dt><dd |
| class="description">As the <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">"r"</span></span></span> mode, but the image is mapped into the |
| caller’s address space read-write. This mode is only |
| provided for the use of paintbox-style applications |
| which need to directly modify an image. Most |
| programs should use the <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">"w"</span></span></span> mode for image |
| output. |
| </dd></dl> |
| <!--l. 247--><p class="indent" > If an error occurs opening the image, <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_open()</span></span></span> calls |
| <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_error()</span></span></span> with a string describing the cause of the |
| error and returns <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">NULL</span></span></span>. <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_error()</span></span></span> has type |
| |
| |
| |
| <div class="verbatim" id="verbatim-61"> |
| void im_error( const char ⋆domain, |
|  <br />  const char ⋆format, ... ) |
| </div> |
| <!--l. 254--><p class="nopar" > |
| <!--l. 256--><p class="noindent" >The first argument is a string giving the name of the thing |
| that raised the error (just <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">"im_open"</span></span></span>, for example). |
| The format and subsequent arguments work exactly as |
| <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">printf()</span></span></span>. It formats the message and appends the string |
| formed to the error log. You can get a pointer to the error |
| text with <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_error_buffer()</span></span></span>. |
| <div class="verbatim" id="verbatim-62"> |
| const char ⋆im_error_buffer() |
| </div> |
| <!--l. 265--><p class="nopar" > |
| <!--l. 267--><p class="noindent" >Applications may display this string to give users feedback |
| about the cause of the error. The VIPS exit function, |
| <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">error_exit()</span></span></span>, prints <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_error_buffer()</span></span></span> to |
| <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">stderr</span></span></span> and terminates the program with an error code of |
| 1. |
| |
| |
| |
| <div class="verbatim" id="verbatim-63"> |
| void error_exit( const char ⋆format, |
|  <br />  ... ) |
| </div> |
| <!--l. 276--><p class="nopar" > |
| <!--l. 278--><p class="noindent" >There are other functions for handling errors: see the man |
| page for <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_error()</span></span></span>. |
| <!--l. 282--><p class="indent" > Descriptors are closed with <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_close()</span></span></span>. It has |
| type: |
| <div class="verbatim" id="verbatim-64"> |
| int im_close( IMAGE ⋆im ) |
| </div> |
| <!--l. 286--><p class="nopar" > |
| <!--l. 288--><p class="indent" > <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_close()</span></span></span> returns 0 on success and non-zero on |
| error. |
| <!--l. 290--><p class="noindent" > |
| <h4 class="subsectionHead"><span class="titlemark">2.2.5 </span> <a |
| id="x14-420002.2.5"></a>Examples</h4> |
| <!--l. 293--><p class="noindent" >As an example, Figure <a |
| href="#x14-420002.2.5">2.2.5<!--tex4ht:ref: fg:widthheight --></a> will print the width and height |
| of an image stored on disc. |
| |
| |
| |
| <!--l. 297--><p class="indent" > <a |
| id="x14-420014"></a><hr class="float"><div class="float" |
| > |
| |
| |
| |
| |
| <div class="verbatim" id="verbatim-65"> |
| #include <stdio.h> |
|  <br />#include <vips/vips.h> |
|  <br /> |
|  <br />int |
|  <br />main( int argc, char ⋆⋆argv ) |
|  <br />{ |
|  <br />  IMAGE ⋆im; |
|  <br /> |
|  <br />  /⋆ Check arguments. |
|  <br />   ⋆/ |
|  <br />  if( im_init_world( argv[0] ) ) |
|  <br />    error_exit( "unable to start VIPS" ); |
|  <br />  if( argc != 2 ) |
|  <br />    error_exit( "usage: %s filename", argv[0] ); |
|  <br /> |
|  <br />  /⋆ Open file. |
|  <br />   ⋆/ |
|  <br />  if( !(im = im_open( argv[1], "r" )) ) |
|  <br />    error_exit( "unable to open %s for input", argv[1] ); |
|  <br /> |
|  <br />  /⋆ Process. |
|  <br />   ⋆/ |
|  <br />  printf( "width = %d, height = %d\n", im->Xsize, im->Ysize ); |
|  <br /> |
|  <br />  /⋆ Close. |
|  <br />   ⋆/ |
|  <br />  if( im_close( im ) ) |
|  <br />      error_exit( "unable to close %s", argv[1] ); |
|  <br /> |
|  <br />  return( 0 ); |
|  <br />} |
| </div> |
| <!--l. 329--><p class="nopar" > |
| <br /><div class="caption" |
| ><span class="id">Figure 2.4: </span><span |
| class="content">Print width and height of an image</span></div><!--tex4ht:label?: x14-420014 --> |
| |
| |
| |
| |
| </div><hr class="endfloat" /> |
| <!--l. 334--><p class="indent" > To compile this example, use: |
| <div class="verbatim" id="verbatim-66"> |
| cc ‘pkg-config vips-7.14 \ |
|  <br />  --cflags --libs‘ myfunc.c |
| </div> |
| <!--l. 339--><p class="nopar" > |
| <!--l. 341--><p class="indent" > As a slightly more complicated example, Figure <a |
| href="#x14-420002.2.5">2.2.5<!--tex4ht:ref: fg:negative --></a> |
| will calculate the photographic negative of an image. |
| |
| |
| |
| <!--l. 345--><p class="indent" > <a |
| id="x14-420025"></a><hr class="float"><div class="float" |
| > |
| |
| |
| |
| |
| <div class="verbatim" id="verbatim-67"> |
| #include <stdio.h> |
|  <br />#include <vips/vips.h> |
|  <br /> |
|  <br />int |
|  <br />main( int argc, char ⋆⋆argv ) |
|  <br />{ |
|  <br />  IMAGE ⋆in, ⋆out; |
|  <br /> |
|  <br />  /⋆ Check arguments. |
|  <br />   ⋆/ |
|  <br />  if( im_init_world( argv[0] ) ) |
|  <br />    error_exit( "unable to start VIPS" ); |
|  <br />  if( argc != 3 ) |
|  <br />    error_exit( "usage: %s infile outfile", argv[0] ); |
|  <br /> |
|  <br />  /⋆ Open images for read and write, invert, update the history with our |
|  <br />   ⋆ args, and close. |
|  <br />   ⋆/ |
|  <br />  if( !(in = im_open( argv[1], "r" )) || |
|  <br />    !(out = im_open( argv[2], "w" )) || |
|  <br />    im_invert( in, out ) || |
|  <br />    im_updatehist( out, argc, argv ) || |
|  <br />    im_close( in ) || |
|  <br />    im_close( out ) ) |
|  <br />    error_exit( argv[0] ); |
|  <br /> |
|  <br />  return( 0 ); |
|  <br />} |
| </div> |
| <!--l. 374--><p class="nopar" > |
| <br /><div class="caption" |
| ><span class="id">Figure 2.5: </span><span |
| class="content">Find photographic negative</span></div><!--tex4ht:label?: x14-420025 --> |
| |
| |
| |
| |
| </div><hr class="endfloat" /> |
| <h4 class="subsectionHead"><span class="titlemark">2.2.6 </span> <a |
| id="x14-430002.2.6"></a>Metadata</h4> |
| <!--l. 382--><p class="noindent" >VIPS lets you attach arbitrary metadata to an IMAGE. For |
| example, ICC profiles, EXIF tags, image history, whatever |
| you like. VIPS will efficiently propagate metadata as images |
| are processed (usually just by copying pointers) and will |
| automatically save and load metadata from VIPS files (see |
| <span |
| class="cmsy-10">§</span><a |
| href="vipsmanualse2.html#x7-80001.2.1">1.2.1<!--tex4ht:ref: sec:header --></a>). |
| <!--l. 388--><p class="indent" > A piece of metadata is a value and an identifying name. A |
| set of convenience functions let you set and get int, double, |
| string and blob. For example: |
| <div class="verbatim" id="verbatim-68"> |
| int im_meta_set_int( IMAGE ⋆, |
|  <br />  const char ⋆field, int ); |
|  <br />int im_meta_get_int( IMAGE ⋆, |
|  <br />  const char ⋆field, int ⋆ ); |
| </div> |
| <!--l. 397--><p class="nopar" > |
| <!--l. 399--><p class="indent" > So you can do: |
| |
| |
| |
| <div class="verbatim" id="verbatim-69"> |
| if( im_meta_set_int( im, "poop", 42 ) ) |
|  <br />  return( -1 ); |
| </div> |
| <!--l. 404--><p class="nopar" > |
| <!--l. 406--><p class="noindent" >to create an int called <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">"poop"</span></span></span>, then at some later point |
| (possibly much, much later), in an image distantly derived |
| from <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im</span></span></span>, you can use: |
| <div class="verbatim" id="verbatim-70"> |
| int i; |
|  <br /> |
|  <br />if( im_meta_get_int( im, "poop", &i ) ) |
|  <br />  return( -1 ); |
| </div> |
| <!--l. 415--><p class="nopar" > |
| <!--l. 417--><p class="noindent" >And get the value 42 back. |
| <!--l. 420--><p class="indent" > You can use <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_meta_set()</span></span></span> and <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_meta_get()</span></span></span> |
| to attach arbitrary <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">GValue</span></span></span> to images. See the man page for |
| <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_meta_set()</span></span></span> for full details. |
| <!--l. 424--><p class="indent" > You can test for a field being present with |
| <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_meta_get_type()</span></span></span> (you’ll get <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">G_TYPE_INT</span></span></span> back |
| for <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">"poop"</span></span></span>, for example, or 0 if it is not defined for this |
| image). |
| <!--l. 428--><p class="noindent" > |
| <h4 class="subsectionHead"><span class="titlemark">2.2.7 </span> <a |
| id="x14-440002.2.7"></a>History</h4> |
| <!--l. 431--><p class="noindent" >VIPS tracks the history of an image, that is, the sequence of |
| operations which have led to the creation of an image. You |
| can view a VIPS image’s history with the <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">header</span></span></span> |
| command, or with <span |
| class="pcrr7t-">nip2</span>’s <span |
| class="pcrr7t-">View Header </span>menu. |
| Whenever an application performs an action, it should |
| append a line of shell script to the history which would |
| perform the same action. |
| <!--l. 437--><p class="indent" > The call to <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_updatehist()</span></span></span> in Figure <a |
| href="#x14-420002.2.5">2.2.5<!--tex4ht:ref: fg:negative --></a> adds a |
| line to the image history noting the invocation of this |
| program, its arguments, and the time and date at which it |
| was run. You may also find <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_histlin()</span></span></span> helpful. It has |
| type: |
| |
| |
| |
| <div class="verbatim" id="verbatim-71"> |
| void im_histlin( IMAGE ⋆im, |
|  <br />  const char ⋆fmt, ... ) |
| </div> |
| <!--l. 445--><p class="nopar" > |
| <!--l. 447--><p class="noindent" >It formats its arguments as <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">printf()</span></span></span> and appends the |
| string formed to the image history. |
| <!--l. 451--><p class="indent" > You read an image’s history with <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_history_get()</span></span></span>. |
| It returns the entire history of an image, one action per line. |
| No need to free the result. |
| <div class="verbatim" id="verbatim-72"> |
| const char ⋆ |
|  <br />  im_history_get( IMAGE ⋆im ); |
| </div> |
| <!--l. 457--><p class="nopar" > |
| <!--l. 459--><p class="noindent" > |
| <h4 class="subsectionHead"><span class="titlemark">2.2.8 </span> <a |
| id="x14-450002.2.8"></a>Eval callbacks</h4> |
| <!--l. 462--><p class="noindent" >VIPS lets you attach callbacks to image descriptors. These |
| are functions you provide which VIPS will call when |
| certain events occur. See <span |
| class="cmsy-10">§</span><a |
| href="vipsmanualse15.html#x22-980003.3.6">3.3.6<!--tex4ht:ref: sec:callback --></a> for more detail. |
| <!--l. 466--><p class="indent" > Eval callbacks are called repeatedly during evaluation |
| and can be used by user-interface programs to give feedback |
| about the progress of evaluation. |
| <!--l. 469--><p class="noindent" > |
| <h4 class="subsectionHead"><span class="titlemark">2.2.9 </span> <a |
| id="x14-460002.2.9"></a>Detailed rules for descriptors</h4> |
| <!--l. 471--><p class="noindent" >These rules are intended to answer awkward questions. |
| <!--l. 473--><p class="indent" > |
| <ol class="enumerate1" > |
| <li |
| class="enumerate" id="x14-46002x1">You can output to a descriptor only once. |
| </li> |
| <li |
| class="enumerate" id="x14-46004x2">You can use a descriptor as an input many times. |
| </li> |
| <li |
| class="enumerate" id="x14-46006x3">You can only output to a descriptor that was opened |
| with modes <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">"w"</span></span></span>, <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">"t"</span></span></span> and <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">"p"</span></span></span>. |
| </li> |
| <li |
| class="enumerate" id="x14-46008x4">You can only use a descriptor as input if it was |
| opened with modes <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">"r"</span></span></span> or <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">"rw"</span></span></span>. |
| </li> |
| <li |
| class="enumerate" id="x14-46010x5">If you have output to a descriptor, you may |
| subsequently use it as an input. <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">"w"</span></span></span> descriptors are |
| automatically changed to <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">"r"</span></span></span> descriptors. |
| <!--l. 494--><p class="noindent" >If the function you are passing the descriptor to |
| uses WIO (see <span |
| class="cmsy-10">§</span><a |
| href="#x14-580002.2.12">2.2.12<!--tex4ht:ref: sec:limit --></a>), then <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">"p"</span></span></span> descriptors |
| become <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">"t"</span></span></span>. If the function you are passing the |
| descriptor to uses PIO, then <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">"p"</span></span></span> descriptors are |
| unchanged. |
| </li></ol> |
| |
| |
| |
| <!--l. 501--><p class="noindent" > |
| <h4 class="subsectionHead"><span class="titlemark">2.2.10 </span> <a |
| id="x14-470002.2.10"></a>Automatic resource deallocation</h4> |
| <!--l. 503--><p class="noindent" >VIPS lets you allocate resources local to an image descriptor, |
| that is, when the descriptor is closed, all resources which |
| were allocated local to that descriptor are automatically |
| released for you. |
| <!--l. 507--><p class="noindent" > |
| <h5 class="subsubsectionHead"><a |
| id="x14-480002.2.10"></a>Local image descriptors</h5> |
| <!--l. 509--><p class="noindent" >VIPS provides a function which will open a new image |
| local to an existing image. <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_open_local()</span></span></span> has |
| type: |
| <div class="verbatim" id="verbatim-73"> |
| IMAGE ⋆im_open_local( IMAGE ⋆im, |
|  <br />  const char ⋆filename, |
|  <br />  const char ⋆mode ) |
| </div> |
| <!--l. 516--><p class="nopar" > |
| <!--l. 518--><p class="indent" > It behaves exactly as <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_open()</span></span></span>, except that you do |
| not need to close the descriptor it returns. It will be |
| closed automatically when its parent descriptor <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im</span></span></span> is |
| closed. |
| |
| |
| |
| <!--l. 523--><p class="indent" > <a |
| id="x14-480016"></a><hr class="float"><div class="float" |
| > |
| |
| |
| |
| |
| <div class="verbatim" id="verbatim-74"> |
| /⋆ Add another image to the accumulated total. |
|  <br /> ⋆/ |
|  <br />static int |
|  <br />sum1( IMAGE ⋆acc, IMAGE ⋆⋆in, int nin, IMAGE ⋆out ) |
|  <br />{ |
|  <br />    IMAGE ⋆t; |
|  <br /> |
|  <br />    if( nin == 0 ) |
|  <br />        /⋆ All done ... copy to out. |
|  <br />         ⋆/ |
|  <br />        return( im_copy( acc, out ) ); |
|  <br /> |
|  <br />    /⋆ Make a new intermediate, and add to it.. |
|  <br />     ⋆/ |
|  <br />    return( !(t = im_open_local( out, "sum1:1", "p" )) || |
|  <br />        im_add( acc, in[0], t ) || |
|  <br />        sum1( t, in + 1, nin - 1, out ) ); |
|  <br />} |
|  <br /> |
|  <br />/⋆ Sum the array of images in[]. nin is the number of images in |
|  <br /> ⋆ in[], out is the descriptor we write the final image to. |
|  <br /> ⋆/ |
|  <br />int |
|  <br />total( IMAGE ⋆⋆in, int nin, IMAGE ⋆out ) |
|  <br />{ |
|  <br />    /⋆ Check that we have at least one image. |
|  <br />     ⋆/ |
|  <br />    if( nin <= 0 ) { |
|  <br />        im_error( "total", "nin should be > 0" ); |
|  <br />        return( -1 ); |
|  <br />    } |
|  <br /> |
|  <br />    /⋆ More than 1, sum recursively. |
|  <br />     ⋆/ |
|  <br />    return( sum1( in[0], in + 1, nin - 1, out ) ); |
|  <br />} |
| </div> |
| <!--l. 560--><p class="nopar" > |
| <br /><div class="caption" |
| ><span class="id">Figure 2.6: </span><span |
| class="content">Sum an array of images</span></div><!--tex4ht:label?: x14-480016 --> |
| |
| |
| |
| |
| </div><hr class="endfloat" /> |
| <!--l. 565--><p class="indent" > Figure <a |
| href="#x14-480016">2.6<!--tex4ht:ref: fg:addemup --></a> is a function which will sum an array of |
| images. We need never close any of the (unknown) number |
| of intermediate images which we open. They will all be |
| closed for us by our caller, when our caller finally closes |
| <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">out</span></span></span>. VIPS lets local images themselves have local images |
| and automatically makes sure that all are closed in the |
| correct order. |
| <!--l. 571--><p class="indent" > It is very important that these intermediate images are |
| made local to <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">out</span></span></span> rather than <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">in</span></span></span>, for reasons which should |
| become apparent in the section on combining operations |
| below. |
| <!--l. 575--><p class="indent" > There’s also <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_open_local_array()</span></span></span> for when |
| you need a lot of local descriptors, see the man page. |
| <h5 class="subsubsectionHead"><a |
| id="x14-490002.2.10"></a>Local memory allocation</h5> |
| <!--l. 581--><p class="noindent" >VIPS includes a set of functions for memory allocation |
| local to an image descriptor. The base memory allocation |
| function is <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_malloc()</span></span></span>. It has type: |
| <div class="verbatim" id="verbatim-75"> |
| void ⋆im_malloc( IMAGE ⋆, size_t ) |
| </div> |
| <!--l. 587--><p class="nopar" > |
| <!--l. 589--><p class="indent" > It operates exactly as the standard <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">malloc()</span></span></span> C library |
| function, except that the area of memory it allocates is local |
| to an image. If <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_malloc()</span></span></span> is unable to allocate |
| memory, it returns <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">NULL</span></span></span>. If you pass <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">NULL</span></span></span> instead of a |
| valid image descriptor, then <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_malloc()</span></span></span> allocates |
| memory globally and you must free it yourself at some |
| stage. |
| <!--l. 596--><p class="indent" > To free memory explicitly, use <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_free()</span></span></span>: |
| |
| |
| |
| <div class="verbatim" id="verbatim-76"> |
| int im_free( void ⋆ ) |
| </div> |
| <!--l. 600--><p class="nopar" > |
| <!--l. 602--><p class="noindent" ><span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_free()</span></span></span> always returns 0, so you can use it as an |
| argument to a callback. |
| <!--l. 606--><p class="indent" > Three macros make memory allocation even easier. |
| <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">IM_NEW()</span></span></span> allocates a new object. You give it a descriptor |
| and a type, and it returns a pointer to enough space to hold |
| an object of that type. It has type: |
| <div class="verbatim" id="verbatim-77"> |
| type-name ⋆IM_NEW( IMAGE ⋆, type-name ) |
| </div> |
| <!--l. 612--><p class="nopar" > |
| <!--l. 614--><p class="indent" > The second macro, <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">IM_ARRAY()</span></span></span>, is very similar, but |
| allocates space for an array of objects. Note that, unlike the |
| usual <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">calloc()</span></span></span> C library function, it does not initialise |
| the array to zero. It has type: |
| |
| |
| |
| <div class="verbatim" id="verbatim-78"> |
| type-name ⋆IM_ARRAY( IMAGE ⋆, int, type-name ) |
| </div> |
| <!--l. 620--><p class="nopar" > |
| <!--l. 622--><p class="indent" > Finally, <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">IM_NUMBER()</span></span></span> returns the number of elements |
| in an array of defined size. See the man pages for a series of |
| examples, or see <span |
| class="cmsy-10">§</span><a |
| href="vipsmanualse9.html#x15-600002.3.1">2.3.1<!--tex4ht:ref: sec:number --></a>. |
| <!--l. 626--><p class="noindent" > |
| <h5 class="subsubsectionHead"><a |
| id="x14-500002.2.10"></a>Other local operations</h5> |
| <!--l. 628--><p class="noindent" >The above facilities are implemented with the VIPS core |
| function <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_add_close_callback()</span></span></span>. You can use |
| this facility to make your own local resource allocators for |
| other types of object — see the manual page for more |
| help. |
| <!--l. 633--><p class="noindent" > |
| <h4 class="subsectionHead"><span class="titlemark">2.2.11 </span> <a |
| id="x14-510002.2.11"></a>Error handling</h4> |
| <!--l. 635--><p class="noindent" >All VIPS operations return 0 on success and non-zero on |
| error, setting <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_error()</span></span></span>. As a consequence, when a |
| VIPS function fails, you do not need to generate an error |
| message — you can simply propagate the error back up to |
| your caller. If however you detect some error yourself (for |
| example, the bad parameter in the example above), you |
| must call <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_error()</span></span></span> to let your caller know what the |
| problem was. |
| <!--l. 642--><p class="indent" > VIPS provides two more functions for error message |
| handling: <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_warn()</span></span></span> and <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_diag()</span></span></span>. These are |
| intended to be used for less serious messages, as their |
| names suggest. Currently, they simply format and print their |
| arguments to <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">stderr</span></span></span>, optionally suppressed by the setting |
| of an environment variable. Future releases of VIPS may |
| allow more sophisticated trapping of these functions to |
| allow their text to be easily presented to the user by VIPS |
| applications. See the manual pages. |
| <!--l. 650--><p class="noindent" > |
| <h4 class="subsectionHead"><span class="titlemark">2.2.12 </span> <a |
| id="x14-520002.2.12"></a>Joining operations together</h4> |
| <!--l. 653--><p class="noindent" >VIPS lets you join image processing operations together so |
| that they behave as a single unit. Figure <a |
| href="#x14-520017">2.7<!--tex4ht:ref: fg:join --></a> shows the |
| definition of the function <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_Lab2disp()</span></span></span> from the VIPS |
| library. This function converts an image in <span |
| class="ptmri7t-">CIE</span><span |
| class="ptmri7t-"> </span><span |
| class="cmmi-10">L</span><span |
| class="cmsy-7">*</span><span |
| class="cmmi-10">a</span><span |
| class="cmsy-7">*</span><span |
| class="cmmi-10">b</span><span |
| class="cmsy-7">*</span> |
| colour space to an RGB image for a monitor. The monitorcharacteristics (gamma, phosphor type, etc.) are described |
| by the <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_col_display</span></span></span> structure, see the man page for |
| <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_col_XYZ2rgb()</span></span></span>. |
| |
| |
| |
| <!--l. 661--><p class="indent" > <a |
| id="x14-520017"></a><hr class="float"><div class="float" |
| > |
| |
| |
| |
| |
| <div class="verbatim" id="verbatim-79"> |
| int |
|  <br />im_Lab2disp( IMAGE ⋆in, IMAGE ⋆out, struct im_col_display ⋆disp ) |
|  <br />{ |
|  <br />    IMAGE ⋆t1; |
|  <br /> |
|  <br />    if( !(t1 = im_open_local( out, "im_Lab2disp:1", "p" )) || |
|  <br />        im_Lab2XYZ( in, t1 ) || |
|  <br />        im_XYZ2disp( t1, out, disp ) ) |
|  <br />        return( -1 ); |
|  <br /> |
|  <br />    return( 0 ); |
|  <br />} |
| </div> |
| <!--l. 674--><p class="nopar" > |
| <br /><div class="caption" |
| ><span class="id">Figure 2.7: </span><span |
| class="content">Two image-processing operations joined together</span></div><!--tex4ht:label?: x14-520017 --> |
| |
| |
| |
| |
| </div><hr class="endfloat" /> |
| <!--l. 679--><p class="indent" > The special <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">"p"</span></span></span> mode (for partial) used to open |
| the image descriptor used as the intermediate image |
| in this function ‘glues’ the two operations together. |
| When you use <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_Lab2disp()</span></span></span>, the two operations |
| inside it will execute together and no extra storage |
| is necessary for the intermediate image (<span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">t1</span></span></span> in this |
| example). This is important if you want to process |
| images larger than the amount of RAM you have on your |
| machine. |
| <!--l. 686--><p class="indent" > As an added bonus, if you have more than one CPU in |
| your computer, the work will be automatically spread |
| across the processors for you. You can control this |
| parallelization with the <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">IM_CONCURRENCY</span></span></span> environment |
| variable, <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_concurrency_set()</span></span></span>, and with the |
| <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">--vips-concurrency</span></span></span> command-line switch. See the |
| man page for <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_generate()</span></span></span>. |
| <h5 class="subsubsectionHead"><a |
| id="x14-530002.2.12"></a>How it works</h5> |
| <!--l. 694--><p class="noindent" >When a VIPS function is asked to output to a <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">"p"</span></span></span> image |
| descriptor, all the fields in the descriptor are set (the output |
| image size and type are set, for example), but no image data |
| is actually generated. Instead, the function attaches |
| callbacks to the image descriptor which VIPS can use later |
| to generate any piece of the output image that might be |
| needed. |
| <!--l. 700--><p class="indent" > When a VIPS function is asked to output to a <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">"w"</span></span></span> or a |
| <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">"t"</span></span></span> descriptor (a real disc file or a real memory buffer), it |
| evaluates immediately and its evaluation in turn forces the |
| evaluation of any earlier <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">"p"</span></span></span> images. |
| <!--l. 705--><p class="indent" > In the example in Figure <a |
| href="#x14-520017">2.7<!--tex4ht:ref: fg:join --></a>, whether or not any pixels |
| are really processed when <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_Lab2disp()</span></span></span> is called |
| depends upon the mode in which <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">out</span></span></span> was opened. |
| If <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">out</span></span></span> is also a partial image, then no pixels will be |
| calculated — instead, a pipeline of VIPS operations |
| will be constructed behind the scenes and attached to |
| <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">out</span></span></span>. |
| <!--l. 711--><p class="indent" > Conversely, if <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">out</span></span></span> is a real image (that is, either <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">"w"</span></span></span> or |
| <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">"t"</span></span></span>), then the final VIPS operation in the function |
| (<span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_XYZ2disp()</span></span></span>) will output the entire image to <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">out</span></span></span>, |
| causing the earlier parts of <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_Lab2disp()</span></span></span> (and indeed |
| possibly some earlier pieces of program, if <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">in</span></span></span> was also a |
| <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">"p"</span></span></span> image) to run. |
| <!--l. 717--><p class="indent" > When a VIPS pipeline does finally evaluate, all of the |
| functions in the pipeline execute together, sucking image |
| data through the system in small pieces. As a consequence, |
| no intermediate images are generated, large amounts of |
| RAM are not needed, and no slow disc I/O needs to be performed. |
| <!--l. 722--><p class="indent" > Since VIPS partial I/O is demand-driven rather than |
| data-driven this works even if some of the operations |
| perform coordinate transformations. We could, for example, |
| include a call to <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_affine()</span></span></span>, which performs arbitrary |
| rotation and scaling, and everything would still work |
| correctly. |
| <!--l. 727--><p class="noindent" > |
| <h5 class="subsubsectionHead"><a |
| id="x14-540002.2.12"></a>Pitfalls with partials</h5> |
| <!--l. 729--><p class="noindent" >To go with all of the benefits that partial image I/O brings, |
| there are also some problems. The most serious is that you |
| are often not quite certain when computation will happen. |
| This can cause problems if you close an input file, thinking |
| that it is finished with, when in fact that file has not been |
| processed yet. Doing this results in dangling pointers and an |
| almost certain core-dump. |
| <!--l. 736--><p class="indent" > You can prevent this from happening with careful use of |
| <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_open_local()</span></span></span>. If you always open local to your |
| output image, you can be sure that the input will not be |
| closed before the output has been generated to a file |
| or memory buffer. You do not need to be so careful |
| with non-image arguments. VIPS functions which take |
| extra non-image arguments (a matrix, perhaps) are |
| careful to make their own copy of the object before |
| returning. |
| <!--l. 744--><p class="noindent" > |
| <h5 class="subsubsectionHead"><a |
| id="x14-550002.2.12"></a>Non-image output</h5> |
| <!--l. 746--><p class="noindent" >Some VIPS functions consume images, but make no image |
| output. <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_stats()</span></span></span> for example, scans an image |
| calculating various statistical values. When you use |
| <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_stats()</span></span></span>, it behaves as a data sink, sucking image |
| data through any earlier pipeline stages. |
| <!--l. 751--><p class="noindent" > |
| <h5 class="subsubsectionHead"><a |
| id="x14-560002.2.12"></a>Calculating twice</h5> |
| <!--l. 753--><p class="noindent" >In some circumstances, the same image data can be |
| generated twice. Figure <a |
| href="#x14-560018">2.8<!--tex4ht:ref: fg:thrmean --></a> is a function which finds the |
| mean value of an image, and writes a new image in which |
| pixels less than the mean are set to 0 and images greater |
| than the mean are set to 255. |
| |
| |
| |
| <!--l. 759--><p class="indent" > <a |
| id="x14-560018"></a><hr class="float"><div class="float" |
| > |
| |
| |
| |
| |
| <div class="verbatim" id="verbatim-80"> |
| int |
|  <br />threshold_at_mean( IMAGE ⋆in, IMAGE ⋆out ) |
|  <br />{ |
|  <br />    double mean; |
|  <br /> |
|  <br />    if( im_avg( in, &mean ) || |
|  <br />        im_moreconst( in, out, mean ) ) |
|  <br />        return( -1 ); |
|  <br /> |
|  <br />    return( 0 ); |
|  <br />} |
| </div> |
| <!--l. 771--><p class="nopar" > |
| <br /><div class="caption" |
| ><span class="id">Figure 2.8: </span><span |
| class="content">Threshold an image at the mean value</span></div><!--tex4ht:label?: x14-560018 --> |
| |
| |
| |
| |
| </div><hr class="endfloat" /> |
| <!--l. 776--><p class="indent" > This seems straightforward — but consider if image <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">in</span></span></span> |
| were a <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">"p"</span></span></span>, and represented the output of a large pipeline |
| of operations. The call to <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_avg()</span></span></span> would force the |
| evaluation of the entire pipeline, and throw it all away, |
| keeping only the average value. The subsequent call to |
| <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_moreconst()</span></span></span> will cause the pipeline to be evaluated |
| a second time. |
| <!--l. 782--><p class="indent" > When designing a program, it is sensible to pay attention |
| to these issues. It might be faster, in some cases, to output to |
| a file before calling <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_avg()</span></span></span>, find the average of the disc |
| file, and then run <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_moreconst()</span></span></span> from that. There’s |
| also <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_cache()</span></span></span> which can keep recent parts of a very |
| large image. |
| <h5 class="subsubsectionHead"><a |
| id="x14-570002.2.12"></a>Blocking computation</h5> |
| <!--l. 791--><p class="noindent" ><span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">IMAGE</span></span></span> descriptors have a flag called <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">kill</span></span></span> which can be |
| used to block computation. If <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im->kill</span></span></span> is set to a |
| non-zero value, then any VIPS pipelines which use <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im</span></span></span> as |
| an intermediate will fail with an error message. This |
| is useful for user-interface writers — suppose your |
| interface is forced to close an image which many other |
| images are using as a source of data. You can just set |
| the <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">kill</span></span></span> flag in all of the deleted image’s immediate |
| children and prevent any dangling pointers from being |
| followed. |
| <!--l. 800--><p class="noindent" > |
| <h5 class="subsubsectionHead"><a |
| id="x14-580002.2.12"></a>Limitations</h5> |
| <!--l. 803--><p class="noindent" >Not all VIPS operations are partial-aware. These non-partial |
| operations use a pre-VIPS 7.0 I/O scheme in which the |
| whole of the input image has to be present at the same time. |
| In some cases, this is because partial I/O simply makes no |
| sense — for example, a Fourier Transform can produce no |
| output until it has seen all of the input. <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_fwfft()</span></span></span> is |
| therefore not a partial operation. In other cases, we have |
| simply not got around to rewriting the old non-partial |
| operation in the newer partial style. |
| <!--l. 811--><p class="indent" > You can mix partial and non-partial VIPS operations |
| freely, without worrying about which type they are. The |
| only effect will be on the time your pipeline takes to |
| execute, and the memory requirements of the intermediate |
| images. VIPS uses the following rules when you mix the |
| two styles of operation: |
| <!--l. 816--><p class="indent" > |
| <ol class="enumerate1" > <li |
| class="enumerate" id="x14-58002x1">When a non-partial operation is asked to output to |
| a partial image descriptor, the <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">"p"</span></span></span> descriptor is |
| magically transformed into a <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">"t"</span></span></span> descriptor. |
| </li> |
| <li |
| class="enumerate" id="x14-58004x2">When a non-partial operation is asked to read from |
| a <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">"p"</span></span></span> descriptor, the <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">"p"</span></span></span> descriptor is turned into |
| a <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">"t"</span></span></span> type, and any earlier stages in the pipeline |
| forced to evaluate into that memory buffer. |
| <!--l. 828--><p class="noindent" >The non-partial operation then processes from the |
| memory buffer. |
| </li></ol> |
| <!--l. 832--><p class="indent" > These rules have the consequence that you may only |
| process very large images if you only use partial operations. |
| If you use any non-partial operations, then parts of your |
| pipelines will fall back to old whole-image I/O and you will |
| need to think carefully about where your intermediates |
| should be stored. |
| |
| |
| |
| <!--l. 1--><div class="crosslinks"><p class="noindent">[<a |
| href="vipsmanualse9.html" >next</a>] [<a |
| href="vipsmanualse7.html" >prev</a>] [<a |
| href="vipsmanualse7.html#tailvipsmanualse7.html" >prev-tail</a>] [<a |
| href="vipsmanualse8.html" >front</a>] [<a |
| href="vipsmanualch2.html#vipsmanualse8.html" >up</a>] </p></div> |
| <!--l. 1--><p class="indent" > <a |
| id="tailvipsmanualse8.html"></a> |
| </body></html> |