| <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" |
| "http://www.w3.org/TR/html4/loose.dtd"> |
| <html > |
| <head><title>Programming WIO operations</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="vipsmanualse15.html" >next</a>] [<a |
| href="vipsmanualse13.html" >prev</a>] [<a |
| href="vipsmanualse13.html#tailvipsmanualse13.html" >prev-tail</a>] [<a |
| href="#tailvipsmanualse14.html">tail</a>] [<a |
| href="vipsmanualch3.html#vipsmanualse14.html" >up</a>] </p></div> |
| <h3 class="sectionHead"><span class="titlemark">3.2 </span> <a |
| id="x21-880003.2"></a>Programming WIO operations</h3> |
| <!--l. 3--><p class="noindent" >WIO is the style for you if you want ease of programming, |
| or if your algorithm must have the whole of the input image |
| available at the same time. For example, a Fourier transform |
| operation is unable to produce any output until it has seen |
| the whole of the input image. |
| <!--l. 8--><p class="noindent" > |
| <h4 class="subsectionHead"><span class="titlemark">3.2.1 </span> <a |
| id="x21-890003.2.1"></a>Input from an image</h4> |
| <!--l. 10--><p class="noindent" >In WIO input, the whole of the image data is made available |
| to the program via the <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">data</span></span></span> field of the descriptor. To make |
| an image ready for reading in this style, programs should |
| call <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_incheck()</span></span></span>: |
| <div class="verbatim" id="verbatim-127"> |
| int im_incheck( IMAGE ⋆im ) |
| </div> |
| <!--l. 16--><p class="nopar" > |
| <!--l. 18--><p class="noindent" >If it succeeds, it returns 0, if it fails, it returns non-zero and |
| sets <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_error()</span></span></span>. On success, VIPS guarantees that all of |
| the user-accessible fields in the descriptor contain valid |
| data, and that all of the image data may be read by simply |
| reading from the <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">data</span></span></span> field (see below for an example). |
| This will only work for images less than about 2GB in |
| size. |
| <!--l. 26--><p class="indent" > VIPS has some simple macros to help address calculations |
| on images: |
| |
| |
| |
| <div class="verbatim" id="verbatim-128"> |
| int IM_IMAGE_SIZEOF_ELEMENT( IMAGE ⋆ ) |
|  <br />int IM_IMAGE_SIZEOF_PEL( IMAGE ⋆ ) |
|  <br />int IM_IMAGE_SIZEOF_LINE( IMAGE ⋆ ) |
|  <br />int IM_IMAGE_N_ELEMENTS( IMAGE ⋆ ) |
|  <br />char ⋆IM_IMAGE_ADDR( IMAGE ⋆, |
|  <br />  int x, int y ) |
| </div> |
| <!--l. 35--><p class="nopar" > |
| <!--l. 37--><p class="noindent" >These macros calculate <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">sizeof()</span></span></span> a band element, a pel |
| and a horizontal line of pels. <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">IM_IMAGE_N_ELEMENTS</span></span></span> |
| returns the number of band elements across an image. |
| <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">IM_IMAGE_ADDR</span></span></span> calculates the address of a pixel in an |
| image. If <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">DEBUG</span></span></span> is defined, it does bounds checking |
| too. |
| |
| |
| |
| |
| <!--l. 44--><p class="indent" > <a |
| id="x21-890011"></a><hr class="float"><div class="float" |
| > |
| |
| |
| |
| |
| <div class="verbatim" id="verbatim-129"> |
| #include <stdio.h> |
|  <br />#include <stdlib.h> |
|  <br /> |
|  <br />#include <vips/vips.h> |
|  <br /> |
|  <br />int |
|  <br />average( IMAGE ⋆im, double ⋆out ) |
|  <br />{ |
|  <br />  int x, y; |
|  <br />  long total; |
|  <br /> |
|  <br />  /⋆ Prepare for reading. |
|  <br />   ⋆/ |
|  <br />  if( im_incheck( im ) ) |
|  <br />    return( -1 ); |
|  <br /> |
|  <br />  /⋆ Check that this is the kind of image we can process. |
|  <br />   ⋆/ |
|  <br />  if( im->BandFmt != IM_BANDFMT_UCHAR || |
|  <br />    im->Coding != IM_CODING_NONE ) { |
|  <br />    im_error( "average", "uncoded uchar images only" ); |
|  <br />    return( -1 ); |
|  <br />  } |
|  <br /> |
|  <br />  /⋆ Loop over the image, summing pixels. |
|  <br />   ⋆/ |
|  <br />  total = 0; |
|  <br />  for( y = 0; y < im->Ysize; y++ ) { |
|  <br />    unsigned char ⋆p = (unsigned char ⋆) IM_IMAGE_ADDR( im, 0, y ); |
|  <br /> |
|  <br />    for( x = 0; x < IM_IMAGE_N_ELEMENTS( im ); x++ ) |
|  <br />      total += p[x]; |
|  <br />  } |
|  <br /> |
|  <br />  /⋆ Calculate average. |
|  <br />   ⋆/ |
|  <br />  ⋆out = (double) total / |
|  <br />    (IM_IMAGE_N_ELEMENTS( im ) ⋆ im->Ysize)); |
|  <br /> |
|  <br />  /⋆ Success! |
|  <br />   ⋆/ |
|  <br />  return( 0 ); |
|  <br />} |
| </div> |
| <!--l. 88--><p class="nopar" > |
| <br /><div class="caption" |
| ><span class="id">Figure 3.1: </span><span |
| class="content">Find average of image</span></div><!--tex4ht:label?: x21-890011 --> |
| |
| |
| |
| </div><hr class="endfloat" /> |
| <!--l. 93--><p class="indent" > Figure <a |
| href="#x21-890011">3.1<!--tex4ht:ref: fg:average --></a> is a simple WIO operation which calculates |
| the average of an unsigned char image. It will work for any |
| size image, with any number of bands. See <span |
| class="cmsy-10">ยง</span><a |
| href="#x21-910003.2.3">3.2.3<!--tex4ht:ref: sec:poly --></a> for |
| techniques for making operations which will work for any |
| image type. This operation might be called from an |
| application with: |
| <div class="verbatim" id="verbatim-130"> |
| #include <stdio.h> |
|  <br />#include <stdlib.h> |
|  <br /> |
|  <br />#include <vips/vips.h> |
|  <br /> |
|  <br />void |
|  <br />find_average( char ⋆name ) |
|  <br />{ |
|  <br />  IMAGE ⋆im; |
|  <br />  double avg; |
|  <br /> |
|  <br />  if( !(im = im_open( name, "r" )) || |
|  <br />    average( im, &avg ) || |
|  <br />    im_close( im ) ) |
|  <br />    error_exit( "failure!" ); |
|  <br /> |
|  <br />  printf( "Average of \"%s\" is %G\n", |
|  <br />    name, avg ); |
|  <br />} |
| </div> |
| <!--l. 119--><p class="nopar" > |
| <!--l. 121--><p class="noindent" >When you write an image processing operation, you can test |
| it by writing a VIPS function descriptor and calling it from |
| the <span |
| class="pcrr7t-">vips </span>universal main program, or from the <span |
| class="pcrr7t-">nip2</span> |
| interface. See <span |
| class="cmsy-10">ยง</span><a |
| href="vipsmanualse7.html#x13-360002.1">2.1<!--tex4ht:ref: sec:appl --></a>. |
| <h4 class="subsectionHead"><span class="titlemark">3.2.2 </span> <a |
| id="x21-900003.2.2"></a>Output to an image</h4> |
| <!--l. 128--><p class="noindent" >Before attempting WIO output, programs should call |
| <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_outcheck()</span></span></span>. It has type: |
| |
| |
| |
| <div class="verbatim" id="verbatim-131"> |
| int im_outcheck( IMAGE ⋆im ) |
| </div> |
| <!--l. 133--><p class="nopar" > |
| <!--l. 135--><p class="noindent" >If <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_outcheck()</span></span></span> succeeds, VIPS guarantees that WIO |
| output is sensible. |
| <!--l. 138--><p class="indent" > Programs should then set fields in the output descriptor to |
| describe the sort of image they wish to write (size, |
| type, and so on) and call <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_setupout()</span></span></span>. It has |
| type: |
| <div class="verbatim" id="verbatim-132"> |
| int im_setupout( IMAGE ⋆im ) |
| </div> |
| <!--l. 144--><p class="nopar" > |
| <!--l. 146--><p class="noindent" ><span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_setupout()</span></span></span> creates the output file or memory buffer, |
| using the size and type fields that were filled in by the |
| program between the calls to <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_outcheck()</span></span></span> and |
| <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_setupout()</span></span></span>, and gets it ready for writing. |
| <!--l. 151--><p class="indent" > Pels are written with <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_writeline()</span></span></span>. This takes a y |
| position (pel (0,0) is in the top-left-hand corner of the |
| image), a descriptor and a pointer to a line of pels. It has |
| type: |
| |
| |
| |
| <div class="verbatim" id="verbatim-133"> |
| int im_writeline( int y, |
|  <br />  IMAGE ⋆im, unsigned char ⋆pels ) |
| </div> |
| <!--l. 158--><p class="nopar" > |
| <!--l. 160--><p class="indent" > Two convenience functions are available to make this |
| process slightly easier. <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_iocheck()</span></span></span> is useful for |
| programs which take one input image and produce one |
| image output. It simply calls <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_incheck()</span></span></span> and |
| <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_outcheck()</span></span></span>. It has type: |
| <div class="verbatim" id="verbatim-134"> |
| int im_iocheck( IMAGE ⋆in, IMAGE ⋆out ) |
| </div> |
| <!--l. 167--><p class="nopar" > |
| <!--l. 169--><p class="indent" > The second convenience function copies the fields |
| describing size, type, metadata and history from one image |
| descriptor to another. It is useful when the output image will |
| be similar in size and type to the input image. It has |
| type: |
| |
| |
| |
| <div class="verbatim" id="verbatim-135"> |
| int im_cp_desc( IMAGE ⋆out, IMAGE ⋆in ) |
| </div> |
| <!--l. 176--><p class="nopar" > |
| <!--l. 178--><p class="noindent" >There’s also <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_cp_descv()</span></span></span>, see the man page. |
| |
| |
| |
| |
| <!--l. 182--><p class="indent" > <a |
| id="x21-900012"></a><hr class="float"><div class="float" |
| > |
| |
| |
| |
| |
| <div class="verbatim" id="verbatim-136"> |
| #include <stdio.h> |
|  <br />#include <stdlib.h> |
|  <br /> |
|  <br />#include <vips/vips.h> |
|  <br />#include <vips/util.h> |
|  <br /> |
|  <br />int |
|  <br />invert( IMAGE ⋆in, IMAGE ⋆out ) |
|  <br />{ |
|  <br />  int x, y; |
|  <br />  unsigned char ⋆buffer; |
|  <br /> |
|  <br />  /⋆ Check images. |
|  <br />   ⋆/ |
|  <br />  if( im_iocheck( in, out ) ) |
|  <br />    return( -1 ); |
|  <br />  if( in->BandFmt != IM_BANDFMT_UCHAR || in->Coding != IM_CODING_NONE ) { |
|  <br />    im_error( "invert", "uncoded uchar images only" ); |
|  <br />    return( -1 ); |
|  <br />  } |
|  <br /> |
|  <br />  /⋆ Make output image. |
|  <br />   ⋆/ |
|  <br />  if( im_cp_desc( out, in ) ) |
|  <br />    return( -1 ); |
|  <br />  if( im_setupout( out ) ) |
|  <br />    return( -1 ); |
|  <br /> |
|  <br />  /⋆ Allocate a line buffer and make sure it will be freed correctly. |
|  <br />   ⋆/ |
|  <br />  if( !(buffer = IM_ARRAY( out, |
|  <br />    IM_IMAGE_SIZEOF_LINE( in ), unsigned char )) ) |
|  <br />    return( -1 ); |
|  <br /> |
|  <br />  /⋆ Loop over the image! |
|  <br />   ⋆/ |
|  <br />  for( y = 0; y < in->Ysize; y++ ) { |
|  <br />    unsigned char ⋆p = (unsigned char ⋆) IM_IMAGE_ADDR( in, 0, y ); |
|  <br /> |
|  <br />    for( x = 0; x < IM_IMAGE_N_ELEMENTS( in ); x++ ) |
|  <br />      buffer[x] = 255 - p[x]; |
|  <br />    if( im_writeline( y, out, buffer ) ) |
|  <br />      return( -1 ); |
|  <br />  } |
|  <br /> |
|  <br />  return( 0 );  <br />} |
| </div> |
| <!--l. 230--><p class="nopar" > |
| <br /><div class="caption" |
| ><span class="id">Figure 3.2: </span><span |
| class="content">Invert an image</span></div><!--tex4ht:label?: x21-900012 --> |
| |
| |
| |
| </div><hr class="endfloat" /> |
| <!--l. 235--><p class="indent" > Figure <a |
| href="#x21-900012">3.2<!--tex4ht:ref: fg:invert --></a> is a WIO VIPS operation which finds the |
| photographic negative of an unsigned char image. See |
| <span |
| class="cmsy-10">ยง</span><a |
| href="vipsmanualse8.html#x14-490002.2.10">2.2.10<!--tex4ht:ref: sec:malloc --></a> for an explanation of <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">IM_ARRAY</span></span></span>. This operation |
| might be called from an application with: |
| <div class="verbatim" id="verbatim-137"> |
| #include <stdio.h> |
|  <br />#include <stdlib.h> |
|  <br /> |
|  <br />#include <vips/vips.h> |
|  <br /> |
|  <br />void |
|  <br />find_negative( char ⋆inn, char ⋆outn ) |
|  <br />{ |
|  <br />  IMAGE ⋆in, ⋆out; |
|  <br /> |
|  <br />  if( !(in = im_open( inn, "r" )) || |
|  <br />    !(out = im_open( outn, "w" )) || |
|  <br />    invert( in, out ) || |
|  <br />    im_updatehist( out, "invert" ) || |
|  <br />    im_close( in ) || |
|  <br />    im_close( out ) ) |
|  <br />    error_exit( "failure!" ); |
|  <br />} |
| </div> |
| <!--l. 259--><p class="nopar" > |
| <!--l. 261--><p class="indent" > See <span |
| class="cmsy-10">ยง</span><a |
| href="vipsmanualse8.html#x14-440002.2.7">2.2.7<!--tex4ht:ref: sec:history --></a> for an explanation of the call to |
| <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_updatehist()</span></span></span>. |
| <h4 class="subsectionHead"><span class="titlemark">3.2.3 </span> <a |
| id="x21-910003.2.3"></a>Polymorphism</h4> |
| <!--l. 266--><p class="noindent" >Most image processing operations in the VIPS library can |
| operate on images of any type (<span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">IM_BANDFMT_UCHAR</span></span></span>, as |
| in our examples above, also <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">IM_BANDFMT_UINT</span></span></span> etc.). |
| This is usually implemented with code replication: the |
| operation contains loops for processing every kind of image, |
| and when called, invokes the appropriate loop for the image |
| it is given. |
| <!--l. 272--><p class="indent" > As an example, figure <a |
| href="#x21-910013">3.3<!--tex4ht:ref: fg:exp --></a> calculates <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">exp()</span></span></span> for every |
| pel in an image. If the input image is <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">double</span></span></span>, we write |
| <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">double</span></span></span> output. If it is any other non-complex type, we |
| write <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">float</span></span></span>. If it is complex, we flag an error (<span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">exp()</span></span></span> of |
| a complex number is fiddly). The example uses an |
| image type predicate, <span class="obeylines-h"><span class="verb"><span |
| class="pcrr7t-">im_iscomplex()</span></span></span>. There are a |
| number of these predicate functions, see the manual |
| page. |
| |
| |
| |
| <!--l. 280--><p class="indent" > <a |
| id="x21-910013"></a><hr class="float"><div class="float" |
| > |
| |
| |
| |
| |
| <div class="verbatim" id="verbatim-138"> |
| #include <stdio.h> |
|  <br />#include <stdlib.h> |
|  <br />#include <math.h> |
|  <br /> |
|  <br />#include <vips/vips.h> |
|  <br />#include <vips/util.h> |
|  <br /> |
|  <br />/⋆ Exponential transform. |
|  <br /> ⋆/ |
|  <br />int |
|  <br />exptra( IMAGE ⋆in, IMAGE ⋆out ) |
|  <br />{ |
|  <br />  int x, y; |
|  <br />  unsigned char ⋆buffer; |
|  <br /> |
|  <br />  /⋆ Check descriptors. |
|  <br />   ⋆/ |
|  <br />  if( im_iocheck( in, out ) ) |
|  <br />    return( -1 ); |
|  <br />  if( in->Coding != IM_CODING_NONE || im_iscomplex( in ) ) { |
|  <br />    im_error( "exptra", "uncoded non-complex only" ); |
|  <br />    return( -1 ); |
|  <br />  } |
|  <br /> |
|  <br />  /⋆ Make output image. |
|  <br />   ⋆/ |
|  <br />  if( im_cp_desc( out, in ) ) |
|  <br />    return( -1 ); |
|  <br />  if( in->BandFmt != IM_BANDFMT_DOUBLE ) |
|  <br />    out->BandFmt = IM_BANDFMT_FLOAT; |
|  <br />  if( im_setupout( out ) ) |
|  <br />    return( -1 ); |
| </div> |
| <!--l. 313--><p class="nopar" > |
| <br /><div class="caption" |
| ><span class="id">Figure 3.3: </span><span |
| class="content">Calculate <span |
| class="pcrr7t-">exp() </span>for an image</span></div><!--tex4ht:label?: x21-910013 --> |
| |
| |
| |
| |
| </div><hr class="endfloat" /> |
| |
| |
| |
| |
| <!--l. 319--><p class="indent" > <a |
| id="x21-910024"></a><hr class="float"><div class="float" |
| > |
| |
| |
| |
| |
| <div class="verbatim" id="verbatim-139"> |
|   /⋆ Allocate a line buffer. |
|  <br />   ⋆/ |
|  <br />  if( !(buffer = IM_ARRAY( out, IM_IMAGE_SIZEOF_LINE( in ), unsigned char )) ) |
|  <br />    return( -1 ); |
|  <br /> |
|  <br />/⋆ Our inner loop, parameterised for both the input and output |
|  <br /> ⋆ types. Note the use of ‘\', since macros have to be all on |
|  <br /> ⋆ one line. |
|  <br /> ⋆/ |
|  <br />#define loop(IN, OUT) { \ |
|  <br />  for( y = 0; y < in->Ysize; y++ ) { \ |
|  <br />    IN ⋆p = (IN ⋆) IM_IMAGE_ADDR( in, 0, y ); \ |
|  <br />    OUT ⋆q = (OUT ⋆) buffer; \ |
|  <br />    \ |
|  <br />    for( x = 0; x < IM_IMAGE_N_ELEMENTS( in ); x++ ) \ |
|  <br />      q[x] = exp( p[x] ); \ |
|  <br />    if( im_writeline( y, out, buffer ) ) \ |
|  <br />      return( -1 ); \ |
|  <br />   } \ |
|  <br />} |
|  <br /> |
|  <br />  /⋆ Switch for all the types we can handle. |
|  <br />   ⋆/ |
|  <br />  switch( in->BandFmt ) { |
|  <br />    case IM_BANDFMT_UCHAR: loop( unsigned char, float ); break; |
|  <br />    case IM_BANDFMT_CHAR:  loop( char, float ); break; |
|  <br />    case IM_BANDFMT_USHORT:loop( unsigned short, float ); break; |
|  <br />    case IM_BANDFMT_SHORT: loop( short, float ); break; |
|  <br />    case IM_BANDFMT_UINT:  loop( unsigned int, float ); break; |
|  <br />    case IM_BANDFMT_INT:   loop( int, float ); break; |
|  <br />    case IM_BANDFMT_FLOAT: loop( float, float ); break; |
|  <br />    case IM_BANDFMT_DOUBLE:loop( double, double ); break; |
|  <br />    default: |
|  <br />      im_error( "exptra", "internal error" ); |
|  <br />      return( -1 ); |
|  <br />  } |
|  <br /> |
|  <br />  /⋆ Success. |
|  <br />   ⋆/ |
|  <br />  return( 0 ); |
|  <br />} |
| </div> |
| <!--l. 361--><p class="nopar" > |
| <br /><div class="caption" |
| ><span class="id">Figure 3.4: </span><span |
| class="content">Calculate <span |
| class="pcrr7t-">exp() </span>for an image (cont)</span></div><!--tex4ht:label?: x21-910024 --> |
| |
| |
| |
| |
| </div><hr class="endfloat" /> |
| |
| |
| |
| |
| <!--l. 1--><div class="crosslinks"><p class="noindent">[<a |
| href="vipsmanualse15.html" >next</a>] [<a |
| href="vipsmanualse13.html" >prev</a>] [<a |
| href="vipsmanualse13.html#tailvipsmanualse13.html" >prev-tail</a>] [<a |
| href="vipsmanualse14.html" >front</a>] [<a |
| href="vipsmanualch3.html#vipsmanualse14.html" >up</a>] </p></div> |
| <!--l. 1--><p class="indent" > <a |
| id="tailvipsmanualse14.html"></a> |
| </body></html> |