<?xml version="1.0"?>
<rss version="2.0"
     xmlns:dc="http://purl.org/dc/elements/1.1/"
     xmlns:dcterms="http://purl.org/dc/terms/" >
<channel>
<title>tags/mw4</title>
<link>http://youkan.39mm.net/~nil/iki/tags/mw4/</link>
<description>Nil</description>
<item>
	
	<title>profiling the image convolution</title>
	
	<guid>http://youkan.39mm.net/~nil/iki/101010/mw/20080603-convol-profiling/</guid>
	<link>http://youkan.39mm.net/~nil/iki/101010/mw/20080603-convol-profiling/</link>
	
	
	<category>en</category>
	
	<category>mw4</category>
	
	<category>profiling</category>
	
	
	<pubDate>Tue, 03 Jun 2008 14:39:38 +0200</pubDate>
	<dcterms:modified>2008-08-21T18:24:34Z</dcterms:modified>
	
	<description><![CDATA[<p>The <a href="http://youkan.39mm.net/~nil/iki/tags/mw4/../../101010/mw/20080602-image-access-profiling/">previous tests</a> confirmed that
direct and predictable access to the data is always faster than indirect
access with code branches.</p>

<p>This time we try to improve the code for the general 2D convolution
routine. Three versions were compared for the convolution of a
2048x2048 image with a 5x5 kernel:</p>

<ul>
<li>a naive convert+macro based routine</li>
<li>the routine from megawave 3</li>
<li>a modified version, using only pointer arithmetics in the inner loop</li>
</ul>

<p>I used the same simple profiling tools as before, with gprof:</p>

<ul>
<li><a href="http://youkan.39mm.net/~nil/iki/tags/mw4/../../101010/mw/20080603-convol-profiling/convol.c">convol.c</a></li>
<li><a href="http://youkan.39mm.net/~nil/iki/tags/mw4/../../101010/mw/20080603-convol-profiling/convol.h">convol.h</a></li>
<li><a href="http://youkan.39mm.net/~nil/iki/tags/mw4/../../101010/mw/20080603-convol-profiling/bench.c">bench.c</a></li>
</ul>

<h1>measures</h1>

<h2>without compiler optimization</h2>

<pre><code> %   cumulative   self              self     total           
time   seconds   seconds    calls   s/call   s/call  name    
39.33     25.36    25.36       10     2.54     2.54  _convol_macro
33.48     46.95    21.59       10     2.16     2.16  _convol_old
25.20     63.20    16.25       10     1.62     1.62  _convol_pointer
 1.99     64.48     1.28                             main
 0.00     64.48     0.00       30     0.00     2.11  convol
</code></pre>

<ul>
<li><a href="http://youkan.39mm.net/~nil/iki/tags/mw4/../../101010/mw/20080603-convol-profiling/no-opti.txt">full gprof output</a></li>
</ul>

<h2>with compiler optimization</h2>

<pre><code> %   cumulative   self              self     total           
time   seconds   seconds    calls   s/call   s/call  name    
46.85     10.47    10.47       10     1.05     1.05  _convol_macro
26.35     16.36     5.89       10     0.59     0.59  _convol_old
24.43     21.82     5.46       10     0.55     0.55  _convol_pointer
 2.37     22.35     0.53                             main
 0.00     22.35     0.00       30     0.00     0.73  convol
</code></pre>

<ul>
<li><a href="http://youkan.39mm.net/~nil/iki/tags/mw4/../../101010/mw/20080603-convol-profiling/opti.txt">full gprof output</a></li>
</ul>

<p>So, what?</p>

<ul>
<li>Well, the first remark is that the macro version is slow. This doesn't
mean that the macro access is slow (it is very close to the syntax
used in the "old" version), because the loops design is poor, in fact,
with lots of <code>if</code> branches. It breaks the CPU prediction and the
insctrucion pipelining (see the "unrolling" note, hereafter).</li>
<li>then the <code>pointer</code> code is faster. 25% faster without compiler
optimizations, only 5% faster with optimization. This advantage was
observed for various image sizes, but it's not very significant. My guess
is that the gain in pointer arithmetics (less variables and less
operations in the inner loop) were compensated by the pointer aliasing
problems (see the "restrict" note, hereafter).</li>
</ul>

<p>These measures were obtained for a compilation with gcc-4.2. The
results are similar with gcc-3.4; with gcc-2.95, the optimization of
the "old" version seems inefficient, but the overall impression is the same.</p>

<h1>alternatives?</h1>

<p>I tried an orthogonal approach, looping first on the kernel, then on
the image; as the kernel is supposed to be (much) smaller than the
image, it would result in long and regular inner loops, which I
expected to be more efficient. But then we can't use a 64-bit accumulator. Is this <em>really</em> needed?</p>

<p>Finally, the results were not convincing, because the loops needed
lots of temporary variables, probably more than what the CPU registers
allow. I keep it aside, it may be useful later.</p>

<h1>miscellaneous remarks</h1>

<h2>integer indexes</h2>

<p>I noticed that with gcc 4.2 on an x86_32 CPU, indexing the loops with
an <code>unsigned integer</code> makes the code 30% slower than when we index the
loops with a vanilla <code>signed integer</code>. Too me, it looks like a gcc
optimization bug.</p>

<h2>register starvation</h2>

<p>x86 architecture has only <img src="http://youkan.39mm.net/~nil/iki/tags/mw4/../../data/style/icons/exclamation.png" alt="(!)" /> 
<a href="http://blogs.msdn.com/oldnewthing/archive/2004/01/05/47685.aspx">7 integer registers</a>
and it's easy to need more for nested loops with variable limits. A
few extra registers would be of great help, and are likely to increase
the code efficiency, but the x86 CPU family won't provide them.</p>

<h2>restrict keyword</h2>

<p>In C99, the <code>restrict</code> keyword provides hints to the compiler; it
ensures (from the programmer's brain) that two pointers will never
alias the same data, allowing 
<a href="http://www.cellperformance.com/mike_acton/2006/05/demystifying_the_restrict_keyw.html">better optimizations</a>,
and saving some registers. This may improve out pointer-based loops. But
it's C99-only...</p>

<h2>unrolling the loops</h2>

<p>Partial unrolling of the loops usually uses more efficiently the modern CPUs
<a href="http://en.wikipedia.org/wiki/Superscalar">superscalar</a> and
<a href="http://en.wikipedia.org/wiki/Instruction_pipeline">pipelining</a>
features. This is achieved by replacing a single-instruction loop</p>

<pre><code>for (i = 0; i &lt; imax; i++)
    do_stuff_with(i);
</code></pre>

<p>by a bunch of similar instructions inside the loop; for
example, with 8 instructions in the loop</p>

<pre><code>for (i = 0; i &lt; imax % 8; i++)
     do_stuff_with(i);
for (i = imax % 8; i &lt; imax; i += 8)
{
     do_stuff_with(i);
     do_stuff_with(i + 1);
     do_stuff_with(i + 2);
     do_stuff_with(i + 3);
     do_stuff_with(i + 4);
     do_stuff_with(i + 5);
     do_stuff_with(i + 6);
     do_stuff_with(i + 7);
}
</code></pre>

<p>The downside is that this is largely
architecture-dependant. <a href="http://math-atlas.sourceforge.net/">ATLAS</a>
uses build-time heuristics to do these optimisations.</p>
]]></description>
	
</item>
<item>
	
	<title>profiling the image access methods</title>
	
	<guid>http://youkan.39mm.net/~nil/iki/101010/mw/20080602-image-access-profiling/</guid>
	<link>http://youkan.39mm.net/~nil/iki/101010/mw/20080602-image-access-profiling/</link>
	
	
	<category>en</category>
	
	<category>mw4</category>
	
	<category>profiling</category>
	
	
	<pubDate>Tue, 03 Jun 2008 02:36:31 +0200</pubDate>
	<dcterms:modified>2008-08-21T18:24:34Z</dcterms:modified>
	
	<description><![CDATA[<p>The <a href="http://youkan.39mm.net/~nil/iki/tags/mw4/../../101010/mw/20080530-new-image/">image</a> structures allow different 
<a href="http://youkan.39mm.net/~nil/iki/tags/mw4/../../101010/mw/20080530-new-image/">access methods</a>, with various levels of comfort
and efficiency.</p>

<p>I compared them on a convolution routine, with a 5x5 kernel used on a
2048x2048 image, using the
<a href="http://www.gnu.org.ua/software/binutils/manual/gprof-2.9.1/html_node/gprof_toc.html">gprof</a>
profiler.</p>

<ul>
<li><a href="http://youkan.39mm.net/~nil/iki/tags/mw4/../../101010/mw/20080602-image-access-profiling/convol.c">convol.c</a></li>
<li><a href="http://youkan.39mm.net/~nil/iki/tags/mw4/../../101010/mw/20080602-image-access-profiling/convol.h">convol.h</a></li>
<li><a href="http://youkan.39mm.net/~nil/iki/tags/mw4/../../101010/mw/20080602-image-access-profiling/bench.c">bench.c</a></li>
</ul>

<h1>without compiler optimization</h1>

<p>All the source was compiled with simple default options, including
<code>-O0</code> to disable any compiler optimization.</p>

<pre><code> %   cumulative   self              self     total           
time   seconds   seconds    calls   s/call   s/call  name    
44.95     40.53    40.53       10     4.05     4.05  convol_macro
30.39     67.93    27.40       10     2.74     2.74  convol_convert
23.22     88.87    20.94       10     2.09     2.09  convol_getset
 1.44     90.17     1.30                             main
</code></pre>

<p>So, the <code>XX_XY(img, x, y)</code> has the worst performances here, and
converting all the data to <code>flt32</code> (<code>convol_convert</code>) before using
simple macros is worse than using type casting on each call (<code>convol_getset</code>).</p>

<ul>
<li><a href="http://youkan.39mm.net/~nil/iki/tags/mw4/../../101010/mw/20080602-image-access-profiling/no-opti.txt">full gprof output</a></li>
</ul>

<h1>with compiler optimization</h1>

<p>All the source was compiled with <code>-O2</code> compiler optimization.</p>

<pre><code> %   cumulative   self              self     total           
time   seconds   seconds    calls   s/call   s/call  name    
43.95     27.67    27.67       10     2.77     2.77  convol_macro
36.63     50.73    23.06       10     2.31     2.31  convol_getset
18.71     62.51    11.78       10     1.18     1.18  convol_convert
 0.71     62.96     0.45                             main
</code></pre>

<p>First, the performance is increased by 32% to 57% for the <em>generic
macro</em> and the <em>conversion + specific macro</em> versions, but strangely
decreased for the get/set functions.</p>

<p>Overall, converting all the data to a known type and using predictable
array access macros is the best solution, probably because the
conversion is very efficient and the macros translate to a very clear
syntax, easy to optimize.</p>

<ul>
<li><a href="http://youkan.39mm.net/~nil/iki/tags/mw4/../../101010/mw/20080602-image-access-profiling/opti.txt">full gprof output</a></li>
</ul>

<h1>and pointer arithmetics?</h1>

<p>The macros still need one sum and one product for each data access; it
could be simplified with pointer arithmetics, but for the moment these
expected improvements have been mitigated by</p>

<ul>
<li>CPU limits : x86 platform has very few
<a href="http://en.wikipedia.org/wiki/X86#x86_registers">registers</a>, so a
complex loop requiring less a operations needing to keep track of
more intermediate values may happen to be less efficient, finally,
because it would need lots of memory movements in the CPU.
calls is more likely to be efficiently optimized by the compiler.</li>
<li>compiler optimization : a simple and clear code with few function
calls is more likely to be efficiently optimized by the compiler.</li>
</ul>
]]></description>
	
</item>
<item>
	
	<title>overview of the draft new image formats in megawave</title>
	
	<guid>http://youkan.39mm.net/~nil/iki/101010/mw/20080507-images/</guid>
	<link>http://youkan.39mm.net/~nil/iki/101010/mw/20080507-images/</link>
	
	
	<category>draft</category>
	
	<category>en</category>
	
	<category>mw4</category>
	
	
	<pubDate>Tue, 03 Jun 2008 02:30:54 +0200</pubDate>
	<dcterms:modified>2008-08-21T18:24:34Z</dcterms:modified>
	
	<description><![CDATA[<p>After spending too much time looking around the legacy code, and
thinking about the "good" way to upgrade it to ANSI C, I decided to
try to rewrite it, gradually. So, I start with the images. The basic
ideas are:</p>

<ul>
<li>implement only the basic things, add extra features later if we
really need them</li>
<li>document and test everything</li>
<li>maintain a clean coding style, inspired by this standard</li>
</ul>

<h1>u8image</h1>

<p>This matches the original <a href="http://youkan.39mm.net/~nil/iki/tags/mw4/../../101010/mw/20080408-megawave3-images/">cimage</a> type,
reloaded. <code>uint8</code> is a typedef for <code>unsigned char</code>; we also have
<code>uint16</code>, <code>uint32</code> (no <code>uint64</code>, no <code>long long int</code> in ANSI C),
<code>float32</code> and <code>float64</code> for the other structures.</p>

<p>This structure is defined in [[mw4f lib/src/u8image.h]], with the
implementation details in [[mw4f lib/src/u8image.c]] :</p>

<pre><code>/**
 * 8-bit unsigned integer gray level image
 */
typedef struct s_u8image
{
     uint16 ncol;  /**&lt; number of columns (dx) */
     uint16 nrow;  /**&lt; number of rows (dy)    */
     uint8 * gray; /**&lt; gray level plane       */
} mw_u8image;

/* create an image */
mw_u8image * mw_new_u8image(uint16, uint16);
/* delete an image */
void mw_del_u8image(mw_u8image *);
/* copy an array an image */
mw_u8image * mw_setdata_u8image(mw_u8image *, const uint8 *);
/* copy an image into an existing one */
mw_u8image * mw_copy_u8image(mw_u8image *, mw_u8image *);
/* copy an image into a new one */
mw_u8image * mw_clone_u8image(mw_u8image *);

/* get one value of an image */
int16 mw_getdot_u8image(mw_u8image *, uint16, uint16);
/* set one value of an image */
int16 mw_setdot_u8image(mw_u8image *, uint16, uint16, uint8);
/* fill an image */
uint8 * mw_fill_u8image(mw_u8image *, uint8);

/* write a text representation of an image to a file */
int32 mw_fwrite_u8image(FILE *, mw_u8image *);
/* read a text representation of an image from a file */
mw_u8image * mw_fread_u8image(FILE *);
</code></pre>

<p>So, what is different?</p>

<h2>the structure</h2>

<ul>
<li><code>ncol</code> and <code>ncol</code> are unsigned; it makes sense for indices</li>
<li><code>ncol</code> and <code>nrow</code> are limited to 2^16; this means 2^32 image pixels,
too much...</li>
<li>no more <code>allocsize</code>; the number of pixels is easily computable from
<code>ncol</code> and <code>nrow</code>, and the real allocation size shouldn't be exposed
(sensible, and might be arch-dependant)</li>
<li>no more <code>scale</code>; let's see later if we need it in the structure</li>
<li>no more <code>name</code> or <code>comment</code>; same reasons</li>
<li>no more <code>{first|last}{col|row}</code>; same reasons</li>
<li>no more <code>prev</code> or <code>next</code>; I feel this information should only be
handled by the movie structure</li>
<li><code>mw_u8image</code> is the type of the structure, not a pointer to the
structure; so, we have to explicitly mention the pointer syntax, and
I think improves the code readability</li>
</ul>

<h2>the functions</h2>

<ul>
<li><code>mw_new_u8image</code> allocates the structure <em>and</em> the array; there is
no more <code>mw_change_u8image</code>; it seems that the previous "image
resizing without realer" feature was not used a lot, and this kind of
thing is a candidate for memory leaks; so, from now, we create an
image, we delete an image, but we don't resign it on-the fly; in
<em>some</em> cases, it may imply a performance loss, but the main
performance focus is on the algorithms</li>
<li><code>mw_{setdata|copy|clone}_u8image</code> are handy shortcuts to duplicate
some data</li>
<li><code>mw_{getdot|setdot|fill}_u8image</code> may not be used a lot; but it's a
good way to start manipulating the images</li>
<li><code>mw_{fwrite|fread}_u8image</code> write or read a text representation of
the images; I think it may be the preferred way to dump some data, for
personal use, or maybe when there is no natural format (think about
<em>float</em> images); <em>text</em> representation make it for perfect
portability, readability, and make editing easy; for the moment I
chose the <a href="http://en.wikipedia.org/wiki/JSON">JSON</a> format for its
flexibility and the availability of 
<a href="http://www.json.org/">writing/parsing libraries</a>; text format might
be bigger and slower to process than a binary format, but we can
<em>gzip</em> it, and... once again, the performance is in the algorithms,
not in the i/o.</li>
</ul>

<h1>u16image, f32image, ...</h1>

<p>Same, with another data type. See 
[[mw4f lib/src/u16image.h]]/[[mw4f lib/src/u16image.c]] and 
[[mw4f lib/src/f32image.h]]/[[mw4f lib/src/f32image.c]].</p>

<h1>notes</h1>

<p>All the new code is documented <em>a la</em> doxygen and tested with:</p>

<ul>
<li>static linting with <code>splint +posixlib +weak -ansi89limits</code></li>
<li>separate compilation with  <code>gcc -Wall -I. -pedantic -Werror -Wc++-compat
-Wextra  -Wfloat-equal -Wundef -Wshadow -Wpointer-arith
-Wbad-function-cast -Wcast-qual -Wcast-align -Waggregate-return
-Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations
-Wnested-externs</code></li>
<li>unit tests with <a href="http://cunit.sourceforge.net/">CUnit</a></li>
</ul>

<p>In the future, these gray-level structures might be merged with the
color images.</p>

<p>I also think about a "package", with all the basic operations one may
want to perform on an image:</p>

<ul>
<li><code>add</code> an image or a scalar to an image</li>
<li><code>sub</code> an image or a scalar from an image</li>
<li><code>mul</code> an image by an image or a scalar</li>
<li><code>div</code> an image by an image or a scalar</li>
<li><code>max</code> of an image</li>
<li><code>min</code> of an image</li>
<li><code>mean</code> of an image</li>
<li><code>fmean</code> of an image</li>
<li><code>AND</code> an image and an image or a scalar</li>
<li><code>OR</code> an image and an image or a scalar</li>
<li><code>XOR</code> an image and an image or a scalar</li>
<li><code>AND</code> an image and an image or a scalar</li>
</ul>

<p>By the way, we stick to ANSI C, but overloading and default parameters
would be really nice there; it's possible to implement <em>sort of</em>
overloading in C with <code>union</code>s, but at the price of a code difficult
to write, read, use and maintain. Maybe a C++ overlay later?</p>
]]></description>
	
</item>
<item>
	
	<title>a draft generic image format</title>
	
	<guid>http://youkan.39mm.net/~nil/iki/101010/mw/20080509-generic-image/</guid>
	<link>http://youkan.39mm.net/~nil/iki/101010/mw/20080509-generic-image/</link>
	
	
	<category>draft</category>
	
	<category>en</category>
	
	<category>mw4</category>
	
	
	<pubDate>Tue, 03 Jun 2008 02:30:39 +0200</pubDate>
	<dcterms:modified>2008-08-21T18:24:34Z</dcterms:modified>
	
	<description><![CDATA[<p>After describing the <a href="http://youkan.39mm.net/~nil/iki/tags/mw4/../../101010/mw/20080507-images/">new image structures</a>, I wrote
that a C++ overlay may be nice, mainly for functions overloading. It
would also make sense when reading an image from a file; think about a
TIFF file; is it binary? 8bit? 16bit? You can't know fore sure before you
actually open the file.</p>

<p>Actually, it <em>is</em> possible to make some <em>sort of</em> overloading in C,
with unions. It's not elegant code, and may not be transparent for the
user, but it's possible, and worth trying. I tried it.</p>

<h1>image</h1>

<p>So, here is the generic <code>image</code> structure; I don't know if it will
stay in the code, we'll see.</p>

<p>This structure is defined in [[mw4f lib/src/image.h]], with the
implementation details in [[mw4f lib/src/image.c]] :</p>

<pre><code>/**
 * xx_image union
 */
typedef union u_xximage
{
     mw_u8image  u8;  /**&lt; uint8  image */
     mw_u16image u16; /**&lt; uint16 image */
     mw_f32image f32; /**&lt; uint32 image */
} xximage;

/**
 * gray level image
 */
typedef struct s_image
{
     char dtype;   /**&lt; data type stored */
     xximage img; /**&lt; image union, for all supported dtypes */
} mw_image;

/* create an image */
mw_image * mw_new_image(uint16, uint16, char);
/* delete an image */
void mw_del_image(mw_image *);
/* copy an array to an image */
mw_image * mw_setdata_image(mw_image *, const void *);
/* copy an image into an existing one */
mw_image * mw_copy_image(mw_image *, mw_image *);
/* copy an image into a new one */
mw_image * mw_clone_image(mw_image *);

/* get one value of an image */
flt32 mw_getdot_image(mw_image *, uint16, uint16);
/* set one value of an image */
flt32 mw_setdot_image(mw_image *, uint16, uint16, flt32);
/* fill an image */
void * mw_fill_image(mw_image *, flt32);

/* write a text representation of an image to a file */
int32 mw_fwrite_image(FILE *, mw_image *);
/* read a text representation of an image from a file */
mw_image * mw_fread_image(FILE *);
</code></pre>

<h2>the structure</h2>

<ul>
<li><code>dtype</code> is a marker, to know which kind of image we are dealing with</li>
<li><code>img</code> is an union of <code>mw_u8imge</code>, <code>mw_u16image</code> of <code>mw_f32image</code></li>
</ul>

<p>That's it. With that, depending on the value of <code>dtype</code>, we'll switch
to the correct functions. Note that it doesn't increase the memory
size, as all the <code>`mw_xximage</code> structures have exactly the same
size. All it takes is, basically, one more allocation test, one
<code>switch ()</code> test and one more function call for each <code>mw_xxx_image()</code>
function.</p>

<h2>the functions</h2>

<ul>
<li><code>mw_new_u8image</code>, <code>mw_del_image</code>, <code>mw_{setdata|copy|clone}_image</code>
are the same, nothing changed from the user point of view, except that
you choose which kind of data type you want to use</li>
<li><code>mw_{getdot|setdot|fill}_u8image</code> can't be identical; in order to
provide an unique interface, they take or return <code>flt32</code> values; an
user cast may be required here</li>
<li><code>mw_{fwrite|fread}_u8image</code> didn't change; we just embed the
type-dependant format with some extra information : <br />
<code>{ "dtype" = "MW_UINT8", "img" = { "ncol" = 42, "nrow" = 42, gray = [ 1,
2, 3, ... ] } }</code>, and we get a all-type image file format.</li>
</ul>

<h1>notes</h1>

<p>By the way, all this code compiles perfectly on x86 and x86_64 systems
(PC 32 and 64 bits) and HP-PA too; I should be able to test on some other
architectures soon.</p>
]]></description>
	
</item>
<item>
	
	<title>new image structure, stripped down</title>
	
	<guid>http://youkan.39mm.net/~nil/iki/101010/mw/20080530-new-image/</guid>
	<link>http://youkan.39mm.net/~nil/iki/101010/mw/20080530-new-image/</link>
	
	
	<category>doc</category>
	
	<category>en</category>
	
	<category>mw4</category>
	
	
	<pubDate>Tue, 03 Jun 2008 02:29:36 +0200</pubDate>
	<dcterms:modified>2008-08-21T18:24:34Z</dcterms:modified>
	
	<description><![CDATA[<p>Last week I wrote the image structures, with 3 different structures
(<code>image_u8</code>, <code>image_u16</code>, <code>image_f32</code>) for 3 different basic types
(8bit integer, 16bit integer, 32bit floats). As I wanted a common
interface to these structures, I wrote a king of "meta-structure",
using C unions to make some kind of subclass design.</p>

<p>I still think it was a good idea, and it worked, but.... why not make
it simple. KISS, Keep It Simple (Stupid!). I guess this pseudo-class
design was a consequence of the previous codebase, and I used code
tricks instead of imagination.</p>

<p>So, after a midnight revelation (yes, around 03:00, in bed...) and a
few days rewriting (again...), the design is now simple, very simple:</p>

<h1>new image design</h1>

<p>The image definition is:</p>

<pre><code>/**
 * generic image structure
 */
typedef struct s_image
{
/* TODO : add bit depth and channels */
     mw_dtype dtype;   /**&lt; datatype of the stored values */
     uint16 ncol;      /**&lt; number of columns */
     uint16 nrow;      /**&lt; number of rows    */
     void * data;      /**&lt; data array        */
} mw_image;
</code></pre>

<p>Yes, that's it. An image is:</p>

<ul>
<li>a data type (an integer, in fact, but users should only use
<code>MW_DT_XX</code> macros)</li>
<li>a number of rows</li>
<li>a number or columns</li>
<li>a data array</li>
</ul>

<p>Later, we may introduce some other structure fields, if they are
needed my many algorithms; but the best way could be to add a simple
generic pointer, and let everyone use it as they like (or even
register some alloc/dealloc/copy routines).</p>

<p>For color images, the idea is to add a <code>uint8 nchn</code> field for the
number of channels; then, we have the following correspondances:</p>

<ul>
<li>1 channel  : grayscale image</li>
<li>2 channels : grayscale+alpha image</li>
<li>3 channels : RGB image</li>
<li>4 channels : RGB+alpha image</li>
</ul>

<p>But it still is possible to define a 255 channels images, if it makes
sense (for the algo <em>and</em> for the memory space).</p>

<h1>user interface</h1>

<p>This generic data array can be used in different ways:</p>

<ul>
<li><strong>high-level, generic</strong> <br />
With the macro <code>XY(img, x, y)</code>, you access the same point, but
through less function calls, so it's faster. As it's in fact three
nested <code>( ? : )</code> operations (to adapt the behaviour to the type),
you can't use it as a <code>lvalue</code>, <em>ie</em> to update a value.</li>
<li><strong>high-level, specific</strong> <br />
For <code>lvalues</code>, or when you know for sure what's the dtype of your
image, <code>U8_XY(img, x, y)</code>, <code>U16_XY(img, x, y)</code>, <code>F32_XY(img, x, y)</code>
will work, but still at the cost of two indirections, one sum and
one product.</li>
<li><strong>high-level</strong> <br />
With <code>mw_image_getdot(img, x, y)</code> and 
<code>mw_image_setdot(img, x, y, value)</code>, you can access and update the
point <code>(x, y)</code> in the <code>img</code> image. The functions take care of type
casting and array position. This is easy, simple, but won't be very
fast.</li>
<li><strong>lower-level</strong>
In loops, when speed matters, you can still use a classic array
syntax. But you will need to know the type used in the data array,
and use type casting because it's not possible to use <code>void</code>
pointers directly. It will have to look like 
<code>((uint8 *) image-&gt;data)[y * ncol + x]</code>, but you can also define
first <code>data = (uint8 *) image-&gt;data</code>, then write 
<code>data[y * ncol + x]</code>. This also means that you wil need a 
<code>switch ()</code> statement, to select between the possible types.</li>
<li><strong>lowest-level</strong>
As usual, in C, lowers-level means pointers. Here also, if you cast 
<code>image-&gt;data</code> to the correct pointer type, everything is fine.</li>
</ul>

<p>Some profiling is planned, to provide comparative measures of the
performance of these levels.</p>

<h1>code architecture</h1>

<p>This change improves the code architecture, function calls,
and dependencies. Now it's possible to implement generic
image-processing algorithms without the hassle of dealing with
subtypes, unions, and so on. The image file (TXT, PNG, tIFF...)
read/write routines are also simplified:</p>

<p><img src="http://youkan.39mm.net/~nil/iki/tags/mw4/../../101010/mw/20080530-new-image/mw_image_read.png" alt="mw image read.png" /></p>

<h1>fast loops</h1>

<p>By the way, the images are stored by rows, X-style (<code>(0, 0)</code> is the
upper-left corner). So, the efficient way to pass through all the
pixels is:</p>

<pre><code>uint8 * data;
uint16 nrow, ncol;

data = (uint8 *) image-&gt;data;
nrow = data-&gt;nrow;
ncol = data-&gt;ncol;
for (y = 0; y &lt; nrow; y++)
    for (x = 0; x &lt; ncol; x++)
        do_stuff_with(data[y * ncol + x]);
</code></pre>

<p>This ensures a better memory localisation, less CPU cache miss,
... a faster code.</p>

<p>If performance is a matter, pointer arithmetics will save one
sum, one product, some tests and some registers at each loop, but the
code will be a bit obfuscated:</p>

<pre><code>uint8 * ptr, * stop;

ptr = (uint8 *) image-&gt;data;
stop = ptr + image-&gt;ncol * image-&gt;nrow;
while (ptr &lt; stop)
    do_stuff_with((* ptr++));
</code></pre>
]]></description>
	
</item>
<item>
	
	<title>float64 (double-precision float) image</title>
	
	<guid>http://youkan.39mm.net/~nil/iki/101010/mw/20080602-flt64-image/</guid>
	<link>http://youkan.39mm.net/~nil/iki/101010/mw/20080602-flt64-image/</link>
	
	
	<category>en</category>
	
	<category>mw4</category>
	
	
	<pubDate>Mon, 02 Jun 2008 15:37:46 +0200</pubDate>
	<dcterms:modified>2008-08-21T18:24:34Z</dcterms:modified>
	
	<description><![CDATA[<p>The initial image structure was only implemented with 3 different
types : <code>uint8</code>. <code>uint16</code>, <code>flt32</code>; But finally, I wanted to try
something with double-precision float images.</p>

<p>So, updating the code, linting, the test code, testing and debugging
took about ... 2 hours only. Good!</p>
]]></description>
	
</item>
<item>
	
	<title>design for the image file loading functions</title>
	
	<guid>http://youkan.39mm.net/~nil/iki/101010/mw/20080512-design/</guid>
	<link>http://youkan.39mm.net/~nil/iki/101010/mw/20080512-design/</link>
	
	
	<category>draft</category>
	
	<category>en</category>
	
	<category>mw4</category>
	
	
	<pubDate>Fri, 30 May 2008 15:51:54 +0200</pubDate>
	<dcterms:modified>2008-08-21T18:24:34Z</dcterms:modified>
	
	<description><![CDATA[<p>We have the <a href="http://youkan.39mm.net/~nil/iki/tags/mw4/../../101010/mw/20080507-images/">typed images</a>, and a
<a href="http://youkan.39mm.net/~nil/iki/tags/mw4/../../101010/mw/20080509-generic-image/">generic image</a> definition, with a basic (and
very fragile, for the moment) text input/output format. It's time to
decide how to organise the input-output to external standard formats,
like PNG, TIFF, JPEG...</p>

<h1>standard libraries</h1>

<p>The first decision is to use only the standard and well-known,
well-tested, well-distributed libraries to do it, and only <code>#include</code>
the relevant headers; it may seem obvious, but it was not done like
that until now. This means that: </p>

<ul>
<li>to build the megawave library, you need the headers for these
libraries on your system: you will need the <code>libxxx-dev</code> packages on
Debian-based linux distributions, or the <code>libxxx-devel</code> packages on
RPM-based linux distributions; out of the linux world, I don't know
yet...</li>
<li>to use the megawave library, you need the run-time versions of these
libraries (<em>ie</em> <code>libxxx</code> packages)</li>
</ul>

<p>This should not be a problem, as packages systems handle the
dependencies. We may also provide an "all-inclusive" binary version of
megawave, for quick tests. And it would solve all sorts of
API/compiler/standard compatability issues.</p>

<p>And by "standard libraries", I mean
<a href="http://www.libpng.org/pub/png/libpng.html">libpng</a>,
<a href="http://www.libtiff.org/">libtiff</a>, 
<a href="http://www.ijg.org/">libjpeg</a>,
<a href="http://www.ece.uvic.ca/~mdadams/jasper/">jasper</a>,
<a href="http://giflib.sourceforge.net/doc/">giflib</a>, 
<a href="http://netpbm.sourceforge.net/">netpbm</a>, ...</p>

<p>By the way, I can't find any "standard" library for the BMP files. But
who need BMP file?</p>

<h1>structures and formats</h1>

<p>The main question is then «how should we handle the multiplicity?». We
currently have 3 internal raster image formats (based on <code>uint8</code>,
<code>uint16</code> and <code>flt32</code>); we may add sooner or later the other natural
types (<code>uint32</code>, <code>uint64</code> and <code>flt64</code>), counting to 6. If we implement
the color images as different structures (which is not certain), it
would double this number. Then, later, why not 3D-images (if they are
not the same thing as movies).</p>

<p>The natural image file formats are <code>png</code> and <code>jpeg</code>. Legacy formats,
like <code>pnm</code>, <code>tiff</code>, <code>gif</code> can be useful too. And <code>jpeg2000</code>. Same for
scientific data formats like <code>netcdf</code> of <code>dicom</code>. And then we will
have to think about extracting frames from <code>mpeg</code>, <code>avc</code>, <code>vp</code> (and
variants), <code>huffyuv</code> (lossless) video?</p>

<p>Basically, we have many internal structures, and we want to be able to
fill them from many different kinds of external files.</p>

<h1>in / out matrix</h1>

<p>Let's just consider 3 internal structures, and 3 file formats. The
naive design, <em>ie</em> one function per input/output couple, looks like
that: <br />
<img src="http://youkan.39mm.net/~nil/iki/tags/mw4/../../101010/mw/20080512-design/design_1.png" alt="design 1.png" /> <br />
<a href="http://youkan.39mm.net/~nil/iki/tags/mw4/../../101010/mw/20080512-design/design_1.dot">design 1.dot</a>  <a href="http://youkan.39mm.net/~nil/iki/tags/mw4/../../101010/mw/20080512-design/design_1.svg">design 1.svg</a></p>

<p>So, 9 functions for the moment, with lots of code duplication. Then,
if we want to add one file format, we need to write 4 functions (the
generic <code>load_foo</code> plus the three <code>load_foo_xx</code> interfaces), and
modify 3 other ones (<code>load_xximage</code>). This will grow exponentially,
the the result will be a lot of unmaintainable code.</p>

<h1>multiple in / multiple out</h1>

<p>One simplification is to remove the matrix, and allow direct dialogue
between the "image" side and the "file" side. <br />
<img src="http://youkan.39mm.net/~nil/iki/tags/mw4/../../101010/mw/20080512-design/design_2_direct.png" alt="design 2 direct.png" /> <br />
<a href="http://youkan.39mm.net/~nil/iki/tags/mw4/../../101010/mw/20080512-design/design_2_direct.dot">design 2 direct.dot</a> <a href="http://youkan.39mm.net/~nil/iki/tags/mw4/../../101010/mw/20080512-design/design_2_direct.svg">design 2 direct.svg</a></p>

<p>The it would be somehow more easy to add a new format, we still need
to update many new functions each time we want to add support for a
new format; this big "cross-interaction" at the center has to be removed.</p>

<h1>front-ends</h1>

<p>The same design, with front-ends added, limits the dependencies. <br />
<img src="http://youkan.39mm.net/~nil/iki/tags/mw4/../../101010/mw/20080512-design/design_2_indirect.png" alt="design 2 indirect.png" /> <br />
<a href="http://youkan.39mm.net/~nil/iki/tags/mw4/../../101010/mw/20080512-design/design_2_indirect.dot">design 2 indirect.dot</a> <a href="http://youkan.39mm.net/~nil/iki/tags/mw4/../../101010/mw/20080512-design/design_2_indirect.svg">design 2 indirect.svg</a></p>

<p>Now, each time we add a new format, there is one new function to write
(<code>load_foo</code>) and one to update (<code>load_file</code>). And the two different
parts of the code ("image" and "file") are connected by a single
interface.</p>

<p>One problem remains: the <code>load_file</code> functions must be able to return
different outputs, depending on who called them.</p>

<p>This could be done by:</p>

<ul>
<li>returning a <code>(void *)</code> pointer; no type checking, dangerous,
buggy, etc.</li>
<li>filling a pointer passed as argument; doing so, the memory would be
allocated in the "file" side of the code, then used in the
other side, and the <code>load_xx</code> function would need to access
<code>mw_new_xximage</code>, which means cross-dependencies. </li>
<li>returning a generic <code>mw_image</code>; but this generic structure is an
overlay, not a building brick for the <code>mw_xximages</code></li>
</ul>

<h1>details</h1>

<p>The solution is to split the process in two parts:</p>

<ol>
<li>gather meta-information from the file (shape, data type,
layers...), then create the empty <code>mw_xximage</code> structure and
allocate the correct memory size</li>
<li>gather the image data, filled in the memory area whose address is
passed as a parameter</li>
</ol>

<p>This work-flow would look like that: <br />
<img src="http://youkan.39mm.net/~nil/iki/tags/mw4/../../101010/mw/20080512-design/design_detail.png" alt="design detail.png" /> <br />
<a href="http://youkan.39mm.net/~nil/iki/tags/mw4/../../101010/mw/20080512-design/design_detail.dot">design detail.dot</a> <a href="http://youkan.39mm.net/~nil/iki/tags/mw4/../../101010/mw/20080512-design/design_detail.svg">design detail.svg</a></p>

<p>This design is modular; for example,</p>

<ul>
<li>it's easy to change the way the image format is selected 
(parameter? file name extension? 
<a href="http://packages.debian.org/etch/libmagic-dev">magic</a> 
<a href="http://linux.die.net/man/5/magic">number</a>?)</li>
<li>it's possible to collect only the meta-data, or only the raster data</li>
<li>for any new file format, we need to add two functions and update two
functions</li>
<li>for any new internal format, we just need to implement the same
calls as the already-defined formats do</li>
</ul>
]]></description>
	
</item>
<item>
	
	<title>png support</title>
	
	<guid>http://youkan.39mm.net/~nil/iki/101010/mw/20080522-png-support/</guid>
	<link>http://youkan.39mm.net/~nil/iki/101010/mw/20080522-png-support/</link>
	
	
	<category>en</category>
	
	<category>mw4</category>
	
	
	<pubDate>Fri, 30 May 2008 15:50:39 +0200</pubDate>
	<dcterms:modified>2008-08-21T18:24:34Z</dcterms:modified>
	
	<description><![CDATA[<p>PNG read/write functions are available. For the moment:</p>

<ul>
<li>they can only read grayscale images (color and alpha images will
be available when the color image structures are defined)</li>
<li>they only read 8bit or 16bit (no monochrome, 2bit or 4bit yet)</li>
<li>they can write 8bit or 16bit grayscale</li>
<li>a float image is converted to 16bit integer by multiplying it by
65535 (we assume float values are between 0 and 1)</li>
<li>a png file is loaded into a float image by dividing it by 255 or
65535 (resulting in values between 0 and 1)</li>
</ul>

<p>If explicitely requested, the file is converted to the desired
datatype (8bit, 16bit unsigned integer, or float); else, the most
appropriate image structure is selected, in a <code>mw_image</code>
container.</p>

<p><img src="http://youkan.39mm.net/~nil/iki/tags/mw4/../../101010/mw/20080522-png-support/load.png" alt="load.png" /> <br />
<img src="http://youkan.39mm.net/~nil/iki/tags/mw4/../../101010/mw/20080522-png-support/save.png" alt="save.png" /></p>

<p>It's not freezed, and some parts are likely to be modified in the
future, but the main design is there.</p>

<p>Adding a new image format requires 3 new functions, and 4 changes
in <code>switch</code> statements; adding a new image structure requires 4 changes
in <code>switch</code> statements (and the functions <code>mw_load_xximage()</code> and
<code>mw_save_xximage()</code>).</p>

<p>So, we now have the bare tools to start working on the algorithms:</p>

<ul>
<li>grayscale image formats</li>
<li>native human-readable text i/o formats</li>
<li>common lossless binary i/o formats</li>
</ul>
]]></description>
	
</item>
<item>
	
	<title>ANSI C and snprintf</title>
	
	<guid>http://youkan.39mm.net/~nil/iki/101010/mw/20080522-snprintf/</guid>
	<link>http://youkan.39mm.net/~nil/iki/101010/mw/20080522-snprintf/</link>
	
	
	<category>en</category>
	
	<category>mw4</category>
	
	
	<pubDate>Thu, 22 May 2008 21:03:13 +0200</pubDate>
	<dcterms:modified>2008-08-21T18:24:34Z</dcterms:modified>
	
	<description><![CDATA[<p>One problem with ANSI C is the lack of a safe version of
<code>sprintf()</code>, adressed by C99 with <code>snprintf()</code>. I need it because:</p>

<ul>
<li>we want some rich error/debug messages, including the file and line
number, and...</li>
<li>file and line number are provided by the ANSI C <code>__FILE__</code> and
<code>__LINE__</code> macros, so...</li>
<li>we must call the messages functions with a macro, but ...</li>
<li>we sometimes need to send printf-like formatted messages, like <code>("the
value is %i", foo)</code>, and ...</li>
<li>ANSI C doesn't allow variadic macros, so ...</li>
<li>we must use an intermediary function to format the message and store
it in a temporary buffer, like <code>DEBUG(vmsg("the value is %i",
foo))</code>, but ...</li>
<li>the temporary buffer has a fixed length, and ...</li>
<li><code>sprintf()</code> may write after the end of this buffer, which would
result in a crash.</li>
</ul>

<p>So, as a workaround, we use an <em>"ANSI C implementation of
snprintf()"</em>. Various implementations exist, such as:</p>

<ul>
<li><a href="http://www.jhweiss.de/software/snprintf.html">http://www.jhweiss.de/software/snprintf.html</a></li>
<li><a href="http://www.ijs.si/software/snprintf/">http://www.ijs.si/software/snprintf/</a></li>
</ul>

<p>For the moment, we use the latter one, because it's more compact.</p>

<p>Bad news : none of these implementations are free of <code>splint</code> or  <code>gcc</code>
warnings... so they have to be excluded from our code quality tests.</p>
]]></description>
	
</item>
<item>
	
	<title>listed in freshmeat and ohloh</title>
	
	<guid>http://youkan.39mm.net/~nil/iki/101010/mw/20080219-listed/</guid>
	<link>http://youkan.39mm.net/~nil/iki/101010/mw/20080219-listed/</link>
	
	
	<category>en</category>
	
	<category>floss</category>
	
	<category>mw4</category>
	
	
	<pubDate>Tue, 22 Apr 2008 19:46:10 +0200</pubDate>
	<dcterms:modified>2008-08-21T18:24:34Z</dcterms:modified>
	
	<description><![CDATA[<p>Megawave is moving to a plain FLOSS software, and we plan to adopt a
vanilla well-known licence (read GPL). The details and the license
migration will take some time, but it has been decided.</p>

<p>This change is part of the will to be known better, distributed better,
and used more.</p>

<p>As an early step, megawave is now listed in
<a href="http://freshmeat.net/projects/megawave/">freshmeat</a> and
<a href="http://www.ohloh.net/projects/megawave">ohloh</a>.</p>
]]></description>
	
</item>
<item>
	
	<title>nightly tarballs of the development code</title>
	
	<guid>http://youkan.39mm.net/~nil/iki/101010/mw/20080416-nightly-tarballs/</guid>
	<link>http://youkan.39mm.net/~nil/iki/101010/mw/20080416-nightly-tarballs/</link>
	
	
	<category>en</category>
	
	<category>mw4</category>
	
	
	<pubDate>Thu, 17 Apr 2008 17:45:33 +0200</pubDate>
	<dcterms:modified>2008-08-21T18:24:34Z</dcterms:modified>
	
	<description><![CDATA[<p>From today, some nightly snapshots of the the develoment code will be
available in the <a href="http://youkan.39mm.net/~nil/iki/tags/mw4//download/megawave/">download</a> section of this
website.</p>

<p>Don't expect it to be correct, able to run, or even able to
compile. But it may sometimes be ok.</p>
]]></description>
	
</item>
<item>
	
	<title>mwplight, the syntax</title>
	
	<guid>http://youkan.39mm.net/~nil/iki/101010/mw/20080214-mwplight-syntax/</guid>
	<link>http://youkan.39mm.net/~nil/iki/101010/mw/20080214-mwplight-syntax/</link>
	
	
	<category>doc</category>
	
	<category>en</category>
	
	<category>kernel</category>
	
	<category>mw4</category>
	
	<category>mwp</category>
	
	
	<pubDate>Tue, 08 Apr 2008 16:22:10 +0200</pubDate>
	<dcterms:modified>2008-08-21T18:24:34Z</dcterms:modified>
	
	<description><![CDATA[<p><code>mwplight</code> now has an official command-line syntax, shown with <code>mwplight
-h</code> or when the command-line parameters dont fit the requirements.</p>

<pre><code>Usage: mwplight [options] filename
Options:
  -a, --afile file    name of the A-file (main function of the run-time)
  -m, --mfile file    name of the M-file (source of the modified module)
  -t, --tfile file    name of the T-file (source of the module documentation)
  -i, --ifile file    name of the I-file (interface file for an interpretor)
  -n, --nfile file    name of the N-file (group and name of the module)
  -g, --group group   group the module belongs to (defaults to "unknown")
  -v, --version       print version information
  -d, --debug         debug flag
  -h, -?, --help      print usage help

  -a and -m options and the filename are required.
</code></pre>

<p>And no more environment variable is needed.</p>
]]></description>
	
</item>
<item>
	
	<title>use cases for megawave</title>
	
	<guid>http://youkan.39mm.net/~nil/iki/101010/mw/20080219-usecases/</guid>
	<link>http://youkan.39mm.net/~nil/iki/101010/mw/20080219-usecases/</link>
	
	
	<category>doc</category>
	
	<category>en</category>
	
	<category>mw4</category>
	
	
	<pubDate>Fri, 04 Apr 2008 22:49:59 +0200</pubDate>
	<dcterms:modified>2008-08-21T18:24:34Z</dcterms:modified>
	
	<description><![CDATA[<p>A good tool needs a clear definition of its uses. So, here are the
intended use cases for megawave:</p>

<ol>
<li>Maria is an image processing researcher. She wants to use, try or
compare recent algorithms and methods.</li>
<li>Hakim is an image processing researcher. He wants to show and
distribute his new algorithms and methods.</li>
<li>Hiroko is developing some image processing software or hardware; she
wants to include recent and efficient algorithms.</li>
<li>Marc is a math teacher. He needs to show how various image processing
tools work, and he needs a framework to help his students try things
with this kind of tools.</li>
</ol>

<p>For all af them, megawave intends to provide a solution.</p>
]]></description>
	
</item>
<item>
	
	<title>code readability and splint tests</title>
	
	<guid>http://youkan.39mm.net/~nil/iki/101010/mw/20080229-splint/</guid>
	<link>http://youkan.39mm.net/~nil/iki/101010/mw/20080229-splint/</link>
	
	
	<category>ansi</category>
	
	<category>en</category>
	
	<category>mw4</category>
	
	<category>mwplight</category>
	
	<category>splint</category>
	
	
	<pubDate>Thu, 06 Mar 2008 15:19:56 +0100</pubDate>
	<dcterms:modified>2008-08-21T18:24:34Z</dcterms:modified>
	
	<description><![CDATA[<p>ANSI C (aka C90) conversion is now complete for mwplight, and the code
refactoring is on the way; most of the long strings have been
<code>#define</code>d, to improve the flow readability, and some of the global
variables are now explicitly passed as parameters. This still is a work
in progress, and an extensive in-code documentation (<em>a la</em>
<a href="http://www.stack.nl/~dimitri/doxygen/">doxygen</a>) is in the future plans.</p>

<p><a href="http://www.splint.org/">splint</a> test are also processed, in order to
improve the code quality (type checking, buffer overflow, NULL pointers,
...). No errors are reported for <code>splint +posixlib +weak -ansi89limits
-bufferoverflowhigh</code> and some additional markup is being added for a
standard test (no <code>+weak</code>). There still is the issue of unsafe C90
<code>sprintf()</code> functions, but we may solve it through an external library
in order to keep C/C++ compatability.</p>
]]></description>
	
</item>
<item>
	
	<title>svn frontend</title>
	
	<guid>http://youkan.39mm.net/~nil/iki/101010/mw/20080216-svn/</guid>
	<link>http://youkan.39mm.net/~nil/iki/101010/mw/20080216-svn/</link>
	
	
	<category>en</category>
	
	<category>kernel</category>
	
	<category>mw4</category>
	
	<category>mwp</category>
	
	
	<pubDate>Sun, 17 Feb 2008 00:17:50 +0100</pubDate>
	<dcterms:modified>2008-08-21T18:24:34Z</dcterms:modified>
	
	<description><![CDATA[<p>The code source is managed with <a href="http://darcs.net/">darcs</a>. The natural
way to get a local copy of the code is:</p>

<pre><code>darcs get --partial http://dev.39mm.net/darcs/megawave-4
</code></pre>

<p>I added today a <a href="http://subversion.tigris.org/">subversion</a> frontend. So
you can also get a local copy of the code with:</p>

<pre><code>svn checkout http://dev.39mm.net/svn/megawave-4
</code></pre>

<p>The darcs -&gt; svn sync is performed every night.</p>
]]></description>
	
</item>
<item>
	
	<title>mwplight, ansi code, clean compilation</title>
	
	<guid>http://youkan.39mm.net/~nil/iki/101010/mw/20080213-mwplight-ansi-clean/</guid>
	<link>http://youkan.39mm.net/~nil/iki/101010/mw/20080213-mwplight-ansi-clean/</link>
	
	
	<category>ansi</category>
	
	<category>en</category>
	
	<category>kernel</category>
	
	<category>mw4</category>
	
	<category>mwp</category>
	
	
	<pubDate>Wed, 13 Feb 2008 00:00:00 +0100</pubDate>
	<dcterms:modified>2008-08-21T18:24:34Z</dcterms:modified>
	
	<description><![CDATA[<p>First step!</p>

<p><a href="http://youkan.39mm.net/~nil/iki/tags/mw4//darcsweb?r=megawave-4;a=tree;f=/kernel/mwplight"><code>mwplight</code></a>
compiles
<a href="http://youkan.39mm.net/~nil/iki/tags/mw4//darcsweb?r=megawave-4;a=commit;h=20080213233741-74b31-298a16b360d67c8f0c71d01b0d76a561d5be7552.gz">now</a>
without warnings with <code>gcc -ansi -Wall -Wextra -Wc++-compat</code>.</p>

<p>All the code has been read and cleaned up, and the warnings fixed.</p>

<p>Anyway, the work isn't over, and <code>mwplight</code> still needs...</p>

<ul>
<li>to define all the strings as preprocessor variables, and get clear
indentation (crucial to understand the code)</li>
<li>to get rid of a few macro hacks</li>
<li>to use only information form the command-line</li>
<li>to organise headers, prototypes, inclusion</li>
<li>to design some unit tests</li>
<li>to document the command-line syntax</li>
<li>to document the source</li>
<li>to pass a <code>splint</code> test</li>
<li>to pass an even more strict compilation without <a href="http://youkan.39mm.net/~nil/iki/tags/mw4/../../101010/mw/20080213-mwplight-ansi-clean/make.log">warnings</a></li>
</ul>

<p>The final warning-safe <code>gcc</code> options set should be something like this:</p>

<pre><code>gcc -ansi -Wall -Wextra -Wc++-compat
-pedantic -Wfloat-equal -Wundef -Wshadow -Wpointer-arith
-Wbad-function-cast -Wcast-qual -Wcast-align
-Waggregate-return -Wstrict-prototypes -Wmissing-prototypes
-Wmissing-declarations -Wnested-externs
-Wunreachable-code
</code></pre>
]]></description>
	
</item>
<item>
	
	<title>mwplight, ansi code</title>
	
	<guid>http://youkan.39mm.net/~nil/iki/101010/mw/20080212-mwplight-ansi/</guid>
	<link>http://youkan.39mm.net/~nil/iki/101010/mw/20080212-mwplight-ansi/</link>
	
	
	<category>ansi</category>
	
	<category>en</category>
	
	<category>kernel</category>
	
	<category>mw4</category>
	
	<category>mwp</category>
	
	
	<pubDate>Tue, 12 Feb 2008 00:00:00 +0100</pubDate>
	<dcterms:modified>2008-08-21T18:24:34Z</dcterms:modified>
	
	<description><![CDATA[<p><a href="http://youkan.39mm.net/~nil/iki/tags/mw4//darcsweb?r=megawave-4;a=commit;h=20080208213807-74b31-9c2ab6a4a7fc1cc564cb9428d58237eaa364aa49.gz"><code>mwplight</code></a>,
compiles now with <code>gcc -ansi -Wall -Wextra -Wc++-compat</code>. But it throws
<a href="http://youkan.39mm.net/~nil/iki/tags/mw4/../../101010/mw/20080212-mwplight-ansi/make.log">lots of warnings</a>, which need to be adressed. Most of
them are minor warnings, about unused variables or unclear syntax, and
can be easily fixed; but the main work will be to refactor the code,
with clean <code>foo.c</code>/<code>foo.h</code> files, no more global variables, no
environment variables...</p>

<p>And a documentation (in the source and as a man page) will be required.</p>
]]></description>
	
</item>
<item>
	
	<title>exploring mwplight</title>
	
	<guid>http://youkan.39mm.net/~nil/iki/101010/mw/20080208-exploring/</guid>
	<link>http://youkan.39mm.net/~nil/iki/101010/mw/20080208-exploring/</link>
	
	
	<category>K__38__R</category>
	
	<category>ansi</category>
	
	<category>en</category>
	
	<category>kernel</category>
	
	<category>mw4</category>
	
	<category>mwp</category>
	
	
	<pubDate>Fri, 08 Feb 2008 00:00:00 +0100</pubDate>
	<dcterms:modified>2008-08-21T18:24:34Z</dcterms:modified>
	
	<description><![CDATA[<p>I chose to start on
<a href="http://youkan.39mm.net/~nil/iki/tags/mw4//darcsweb?r=megawave-4;a=tree;f=/kernel/mwplight"><code>mwplight</code></a>,
because it's a quite little piece of code (11 files, 5746 loc),
independant, already designed for a migration to ANSI C. So far, my surgical
tools are:</p>

<ul>
<li><a href="http://gcc.gnu.org/onlinedocs/gcc/Running-Protoize.html"><code>protoize</code></a>
for the K&amp;R-&gt;ANSI conversion</li>
<li><code>gcc -M</code> for the dependencies handling</li>
<li><code>gcc -ansi -Wall -Wextra -Wc++-compat</code> and <a href="http://www.splint.org/">splint</a> for the code
checks</li>
<li><a href="http://www.gnu.org/software/make/"><code>make</code></a> for a simple and generic
build procedure</li>
</ul>


]]></description>
	
</item>
<item>
	
	<title>megawave 4, day 0</title>
	
	<guid>http://youkan.39mm.net/~nil/iki/101010/mw/20080207-day0/</guid>
	<link>http://youkan.39mm.net/~nil/iki/101010/mw/20080207-day0/</link>
	
	
	<category>darcs</category>
	
	<category>en</category>
	
	<category>mw4</category>
	
	
	<pubDate>Thu, 07 Feb 2008 00:00:00 +0100</pubDate>
	<dcterms:modified>2008-08-21T18:24:34Z</dcterms:modified>
	
	<description><![CDATA[<p>The <em>megawave 4</em> project starts today. Its goal is to produce the next
generation of megawave, which should be:</p>

<ul>
<li>C++ compatible (based on ANSI C, no more K&amp;R style)</li>
<li>with a new and modern GUI library</li>
<li>usable in 32bit <em>and</em> 64bit environments</li>
<li>with new data formats (PNG for example)</li>
<li>thoroughly tested</li>
<li>maybe refactored</li>
<li>easy to build and install (only on linux at the beginning)</li>
<li>with source and binary distribution</li>
<li>under a free software license</li>
</ul>

<p>During this process, the 300+ modules will be deeply reviewed, selected, and
their algorithms documented. And a demo service will be proposed.</p>

<p>So, everything starts with a clean 
<a href="http://youkan.39mm.net/~nil/iki/tags/mw4//darcsweb?r=megawave-4;a=tree">source repository</a> (on a temporary
server for the moment), to provide code history tracking and
documentation, easy distribution, easy review, and better
visibility. For now it's a single-user repo, but it may become open
later, if it seems useful. </p>

<p>I used <a href="http://darcs.net">darcs</a> and
<a href="http://auriga.wearlab.de/~alb/darcsweb/">darcsweb</a>, and maybe found 
<a href="http://bugs.darcs.net/issue649">a minor bug</a> in <code>darcs.cgi</code>.</p>

<p>Why darcs? Because I like it, because it's flexible and
non-intrusive. And because, as a 
<a href="http://en.wikipedia.org/wiki/Distributed_revision_control">distributed revision control system</a>, 
it allows easy local branchs, tests, merge. And it allows to patch
while I'm in the subway :).</p>

<p>I plan to write a brief <em>howto</em> later, for people interested in using it,
from scratch.</p>

<p>From now, I will have to bite in the code, and tests its reactions to
ANSI enforcement.</p>
]]></description>
	
</item>
<item>
	
	<title>megawave 4 draft roadmap</title>
	
	<guid>http://youkan.39mm.net/~nil/iki/101010/mw/20080207-megawave4-roadmap/</guid>
	<link>http://youkan.39mm.net/~nil/iki/101010/mw/20080207-megawave4-roadmap/</link>
	
	
	<category>doc</category>
	
	<category>en</category>
	
	<category>mw4</category>
	
	
	<pubDate>Thu, 07 Feb 2008 00:00:00 +0100</pubDate>
	<dcterms:modified>2008-08-21T18:24:34Z</dcterms:modified>
	
	<description><![CDATA[<h1>main goals</h1>

<ul>
<li>update the languages and tools (ISO C99, GUI library, build process)</li>
<li>support new data formats (PNG)</li>
<li>focus on linux for the moment</li>
<li>improve hardware portability (x86_64)</li>
<li>test the code (syntax, conherence, robustness, performance)</li>
<li>drop the traditional preprocessor</li>
<li>refresh the modules collection</li>
<li>distribute binary packages</li>
<li>build a demo service</li>
</ul>
]]></description>
	
</item>

</channel>
</rss>
