diff --git a/src/modules/Image/colortable.c b/src/modules/Image/colortable.c index 9581cf3bec0104286e8286a759251e70e3153251..5c8a346ff2255fdefddda0f46c8732b541f96707 100644 --- a/src/modules/Image/colortable.c +++ b/src/modules/Image/colortable.c @@ -1,11 +1,11 @@ #include <config.h> -/* $Id: colortable.c,v 1.21 1997/11/05 03:41:33 mirar Exp $ */ +/* $Id: colortable.c,v 1.22 1997/11/07 06:06:05 mirar Exp $ */ /* **! module Image **! note -**! $Id: colortable.c,v 1.21 1997/11/05 03:41:33 mirar Exp $ +**! $Id: colortable.c,v 1.22 1997/11/07 06:06:05 mirar Exp $ **! class colortable **! **! This object keeps colortable information, @@ -21,7 +21,7 @@ #undef COLORTABLE_REDUCE_DEBUG #include "global.h" -RCSID("$Id: colortable.c,v 1.21 1997/11/05 03:41:33 mirar Exp $"); +RCSID("$Id: colortable.c,v 1.22 1997/11/07 06:06:05 mirar Exp $"); #include <sys/types.h> #include <sys/stat.h> @@ -125,26 +125,31 @@ static void free_colortable_struct(struct neo_colortable *nct) } } -static void init_colortable_struct(struct object *o) +static void colortable_init_stuff(struct neo_colortable *nct) { int i; - THIS->type=NCT_NONE; - THIS->lookup_mode=NCT_CUBICLES; - THIS->lu.cubicles.cubicles=NULL; + nct->type=NCT_NONE; + nct->lookup_mode=NCT_CUBICLES; + nct->lu.cubicles.cubicles=NULL; - THIS->spacefactor.r=SPACEFACTOR_R; - THIS->spacefactor.g=SPACEFACTOR_G; - THIS->spacefactor.b=SPACEFACTOR_B; + nct->spacefactor.r=SPACEFACTOR_R; + nct->spacefactor.g=SPACEFACTOR_G; + nct->spacefactor.b=SPACEFACTOR_B; - THIS->lu.cubicles.r=CUBICLE_DEFAULT_R; - THIS->lu.cubicles.g=CUBICLE_DEFAULT_G; - THIS->lu.cubicles.b=CUBICLE_DEFAULT_B; - THIS->lu.cubicles.accur=CUBICLE_DEFAULT_ACCUR; + nct->lu.cubicles.r=CUBICLE_DEFAULT_R; + nct->lu.cubicles.g=CUBICLE_DEFAULT_G; + nct->lu.cubicles.b=CUBICLE_DEFAULT_B; + nct->lu.cubicles.accur=CUBICLE_DEFAULT_ACCUR; for (i=0; i<COLORLOOKUPCACHEHASHSIZE; i++) - THIS->lookupcachehash[i].index=-1; + nct->lookupcachehash[i].index=-1; - THIS->dither_type=NCTD_NONE; + nct->dither_type=NCTD_NONE; +} + +static void init_colortable_struct(struct object *obj) +{ + colortable_init_stuff(THIS); } static void exit_colortable_struct(struct object *obj) @@ -1130,8 +1135,8 @@ static void _img_add_colortable(struct neo_colortable *rdest, struct neo_colortable *dest=rdest; int no; - tmp1.type=NCT_NONE; - tmp2.type=NCT_NONE; /* easy free... */ + colortable_init_stuff(&tmp1); + colortable_init_stuff(&tmp2); if (dest->type==NCT_NONE) { @@ -1312,8 +1317,8 @@ static void _img_sub_colortable(struct neo_colortable *rdest, struct neo_colortable *dest=rdest; int no; - tmp1.type=NCT_NONE; - tmp2.type=NCT_NONE; /* easy free... */ + colortable_init_stuff(&tmp1); + colortable_init_stuff(&tmp2); if (dest->type==NCT_NONE) { @@ -1858,7 +1863,7 @@ void image_colortable_free_dither(struct nct_dither *dith) **! Example: **! <pre> **! ct=colortable(my_image,256); // the best 256 colors -**! ct=colortable(my_image,255,({0,0,0})); // black and the best other 255 +**! ct=colortable(my_image,256,({0,0,0})); // black and the best other 255 **! **! ct=colortable(({({0,0,0}),({255,255,255})})); // black and white **! @@ -1979,9 +1984,7 @@ static void image_colortable_add(INT32 args) if (args>=2) if (sp[1-args].type==T_INT) { - THIS->u.flat=_img_get_flat_from_image(img, - sp[1-args].u.integer); - THIS->type=NCT_FLAT; + int numcolors=sp[1-args].u.integer; if (args>2) { struct object *o; @@ -2004,19 +2007,28 @@ static void image_colortable_add(INT32 args) nct->u.flat.entries[i].weight=WEIGHT_NEEDED; } + numcolors-=image_colortable_size(nct); + if (numcolors<0) numcolors=1; + + THIS->u.flat=_img_get_flat_from_image(img,2500+numcolors); + THIS->type=NCT_FLAT; + push_object(o); image_colortable_add(1); pop_n_elems(1); /* we will keep flat... */ args=2; - } - if (sp[1-args].u.integer>0 && - THIS->u.flat.numentries>sp[1-args].u.integer) THIS->u.flat= _img_reduce_number_of_colors(THIS->u.flat, - sp[1-args].u.integer, + numcolors, THIS->spacefactor); + } + else + { + THIS->u.flat=_img_get_flat_from_image(img,numcolors); + THIS->type=NCT_FLAT; + } } else error("Illegal argument 2 to Image.colortable->add|create\n"); diff --git a/src/modules/Image/colortable.h b/src/modules/Image/colortable.h index 002f582355c2b8f95ddc7883f0d56b4fb0d6b761..d5cb1064760269e037c9cf94cbad7383258fdbcc 100644 --- a/src/modules/Image/colortable.h +++ b/src/modules/Image/colortable.h @@ -1,7 +1,7 @@ /* **! module Image **! note -**! $Id: colortable.h,v 1.6 1997/11/03 01:40:35 mirar Exp $ +**! $Id: colortable.h,v 1.7 1997/11/07 06:06:07 mirar Exp $ */ #define COLORLOOKUPCACHEHASHSIZE 207 @@ -187,3 +187,9 @@ int image_colortable_index_8bit_image(struct neo_colortable *nct, int rowlen); void image_colortable_internal_floyd_steinberg(struct neo_colortable *nct); + +int image_colortable_map_image(struct neo_colortable *nct, + rgb_group *s, + rgb_group *d, + int len, + int rowlen); diff --git a/src/modules/Image/colortable_lookup.h b/src/modules/Image/colortable_lookup.h index 83911c8c24764a253977f457a7656a42d5009f21..a9306e64b71ee57dbd13c0cac08b8d926eca365e 100644 --- a/src/modules/Image/colortable_lookup.h +++ b/src/modules/Image/colortable_lookup.h @@ -1,10 +1,10 @@ -/* $Id: colortable_lookup.h,v 1.3 1997/11/03 01:40:36 mirar Exp $ */ +/* $Id: colortable_lookup.h,v 1.4 1997/11/07 06:06:08 mirar Exp $ */ /* included w/ defines in colortable.c */ /* **! module Image **! note -**! $Id: colortable_lookup.h,v 1.3 1997/11/03 01:40:36 mirar Exp $ +**! $Id: colortable_lookup.h,v 1.4 1997/11/07 06:06:08 mirar Exp $ **! class colortable */ @@ -408,7 +408,7 @@ static void NCTLU_CUBE_NAME(rgb_group *s, lc->dest.r=(unsigned char)drgbr; lc->dest.g=(unsigned char)drgbg; lc->dest.b=(unsigned char)drgbb; - lc->index=i; + lc->index=sc->no[i]; mindist=ldist; NCTLU_CACHE_HIT_WRITE; } diff --git a/src/modules/Image/doc/Image.GIF.html b/src/modules/Image/doc/Image.GIF.html index 04a420a25a3400278df49eaa08d9a793aec2d662..e99e5af303645f8bbfa3c7ccb948d1b4adeeb798 100644 --- a/src/modules/Image/doc/Image.GIF.html +++ b/src/modules/Image/doc/Image.GIF.html @@ -9,13 +9,23 @@ This submodule keep the GIF encode/decode capabilities <p> GIF is a common image storage format, usable for a limited color palette - a GIF image can only contain as most 256 colors - and animations. + +<p> Simple encoding: + <tt><a href=Image.GIF.html#encode>encode</a></tt>, <tt><a href=Image.GIF.html#encode_trans>encode_trans</a></tt> + +<p> Advanced stuff: + <tt><a href=Image.GIF.html#render_block>render_block</a></tt>, <tt><a href=Image.GIF.html#header_block>header_block</a></tt>, + <tt><a href=Image.GIF.html#end_block>end_block</a></tt>, <tt><a href=Image.GIF.html#netscape_loop_block>netscape_loop_block</a></tt> + +<p> Very advanced stuff: + <tt><a href=Image.GIF.html#_render_block>_render_block</a></tt>, <tt><a href=Image.GIF.html#_gce_block>_gce_block</a></tt> </blockquote> <h4>SEE ALSO</h4> <blockquote> <tt><a href=Image.html>Image</a></tt>, - <tt><a href=Image.html>Image.image</a></tt>, - <tt><a href=Image.html>Image.colortable</a></tt> + <tt><a href=Image.image.html>Image.image</a></tt>, + <tt><a href=Image.colortable.html>Image.colortable</a></tt> </blockquote> <hr> @@ -29,8 +39,8 @@ This submodule keep the GIF encode/decode capabilities <blockquote> -This function gives back a Graphic Control Extension block, - normally placed before an render block. +This function gives back a Graphic Control Extension block. + A GCE block has the scope of the following render block. </blockquote> <h4>ARGUMENTS</h4> <blockquote><dl> @@ -68,6 +78,271 @@ This is in the very advanced sector of the GIF support; <p> Most decoders just ignore some or all of these parameters. </blockquote> + +<h4>SEE ALSO</h4> +<blockquote> <tt><a href=Image.GIF.html#_render_block>_render_block</a></tt>, + <tt><a href=Image.GIF.html#render_block>render_block</a></tt> +</blockquote> + +<hr> +<a name=_render_block> </a> +<h4>SYNOPSIS</h4> +<blockquote> +<tt>string <b>_render_block</b>(int x, int y, int xsize, int ysize, int bpp, string indices, 0|string colortable, int interlace);</tt> +</blockquote> + +<h4>DESCRIPTION</h4> + + +<blockquote> +Advanced (!) method for writing renderblocks for placement + in a GIF file. This method only applies LZW encoding on the + indices and makes the correct headers. +</blockquote> +<h4>ARGUMENTS</h4> +<blockquote><dl> +<dt><tt>int x</tt> +<dt><tt>int y</tt> + <dd>Position of this image. +<dt><tt>int xsize</tt> +<dt><tt>int ysize</tt> + <dd>Size of the image. Length if the <tt>indices</tt> string + must be xsize*ysize. +<dt><tt>int bpp</tt> + <dd>Bits per pixels in the indices. Valid range 1..8. +<dt><tt>string indices</tt> + <dd>The image indices as an 8bit indices. +<dt><tt>string colortable</tt> + <dd>Colortable with colors to write as palette. + If this argument is zero, no local colortable is written. + Colortable string len must be 1<<bpp. +<dt><tt>int interlace</tt> + <dd>Interlace index data and set interlace bit. The given string + should _not_ be pre-interlaced. +</dl></blockquote> + + +<h4>NOTE</h4> +<blockquote> +This is in the very advanced sector of the GIF support; + please read about how GIFs file works. +</blockquote> + + +<h4>SEE ALSO</h4> +<blockquote> <tt><a href=Image.GIF.html#encode>encode</a></tt>, + <tt><a href=Image.GIF.html#_encode>_encode</a></tt>, + <tt><a href=Image.GIF.html#header_block>header_block</a></tt>, + <tt><a href=Image.GIF.html#end_block>end_block</a></tt> +</blockquote> + +<hr> +<a name=encode> </a> +<a name=encode_trans> </a> +<h4>SYNOPSIS</h4> +<blockquote> +<tt>string <b>encode</b>(object img);<br> +string <b>encode</b>(object img, int colors);<br> +string <b>encode</b>(object img, object colortable);<br> +string <b>encode_trans</b>(object img, object alpha);<br> +string <b>encode_trans</b>(object img, int tr_r, int tr_g, int tr_b);<br> +string <b>encode_trans</b>(object img, int colors, object alpha);<br> +string <b>encode_trans</b>(object img, int colors, int tr_r, int tr_g, int tr_b);<br> +string <b>encode_trans</b>(object img, int colors, object alpha, int tr_r, int tr_g, int tr_b);<br> +string <b>encode_trans</b>(object img, object colortable, object alpha);<br> +string <b>encode_trans</b>(object img, object colortable, int tr_r, int tr_g, int tr_b);<br> +string <b>encode_trans</b>(object img, object colortable, object alpha, int a_r, int a_g, int a_b);<br> +string <b>encode_trans</b>(object img, object colortable, int transp_index);</tt> +</blockquote> + +<h4>DESCRIPTION</h4> + + +<blockquote> +Create a complete GIF file. + +<p> The latter (<tt><a href=Image.GIF.html#encode_trans>encode_trans</a></tt>) functions + add transparency capabilities. + +<p> Example: + <pre> + img=<tt><a href=Image.image.html>Image.image</a></tt>([...]); + [...] // make your very-nice image + write(<tt><a href=Image.GIF.encode.html>Image.GIF.encode</a></tt>(img)); // write it as GIF on stdout + </pre> +</blockquote> +<h4>ARGUMENTS</h4> +<blockquote><dl> +<dt><tt>object img</tt> + <dd>The image which to encode. +<dt><tt>int colors</tt> +<dt><tt>object colortable</tt> + <dd>These arguments decides what colors the image should + be encoded with. If a number is given, a colortable + with be created with (at most) that amount of colors. + Default is '256' (GIF maximum amount of colors). +<dt><tt>object alpha</tt> + <dd>Alpha channel image (defining what is transparent); black + color indicates transparency. GIF has only transparent + or nontransparent (no real alpha channel). + You can always dither a transparency channel: + <tt>Image.colortable(my_alpha, ({({0,0,0}),({255,255,255})}))<wbr> + ->full()<wbr>->floyd_steinberg()<wbr>->map(my_alpha)</tt> +<dt><tt>int tr_r</tt> +<dt><tt>int tr_g</tt> +<dt><tt>int tr_b</tt> + <dd>Use this (or the color closest to this) color as transparent + pixels. +<dt><tt>int a_r</tt> +<dt><tt>int a_g</tt> +<dt><tt>int a_b</tt> + <dd>Encode transparent pixels (given by alpha channel image) + to have this color. This option is for making GIFs for + the decoders that doesn't support transparency. +<dt><tt>int transp_index</tt> + <dd>Use this color no in the colortable as transparent color. +</dl></blockquote> + + +<h4>NOTE</h4> +<blockquote> +For advanced users: + <pre>Image.GIF.encode_trans(img,colortable,alpha);</pre> + is equivalent of using + <pre>Image.GIF.header_block(img->xsize(),img->ysize(),colortable)+ + Image.GIF.render_block(img,colortable,0,0,0,alpha)+ + Image.GIF.end_block();</pre> + and is actually implemented that way. +</blockquote> + +<hr> +<a name=end_block> </a> +<h4>SYNOPSIS</h4> +<blockquote> +<tt>string <b>end_block</b>();</tt> +</blockquote> + +<h4>DESCRIPTION</h4> + + +<blockquote> +This function gives back a GIF end (trailer) block. +</blockquote> +<h4>RETURNS</h4> + + +<blockquote> +the end block as a string. +</blockquote> + + +<h4>NOTE</h4> +<blockquote> +This is in the advanced sector of the GIF support; + please read some about how GIFs are packed. + +<p> The result of this function is always ";" or "\x3b", + but I recommend using this function anyway for code clearity. +</blockquote> + + +<h4>SEE ALSO</h4> +<blockquote> <tt><a href=Image.GIF.html#header_block>header_block</a></tt>, + <tt><a href=Image.GIF.html#end_block>end_block</a></tt> +</blockquote> + +<hr> +<a name=header_block> </a> +<h4>SYNOPSIS</h4> +<blockquote> +<tt>string <b>header_block</b>(int xsize, int ysize, int numcolors);<br> +string <b>header_block</b>(int xsize, int ysize, object colortable);<br> +string <b>header_block</b>(int xsize, int ysize, object colortable, int background_color_index, int gif87a, int aspectx, int aspecty);<br> +string <b>header_block</b>(int xsize, int ysize, object colortable, int background_color_index, int gif87a, int aspectx, int aspecty, int r, int g, int b);</tt> +</blockquote> + +<h4>DESCRIPTION</h4> + + +<blockquote> +This function gives back a GIF header block. + +<p> Giving a colortable to this function includes a + global palette in the header block. +</blockquote> +<h4>ARGUMENTS</h4> +<blockquote><dl> +<dt><tt>int xsize</tt> +<dt><tt>int ysize</tt> + <dd>Size of drawing area. Usually same size as in + the first (or only) render block(s). +<dt><tt>int background_color_index</tt> + <dd>This color in the palette is the background color. + Background is visible if the following render block(s) + doesn't fill the drawing area or are transparent. + Most decoders doesn't use this value, though. +<dt><tt>int gif87a</tt> + <dd>If set, write 'GIF87a' instead of 'GIF89a' (default 0 == 89a). +<dt><tt>int aspectx</tt> +<dt><tt>int aspecty</tt> + <dd>Aspect ratio of pixels, + ranging from 4:1 to 1:4 in increments + of 1/16th. Ignored by most decoders. + If any of <tt>aspectx</tt> or <tt>aspecty</tt> is zero, + aspectratio information is skipped. +<dt><tt>int r</tt> +<dt><tt>int g</tt> +<dt><tt>int b</tt> + <dd>Add this color as the transparent color. + This is the color used as transparency color in + case of alpha-channel given as image object. + This increases (!) the number of colors by one. +</dl></blockquote> +<h4>RETURNS</h4> + + +<blockquote> +the created header block as a string +</blockquote> + + +<h4>NOTE</h4> +<blockquote> +This is in the advanced sector of the GIF support; + please read some about how GIFs are packed. + +<p> This GIF encoder doesn't support different size + of colors in global palette and color resolution. +</blockquote> + + +<h4>SEE ALSO</h4> +<blockquote> <tt><a href=Image.GIF.html#header_block>header_block</a></tt>, + <tt><a href=Image.GIF.html#end_block>end_block</a></tt> +</blockquote> + +<hr> +<a name=netscape_loop_block> </a> +<h4>SYNOPSIS</h4> +<blockquote> +<tt>string <b>netscape_loop_block</b>();<br> +string <b>netscape_loop_block</b>(int number_of_loops);</tt> +</blockquote> + +<h4>DESCRIPTION</h4> + + +<blockquote> +Creates a application-specific extention block; + this block makes netscape and compatible browsers + loop the animation a certain amount of times. +</blockquote> +<h4>ARGUMENTS</h4> +<blockquote><dl> +<dt><tt>int number_of_loops</tt> + <dd>Number of loops. Max and default is 65535. +</dl></blockquote> + <hr> <a name=render_block> </a> <h4>SYNOPSIS</h4> @@ -76,8 +351,8 @@ This is in the very advanced sector of the GIF support; string <b>render_block</b>(object img, object colortable, int x, int y, int localpalette, int transp_index);<br> string <b>render_block</b>(object img, object colortable, int x, int y, int localpalette, object alpha);<br> string <b>render_block</b>(object img, object colortable, int x, int y, int localpalette, object alpha, int r, int g, int b);<br> -string <b>render_block</b>(object img, object colortable, int x, int y, int localpalette, int transp_index, int interlace, int delay, int user_input, int disposal);<br> -string <b>render_block</b>(object img, object colortable, int x, int y, int localpalette, object alpha, int r, int g, int b, int interlace, int delay, int user_input, int disposal);</tt> +string <b>render_block</b>(object img, object colortable, int x, int y, int localpalette, int delay, int transp_index, int interlace, int user_input, int disposal);<br> +string <b>render_block</b>(object img, object colortable, int x, int y, int localpalette, object alpha, int r, int g, int b, int delay, int interlace, int user_input, int disposal);</tt> </blockquote> <h4>DESCRIPTION</h4> @@ -90,30 +365,43 @@ This function gives a image block for placement in a GIF file, the first with graphic control extensions for such things as delay or transparency. -<p> object img - The image. - object colortable - Colortable with colors to use and to write as palette. +<p> Example: + <pre> + img1=<tt><a href=Image.image.html>Image.image</a></tt>([...]); + img2=<tt><a href=Image.image.html>Image.image</a></tt>([...]); + [...] // make your very-nice images + nct=<tt><a href=Image.colortable.html>Image.colortable</a></tt>([...]); // make a nice colortable + write(<tt><a href=Image.GIF.header_block.html>Image.GIF.header_block</a></tt>(xsize,ysize,nct)); // write a GIF header + write(<tt><a href=Image.GIF.render_block.html>Image.GIF.render_block</a></tt>(img1,nct,0,0,0,10)); // write a render block + write(<tt><a href=Image.GIF.render_block.html>Image.GIF.render_block</a></tt>(img2,nct,0,0,0,10)); // write a render block + [...] + write(<tt><a href=Image.GIF.end_block.html>Image.GIF.end_block</a></tt>()); // write end block + // voila! A GIF animation on stdout. + </pre> </blockquote> <h4>ARGUMENTS</h4> <blockquote><dl> +<dt><tt>object img</tt> + <dd>The image. +<dt><tt>object colortable</tt> + <dd>Colortable with colors to use and to write as palette. <dt><tt>int x</tt> <dt><tt>int y</tt> <dd>Position of this image. - int localpalette - If set, writes a local palette. - int transp_index - Index of the transparent color in the colortable. - <tt>-1</tt> indicates no transparency. - object alpha - Alpha channel image; black is transparent. - int r - int g - int b - Color of transparent pixels. Not all decoders understands - transparency. +<dt><tt>int localpalette</tt> + <dd>If set, writes a local palette. +<dt><tt>object alpha</tt> + <dd>Alpha channel image; black is transparent. +<dt><tt>int r</tt> +<dt><tt>int g</tt> +<dt><tt>int b</tt> + <dd>Color of transparent pixels. Not all decoders understands + transparency. This is ignored if localpalette isn't set. <dt><tt>int delay</tt> <dd>View this image for this many centiseconds. Default is zero. +<dt><tt>int transp_index</tt> + <dd>Index of the transparent color in the colortable. + <tt>-1</tt> indicates no transparency. <dt><tt>int user_input</tt> <dd>If set: wait the delay or until user input. If delay is zero, wait indefinitely for user input. May sound the bell @@ -146,8 +434,7 @@ This is in the advanced sector of the GIF support; <h4>SEE ALSO</h4> -<blockquote> <tt><a href=Image.GIF.html#::encode>encode</a></tt>, - <tt><a href=Image.GIF.html#::_encode>_encode</a></tt>, - <tt><a href=Image.GIF.html#::header_block>header_block</a></tt>, - <tt><a href=Image.GIF.html#::end_block>end_block</a></tt> +<blockquote> <tt><a href=Image.GIF.html#encode>encode</a></tt>, + <tt><a href=Image.GIF.html#header_block>header_block</a></tt>, + <tt><a href=Image.GIF.html#end_block>end_block</a></tt> </blockquote> diff --git a/src/modules/Image/doc/Image.PNM.html b/src/modules/Image/doc/Image.PNM.html index b9435cea34cb1627e9ecdbbb269783018a826649..4860830c343b5ff09db989bd845b9790887be852 100644 --- a/src/modules/Image/doc/Image.PNM.html +++ b/src/modules/Image/doc/Image.PNM.html @@ -26,8 +26,8 @@ This submodule keep the PNM encode/decode capabilities <h4>SEE ALSO</h4> <blockquote> <tt><a href=Image.html>Image</a></tt>, - <tt><a href=Image.html>Image.image</a></tt>, - <tt><a href=Image.html>Image.GIF</a></tt> + <tt><a href=Image.image.html>Image.image</a></tt>, + <tt><a href=Image.GIF.html>Image.GIF</a></tt> </blockquote> <hr> @@ -58,7 +58,7 @@ This function may throw errors upon illegal PNM data. <h4>SEE ALSO</h4> -<blockquote> <tt><a href=Image.PNM.html#::encode>encode</a></tt> +<blockquote> <tt><a href=Image.PNM.html#encode>encode</a></tt> </blockquote> <hr> @@ -78,11 +78,11 @@ string <b>encode_P6</b>(object image)</tt> <blockquote> Make a complete PNM file from an image. -<p> <tt><a href=Image.PNM.html#::encode_binary>encode_binary</a></tt>() and <tt><a href=Image.PNM.html#::encode_ascii>encode_ascii</a></tt>() +<p> <tt><a href=Image.PNM.html#encode_binary>encode_binary</a></tt>() and <tt><a href=Image.PNM.html#encode_ascii>encode_ascii</a></tt>() uses the most optimized encoding for this image (bitmap, grey or truecolor) - P4, P5 or P6 respective P1, P2 or P3. -<p> <tt><a href=Image.PNM.html#::encode>encode</a></tt>() maps to <tt><a href=Image.PNM.html#::encode_binary>encode_binary</a></tt>(). +<p> <tt><a href=Image.PNM.html#encode>encode</a></tt>() maps to <tt><a href=Image.PNM.html#encode_binary>encode_binary</a></tt>(). </blockquote> <h4>RETURNS</h4> @@ -100,5 +100,5 @@ Currently only supports type P5 (binary grey) and <h4>SEE ALSO</h4> -<blockquote> <tt><a href=Image.PNM.html#::decode>decode</a></tt> +<blockquote> <tt><a href=Image.PNM.html#decode>decode</a></tt> </blockquote> diff --git a/src/modules/Image/doc/Image.colortable.html b/src/modules/Image/doc/Image.colortable.html index f54451c53bb302b59d28d0a7c4c16ae599dc6dfd..fdf42850aa48c68ecd6e2758b5ca54a163825926 100644 --- a/src/modules/Image/doc/Image.colortable.html +++ b/src/modules/Image/doc/Image.colortable.html @@ -13,9 +13,9 @@ This object keeps colortable information, <h4>SEE ALSO</h4> <blockquote> <tt><a href=Image.html>Image</a></tt>, - <tt><a href=Image.html>Image.image</a></tt>, - <tt><a href=Image.html>Image.font</a></tt>, - <tt><a href=Image.html>Image.GIF</a></tt> + <tt><a href=Image.image.html>Image.image</a></tt>, + <tt><a href=Image.font.html>Image.font</a></tt>, + <tt><a href=Image.GIF.html>Image.GIF</a></tt> </blockquote> <hr> @@ -52,7 +52,7 @@ Map colors in an image object to the colors in <td><a href=illustrations.html#illustration_7.gif><img border=0 src=illustration_7.gif width=67 height=67></a></td> <td><a href=illustrations.html#illustration_8.gif><img border=0 src=illustration_8.gif width=67 height=67></a></td> <td><a href=illustrations.html#illustration_9.gif><img border=0 src=illustration_9.gif width=67 height=67></a></td> - <td><tt><a href=Image.html>floyd_steinberg</a></tt> dither</td> + <td><tt><a href=Image.colortable.html#floyd_steinberg>floyd_steinberg</a></tt> dither</td> </tr><tr valign=center> <td></td> <td><a href=illustrations.html#illustration_10.gif><img border=0 src=illustration_10.gif width=67 height=67></a></td> @@ -60,7 +60,7 @@ Map colors in an image object to the colors in <td><a href=illustrations.html#illustration_12.gif><img border=0 src=illustration_12.gif width=67 height=67></a></td> <td><a href=illustrations.html#illustration_13.gif><img border=0 src=illustration_13.gif width=67 height=67></a></td> <td><a href=illustrations.html#illustration_14.gif><img border=0 src=illustration_14.gif width=67 height=67></a></td> - <td><tt><a href=Image.html>ordered</a></tt> dither</td> + <td><tt><a href=Image.colortable.html#ordered>ordered</a></tt> dither</td> </tr><tr valign=center> <td><img src=lena.gif width=67 height=67></td> <td><a href=illustrations.html#illustration_16.gif><img border=0 src=illustration_16.gif width=67 height=67></a></td> @@ -68,7 +68,7 @@ Map colors in an image object to the colors in <td><a href=illustrations.html#illustration_18.gif><img border=0 src=illustration_18.gif width=67 height=67></a></td> <td><a href=illustrations.html#illustration_19.gif><img border=0 src=illustration_19.gif width=67 height=67></a></td> <td><a href=illustrations.html#illustration_20.gif><img border=0 src=illustration_20.gif width=67 height=67></a></td> - <td><tt><a href=Image.html>randomcube</a></tt> dither</td> + <td><tt><a href=Image.colortable.html#randomcube>randomcube</a></tt> dither</td> </tr><tr valign=center> <td>original</td> <td>2</td> @@ -88,7 +88,7 @@ a new image object <h4>NOTE</h4> <blockquote> -Flat (not cube) colortable and not '<tt><a href=Image.html>full</a></tt>' method: +Flat (not cube) colortable and not '<tt><a href=Image.colortable.html#full>full</a></tt>' method: this method does figure out the data needed for the lookup method, which may take time the first use of the colortable - the second use is quicker. @@ -96,8 +96,8 @@ Flat (not cube) colortable and not '<tt><a href=Image.html>full</a></tt>' method <h4>SEE ALSO</h4> -<blockquote> <tt><a href=Image.html>cubicles</a></tt>, - <tt><a href=Image.html>full</a></tt> +<blockquote> <tt><a href=Image.colortable.html#cubicles>cubicles</a></tt>, + <tt><a href=Image.colortable.html#full>full</a></tt> </blockquote> <hr> @@ -116,7 +116,7 @@ sums colortables <h4>ARGUMENTS</h4> <blockquote><dl> <dt><tt>object(<ref>colortable</ref>) with</tt> - <dd><tt><a href=Image.html>colortable</a></tt> object with colors to add + <dd><tt><a href=Image.colortable.html#colortable>colortable</a></tt> object with colors to add </dl></blockquote> <h4>RETURNS</h4> @@ -141,7 +141,7 @@ subtracts colortables <h4>ARGUMENTS</h4> <blockquote><dl> <dt><tt>object(<ref>colortable</ref>) with</tt> - <dd><tt><a href=Image.html>colortable</a></tt> object with colors to subtract + <dd><tt><a href=Image.colortable.html#colortable>colortable</a></tt> object with colors to subtract </dl></blockquote> <h4>RETURNS</h4> @@ -172,11 +172,11 @@ object <b>add</b>(int r, int g, int b, array(int) from <blockquote> -<tt><a href=Image.html>create</a></tt> initiates a colortable object. +<tt><a href=Image.colortable.html#create>create</a></tt> initiates a colortable object. Default is that no colors are in the colortable. -<p> <tt><a href=Image.html>create</a></tt> can also take the same arguments - as <tt><a href=Image.html>add</a></tt>, thus adding colors to the colortable. +<p> <tt><a href=Image.colortable.html#add>add</a></tt> takes the same argument as + <tt><a href=Image.colortable.html#create>create</a></tt>, thus adding colors to the colortable. <p> The colortable is mostly a list of colors, or more advanced, colors and weight. @@ -320,7 +320,7 @@ Set the colortable to use the cubicles algorithm to lookup 1000�1000 cubicles(12,12,12) (factor 2 faster than default) </pre> -<p> In some cases, the <tt><a href=Image.html>full</a></tt> method is faster. +<p> In some cases, the <tt><a href=Image.colortable.html#full>full</a></tt> method is faster. <p> <table><tr valign=center> <td><img src=lena.gif width=67 height=67></td> @@ -450,8 +450,8 @@ Not applicable to colorcube types of colortable. <h4>SEE ALSO</h4> -<blockquote> <tt><a href=Image.html>cubicles</a></tt>, - <tt><a href=Image.html>map</a></tt> +<blockquote> <tt><a href=Image.colortable.html#cubicles>cubicles</a></tt>, + <tt><a href=Image.colortable.html#map>map</a></tt> </blockquote> <hr> @@ -543,10 +543,10 @@ the called object <h4>SEE ALSO</h4> -<blockquote> <tt><a href=Image.html>randomcube</a></tt>, - <tt><a href=Image.html>nodither</a></tt>, - <tt><a href=Image.html>floyd_steinberg</a></tt>, - <tt><a href=Image.html>create</a></tt> +<blockquote> <tt><a href=Image.colortable.html#randomcube>randomcube</a></tt>, + <tt><a href=Image.colortable.html#nodither>nodither</a></tt>, + <tt><a href=Image.colortable.html#floyd_steinberg>floyd_steinberg</a></tt>, + <tt><a href=Image.colortable.html#create>create</a></tt> </blockquote> <hr> @@ -606,17 +606,17 @@ the called object <h4>NOTE</h4> <blockquote> -<tt><a href=Image.html>randomgrey</a></tt> method needs colorcube size to be the same on +<tt><a href=Image.colortable.html#randomgrey>randomgrey</a></tt> method needs colorcube size to be the same on red, green and blue sides to work properly. It uses the red colorcube value as default. </blockquote> <h4>SEE ALSO</h4> -<blockquote> <tt><a href=Image.html>ordered</a></tt>, - <tt><a href=Image.html>nodither</a></tt>, - <tt><a href=Image.html>floyd_steinberg</a></tt>, - <tt><a href=Image.html>create</a></tt> +<blockquote> <tt><a href=Image.colortable.html#ordered>ordered</a></tt>, + <tt><a href=Image.colortable.html#nodither>nodither</a></tt>, + <tt><a href=Image.colortable.html#floyd_steinberg>floyd_steinberg</a></tt>, + <tt><a href=Image.colortable.html#create>create</a></tt> </blockquote> <hr> @@ -632,7 +632,7 @@ the called object <blockquote> reduces the number of colors -<p> All needed (see <tt><a href=Image.html>create</a></tt>) colors are kept. +<p> All needed (see <tt><a href=Image.colortable.html#create>create</a></tt>) colors are kept. </blockquote> <h4>ARGUMENTS</h4> <blockquote><dl> @@ -661,8 +661,8 @@ Colortable tuning option, this sets the color space distance factors. This is used when comparing distances in the colorspace and comparing grey levels. -<p> Default factors are 2, 3 and 1; blue is much - darker than green. Compare with <tt><a href=Image.html>Image.image::grey</a></tt>(). +<p> Default factors are 3, 4 and 1; blue is much + darker than green. Compare with <tt><a href=Image.image::grey.html>Image.image::grey</a></tt>(). </blockquote> <h4>RETURNS</h4> diff --git a/src/modules/Image/doc/Image.font.html b/src/modules/Image/doc/Image.font.html index b278b53b74e704b74d337d448eb09085319fb422..a9824cabdf71ca87bab7713f434d2ed508633327 100644 --- a/src/modules/Image/doc/Image.font.html +++ b/src/modules/Image/doc/Image.font.html @@ -9,13 +9,13 @@ Short technical documentation on a font file: capabilities of the <tt><a href=Image.html>Image</a></tt> module. <p> For simple usage, see - <tt><a href=Image.html>write</a></tt> and <tt><a href=Image.html>load</a></tt>. + <tt><a href=Image.font.html#write>write</a></tt> and <tt><a href=Image.font.html#load>load</a></tt>. -<p> other methods: <tt><a href=Image.html>baseline</a></tt>, - <tt><a href=Image.html>height</a></tt>, - <tt><a href=Image.html>set_xspacing_scale</a></tt>, - <tt><a href=Image.html>set_yspacing_scale</a></tt>, - <tt><a href=Image.html>text_extents</a></tt> +<p> other methods: <tt><a href=Image.font.html#baseline>baseline</a></tt>, + <tt><a href=Image.font.html#height>height</a></tt>, + <tt><a href=Image.font.html#set_xspacing_scale>set_xspacing_scale</a></tt>, + <tt><a href=Image.font.html#set_yspacing_scale>set_yspacing_scale</a></tt>, + <tt><a href=Image.font.html#text_extents>text_extents</a></tt> <pre> struct file_head @@ -39,7 +39,7 @@ Short technical documentation on a font file: <h4>SEE ALSO</h4> <blockquote> <tt><a href=Image.html>Image</a></tt>, - <tt><a href=Image.html>Image.image</a></tt> + <tt><a href=Image.image.html>Image.image</a></tt> </blockquote> <hr> @@ -58,8 +58,8 @@ font baseline (pixels from top) <h4>SEE ALSO</h4> -<blockquote> <tt><a href=Image.html>height</a></tt>, - <tt><a href=Image.html>text_extents</a></tt> +<blockquote> <tt><a href=Image.font.html#height>height</a></tt>, + <tt><a href=Image.font.html#text_extents>text_extents</a></tt> </blockquote> <hr> @@ -76,7 +76,7 @@ array(int) <b>text_extents</b>(string text, ...)</tt> <blockquote> Calculate extents of a text-image, - that would be created by calling <tt><a href=Image.html>write</a></tt> + that would be created by calling <tt><a href=Image.font.html#write>write</a></tt> with the same arguments. </blockquote> <h4>ARGUMENTS</h4> @@ -93,9 +93,9 @@ an array of width and height <h4>SEE ALSO</h4> -<blockquote> <tt><a href=Image.html>write</a></tt>, - <tt><a href=Image.html>height</a></tt>, - <tt><a href=Image.html>baseline</a></tt> +<blockquote> <tt><a href=Image.font.html#write>write</a></tt>, + <tt><a href=Image.font.html#height>height</a></tt>, + <tt><a href=Image.font.html#baseline>baseline</a></tt> </blockquote> <hr> @@ -125,7 +125,7 @@ zero upon failure, font object upon success <h4>SEE ALSO</h4> -<blockquote> <tt><a href=Image.html>write</a></tt> +<blockquote> <tt><a href=Image.font.html#write>write</a></tt> </blockquote> <hr> @@ -174,13 +174,13 @@ Writes some text; thus creating an image object <blockquote> -an <ref>Image::image</ref> object +an <ref>Image.image</ref> object </blockquote> <h4>SEE ALSO</h4> -<blockquote> <tt><a href=Image.html>text_extents</a></tt>, - <tt><a href=Image.html>load</a></tt>, - <tt><a href=Image.html>image::paste_mask</a></tt>, - <tt><a href=Image.html>image::paste_alpha_color</a></tt> +<blockquote> <tt><a href=Image.font.html#text_extents>text_extents</a></tt>, + <tt><a href=Image.font.html#load>load</a></tt>, + <tt><a href=Image.image.html#paste_mask>Image.image->paste_mask</a></tt>, + <tt><a href=Image.image.html#paste_alpha_color>Image.image->paste_alpha_color</a></tt> </blockquote> diff --git a/src/modules/Image/doc/Image.html b/src/modules/Image/doc/Image.html index bbbf85d53d069302b48a157ef6ac94cac61d60df..2d9dfc9a9f6535cca066998d7d4d992ceb5079f6 100644 --- a/src/modules/Image/doc/Image.html +++ b/src/modules/Image/doc/Image.html @@ -8,19 +8,19 @@ This module adds image-drawing and -manipulating <p> <table border=0> <tr> - <td align=left valign=top><tt><a href=Image.html>Image.image</a></tt></td> + <td align=left valign=top><tt><a href=Image.image.html>Image.image</a></tt></td> <td align=left valign=top>Basic image manipulation</td> </tr> <tr> - <td align=left valign=top><tt><a href=Image.html>Image.font</a></tt></td> + <td align=left valign=top><tt><a href=Image.font.html>Image.font</a></tt></td> <td align=left valign=top>Creating images from text</td> </tr> <tr> - <td align=left valign=top><tt><a href=Image.html>Image.colortable</a></tt></td> + <td align=left valign=top><tt><a href=Image.colortable.html>Image.colortable</a></tt></td> <td align=left valign=top>Color reduction, quantisation and dither</td> </tr> <tr> - <td align=left valign=top><tt><a href=Image.html>Image.GIF</a></tt></td> + <td align=left valign=top><tt><a href=Image.GIF.html>Image.GIF</a></tt></td> <td align=left valign=top>GIF encoding/decoding capabilities</td> </tr> </table> @@ -30,26 +30,26 @@ This module adds image-drawing and -manipulating <h4>NOTE</h4> <blockquote> <font size=-1><pre>file versions: - $Id: Image.html,v 1.11 1997/11/02 03:44:32 mirar Exp $ - $Id: Image.html,v 1.11 1997/11/02 03:44:32 mirar Exp $ - $Id: Image.html,v 1.11 1997/11/02 03:44:32 mirar Exp $ - $Id: Image.html,v 1.11 1997/11/02 03:44:32 mirar Exp $ - $Id: Image.html,v 1.11 1997/11/02 03:44:32 mirar Exp $ - $Id: Image.html,v 1.11 1997/11/02 03:44:32 mirar Exp $ - $Id: Image.html,v 1.11 1997/11/02 03:44:32 mirar Exp $ - $Id: Image.html,v 1.11 1997/11/02 03:44:32 mirar Exp $ - $Id: Image.html,v 1.11 1997/11/02 03:44:32 mirar Exp $ - $Id: Image.html,v 1.11 1997/11/02 03:44:32 mirar Exp $ - $Id: Image.html,v 1.11 1997/11/02 03:44:32 mirar Exp $ - $Id: Image.html,v 1.11 1997/11/02 03:44:32 mirar Exp $ - $Id: Image.html,v 1.11 1997/11/02 03:44:32 mirar Exp $ - $Id: Image.html,v 1.11 1997/11/02 03:44:32 mirar Exp $ - $Id: Image.html,v 1.11 1997/11/02 03:44:32 mirar Exp $ - $Id: Image.html,v 1.11 1997/11/02 03:44:32 mirar Exp $ - $Id: Image.html,v 1.11 1997/11/02 03:44:32 mirar Exp $ - $Id: Image.html,v 1.11 1997/11/02 03:44:32 mirar Exp $ - $Id: Image.html,v 1.11 1997/11/02 03:44:32 mirar Exp $ - $Id: Image.html,v 1.11 1997/11/02 03:44:32 mirar Exp $ - $Id: Image.html,v 1.11 1997/11/02 03:44:32 mirar Exp $ + $Id: Image.html,v 1.12 1997/11/07 06:06:25 mirar Exp $ + $Id: Image.html,v 1.12 1997/11/07 06:06:25 mirar Exp $ + $Id: Image.html,v 1.12 1997/11/07 06:06:25 mirar Exp $ + $Id: Image.html,v 1.12 1997/11/07 06:06:25 mirar Exp $ + $Id: Image.html,v 1.12 1997/11/07 06:06:25 mirar Exp $ + $Id: Image.html,v 1.12 1997/11/07 06:06:25 mirar Exp $ + $Id: Image.html,v 1.12 1997/11/07 06:06:25 mirar Exp $ + $Id: Image.html,v 1.12 1997/11/07 06:06:25 mirar Exp $ + $Id: Image.html,v 1.12 1997/11/07 06:06:25 mirar Exp $ + $Id: Image.html,v 1.12 1997/11/07 06:06:25 mirar Exp $ + $Id: Image.html,v 1.12 1997/11/07 06:06:25 mirar Exp $ + $Id: Image.html,v 1.12 1997/11/07 06:06:25 mirar Exp $ + $Id: Image.html,v 1.12 1997/11/07 06:06:25 mirar Exp $ + $Id: Image.html,v 1.12 1997/11/07 06:06:25 mirar Exp $ + $Id: Image.html,v 1.12 1997/11/07 06:06:25 mirar Exp $ + $Id: Image.html,v 1.12 1997/11/07 06:06:25 mirar Exp $ + $Id: Image.html,v 1.12 1997/11/07 06:06:25 mirar Exp $ + $Id: Image.html,v 1.12 1997/11/07 06:06:25 mirar Exp $ + $Id: Image.html,v 1.12 1997/11/07 06:06:25 mirar Exp $ + $Id: Image.html,v 1.12 1997/11/07 06:06:25 mirar Exp $ + $Id: Image.html,v 1.12 1997/11/07 06:06:25 mirar Exp $ </pre> </blockquote> diff --git a/src/modules/Image/doc/Image.image.html b/src/modules/Image/doc/Image.image.html index edf9179b17979355e423fc595fbce9ff8266780d..64f4c67e36dea7506e29547880e96fc591f23726 100644 --- a/src/modules/Image/doc/Image.image.html +++ b/src/modules/Image/doc/Image.image.html @@ -6,94 +6,94 @@ The main object of the <tt><a href=Image.html>Image</a></tt> module, this object is used as drawing area, mask or result of operations. -<p> init: <tt><a href=Image.html>clear</a></tt>, - <tt><a href=Image.html>clone</a></tt>, - <tt><a href=Image.html>create</a></tt>, - <tt><a href=Image.html>xsize</a></tt>, - <tt><a href=Image.html>ysize</a></tt> - -<p> plain drawing: <tt><a href=Image.html>box</a></tt>, - <tt><a href=Image.html>circle</a></tt>, - <tt><a href=Image.html>getpixel</a></tt>, - <tt><a href=Image.html>line</a></tt>, - <tt><a href=Image.html>setcolor</a></tt>, - <tt><a href=Image.html>setpixel</a></tt>, - <tt><a href=Image.html>treshold</a></tt>, - <tt><a href=Image.html>tuned_box</a></tt>, - <tt><a href=Image.html>polygone</a></tt> - -<p> operators: <tt><a href=Image.html>`&</a></tt>, - <tt><a href=Image.html>`*</a></tt>, - <tt><a href=Image.html>`+</a></tt>, - <tt><a href=Image.html>`-</a></tt>, - <tt><a href=Image.html>`|</a></tt> - -<p> pasting images, layers: <tt><a href=Image.html>add_layers</a></tt>, - <tt><a href=Image.html>paste</a></tt>, - <tt><a href=Image.html>paste_alpha</a></tt>, - <tt><a href=Image.html>paste_alpha_color</a></tt>, - <tt><a href=Image.html>paste_mask</a></tt> - -<p> getting subimages, scaling, rotating: <tt><a href=Image.html>autocrop</a></tt>, - <tt><a href=Image.html>clone</a></tt>, - <tt><a href=Image.html>copy</a></tt>, - <tt><a href=Image.html>dct</a></tt>, - <tt><a href=Image.html>mirrorx</a></tt>, - <tt><a href=Image.html>rotate</a></tt>, - <tt><a href=Image.html>rotate_expand</a></tt>, - <tt><a href=Image.html>rotate_ccw</a></tt>, - <tt><a href=Image.html>rotate_cw</a></tt>, - <tt><a href=Image.html>scale</a></tt>, - <tt><a href=Image.html>skewx</a></tt>, - <tt><a href=Image.html>skewx_expand</a></tt>, - <tt><a href=Image.html>skewy</a></tt>, - <tt><a href=Image.html>skewy_expand</a></tt> - -<p> calculation by pixels: <tt><a href=Image.html>apply_matrix</a></tt>, - <tt><a href=Image.html>change_color</a></tt>, - <tt><a href=Image.html>color</a></tt>, - <tt><a href=Image.html>distancesq</a></tt>, - <tt><a href=Image.html>grey</a></tt>, - <tt><a href=Image.html>invert</a></tt>, - <tt><a href=Image.html>map_closest</a></tt>, - <tt><a href=Image.html>map_fast</a></tt>, - <tt><a href=Image.html>select_colors</a></tt>, - <tt><a href=Image.html>modify_by_intensity</a></tt>, - <tt><a href=Image.html>select_from</a></tt>, - <tt><a href=Image.html>rgb_to_hsv</a></tt>, - <tt><a href=Image.html>hsv_to_rgb</a></tt> - -<p> converting to other datatypes: <tt><a href=Image.html>cast</a></tt>, - <tt><a href=Image.html>fromgif</a></tt>, - <tt><a href=Image.html>frompnm</a></tt>/<tt><a href=Image.html>fromppm</a></tt>, - <tt><a href=Image.html>gif_add</a></tt>, - <tt><a href=Image.html>gif_add_fs</a></tt>, - <tt><a href=Image.html>gif_add_fs_nomap</a></tt>, - <tt><a href=Image.html>gif_add_nomap</a></tt>, - <tt><a href=Image.html>gif_begin</a></tt>, - <tt><a href=Image.html>gif_end</a></tt>, - <tt><a href=Image.html>gif_netscape_loop</a></tt>, - <tt><a href=Image.html>gif_transparency</a></tt>, - <tt><a href=Image.html>to8bit</a></tt>, - <tt><a href=Image.html>to8bit_closest</a></tt>, - <tt><a href=Image.html>to8bit_fs</a></tt>, - <tt><a href=Image.html>to8bit_rgbcube</a></tt>, - <tt><a href=Image.html>to8bit_rgbcube_rdither</a></tt>, - <tt><a href=Image.html>tobitmap</a></tt>, - <tt><a href=Image.html>togif</a></tt>, - <tt><a href=Image.html>togif_fs</a></tt>, - <tt><a href=Image.html>toppm</a></tt>, - <tt><a href=Image.html>tozbgr</a></tt> +<p> init: <tt><a href=Image.image.html#clear>clear</a></tt>, + <tt><a href=Image.image.html#clone>clone</a></tt>, + <tt><a href=Image.image.html#create>create</a></tt>, + <tt><a href=Image.image.html#xsize>xsize</a></tt>, + <tt><a href=Image.image.html#ysize>ysize</a></tt> + +<p> plain drawing: <tt><a href=Image.image.html#box>box</a></tt>, + <tt><a href=Image.image.html#circle>circle</a></tt>, + <tt><a href=Image.image.html#getpixel>getpixel</a></tt>, + <tt><a href=Image.image.html#line>line</a></tt>, + <tt><a href=Image.image.html#setcolor>setcolor</a></tt>, + <tt><a href=Image.image.html#setpixel>setpixel</a></tt>, + <tt><a href=Image.image.html#treshold>treshold</a></tt>, + <tt><a href=Image.image.html#tuned_box>tuned_box</a></tt>, + <tt><a href=Image.image.html#polygone>polygone</a></tt> + +<p> operators: <tt><a href=Image.image.html#%60%26>`&</a></tt>, + <tt><a href=Image.image.html#%60*>`*</a></tt>, + <tt><a href=Image.image.html#%60+>`+</a></tt>, + <tt><a href=Image.image.html#%60->`-</a></tt>, + <tt><a href=Image.image.html#%60|>`|</a></tt> + +<p> pasting images, layers: <tt><a href=Image.image.html#add_layers>add_layers</a></tt>, + <tt><a href=Image.image.html#paste>paste</a></tt>, + <tt><a href=Image.image.html#paste_alpha>paste_alpha</a></tt>, + <tt><a href=Image.image.html#paste_alpha_color>paste_alpha_color</a></tt>, + <tt><a href=Image.image.html#paste_mask>paste_mask</a></tt> + +<p> getting subimages, scaling, rotating: <tt><a href=Image.image.html#autocrop>autocrop</a></tt>, + <tt><a href=Image.image.html#clone>clone</a></tt>, + <tt><a href=Image.image.html#copy>copy</a></tt>, + <tt><a href=Image.image.html#dct>dct</a></tt>, + <tt><a href=Image.image.html#mirrorx>mirrorx</a></tt>, + <tt><a href=Image.image.html#rotate>rotate</a></tt>, + <tt><a href=Image.image.html#rotate_expand>rotate_expand</a></tt>, + <tt><a href=Image.image.html#rotate_ccw>rotate_ccw</a></tt>, + <tt><a href=Image.image.html#rotate_cw>rotate_cw</a></tt>, + <tt><a href=Image.image.html#scale>scale</a></tt>, + <tt><a href=Image.image.html#skewx>skewx</a></tt>, + <tt><a href=Image.image.html#skewx_expand>skewx_expand</a></tt>, + <tt><a href=Image.image.html#skewy>skewy</a></tt>, + <tt><a href=Image.image.html#skewy_expand>skewy_expand</a></tt> + +<p> calculation by pixels: <tt><a href=Image.image.html#apply_matrix>apply_matrix</a></tt>, + <tt><a href=Image.image.html#change_color>change_color</a></tt>, + <tt><a href=Image.image.html#color>color</a></tt>, + <tt><a href=Image.image.html#distancesq>distancesq</a></tt>, + <tt><a href=Image.image.html#grey>grey</a></tt>, + <tt><a href=Image.image.html#invert>invert</a></tt>, + <tt><a href=Image.image.html#map_closest>map_closest</a></tt>, + <tt><a href=Image.image.html#map_fast>map_fast</a></tt>, + <tt><a href=Image.image.html#select_colors>select_colors</a></tt>, + <tt><a href=Image.image.html#modify_by_intensity>modify_by_intensity</a></tt>, + <tt><a href=Image.image.html#select_from>select_from</a></tt>, + <tt><a href=Image.image.html#rgb_to_hsv>rgb_to_hsv</a></tt>, + <tt><a href=Image.image.html#hsv_to_rgb>hsv_to_rgb</a></tt> + +<p> converting to other datatypes: <tt><a href=Image.image.html#cast>cast</a></tt>, + <tt><a href=Image.image.html#fromgif>fromgif</a></tt>, + <tt><a href=Image.image.html#frompnm>frompnm</a></tt>/<tt><a href=Image.image.html#fromppm>fromppm</a></tt>, + <tt><a href=Image.image.html#gif_add>gif_add</a></tt>, + <tt><a href=Image.image.html#gif_add_fs>gif_add_fs</a></tt>, + <tt><a href=Image.image.html#gif_add_fs_nomap>gif_add_fs_nomap</a></tt>, + <tt><a href=Image.image.html#gif_add_nomap>gif_add_nomap</a></tt>, + <tt><a href=Image.image.html#gif_begin>gif_begin</a></tt>, + <tt><a href=Image.image.html#gif_end>gif_end</a></tt>, + <tt><a href=Image.image.html#gif_netscape_loop>gif_netscape_loop</a></tt>, + <tt><a href=Image.image.html#gif_transparency>gif_transparency</a></tt>, + <tt><a href=Image.image.html#to8bit>to8bit</a></tt>, + <tt><a href=Image.image.html#to8bit_closest>to8bit_closest</a></tt>, + <tt><a href=Image.image.html#to8bit_fs>to8bit_fs</a></tt>, + <tt><a href=Image.image.html#to8bit_rgbcube>to8bit_rgbcube</a></tt>, + <tt><a href=Image.image.html#to8bit_rgbcube_rdither>to8bit_rgbcube_rdither</a></tt>, + <tt><a href=Image.image.html#tobitmap>tobitmap</a></tt>, + <tt><a href=Image.image.html#togif>togif</a></tt>, + <tt><a href=Image.image.html#togif_fs>togif_fs</a></tt>, + <tt><a href=Image.image.html#toppm>toppm</a></tt>, + <tt><a href=Image.image.html#tozbgr>tozbgr</a></tt> <p> special pattern drawing: - <tt><a href=Image.html>noise</a></tt>, - <tt><a href=Image.html>turbulence</a></tt> + <tt><a href=Image.image.html#noise>noise</a></tt>, + <tt><a href=Image.image.html#turbulence>turbulence</a></tt> </blockquote> <h4>SEE ALSO</h4> <blockquote> <tt><a href=Image.html>Image</a></tt>, - <tt><a href=Image.html>Image.font</a></tt> + <tt><a href=Image.font.html>Image.font</a></tt> </blockquote> <hr> @@ -131,11 +131,11 @@ the new image object <h4>SEE ALSO</h4> -<blockquote> <tt><a href=Image.html>`-</a></tt>, - <tt><a href=Image.html>`+</a></tt>, - <tt><a href=Image.html>`|</a></tt>, - <tt><a href=Image.html>`*</a></tt>, - <tt><a href=Image.html>add_layers</a></tt> +<blockquote> <tt><a href=Image.image.html#%60->`-</a></tt>, + <tt><a href=Image.image.html#%60+>`+</a></tt>, + <tt><a href=Image.image.html#%60|>`|</a></tt>, + <tt><a href=Image.image.html#%60*>`*</a></tt>, + <tt><a href=Image.image.html#add_layers>add_layers</a></tt> </blockquote> <hr> @@ -178,11 +178,11 @@ the new image object <h4>SEE ALSO</h4> -<blockquote> <tt><a href=Image.html>`-</a></tt>, - <tt><a href=Image.html>`+</a></tt>, - <tt><a href=Image.html>`|</a></tt>, - <tt><a href=Image.html>`&</a></tt>, - <tt><a href=Image.html>add_layers</a></tt> +<blockquote> <tt><a href=Image.image.html#%60->`-</a></tt>, + <tt><a href=Image.image.html#%60+>`+</a></tt>, + <tt><a href=Image.image.html#%60|>`|</a></tt>, + <tt><a href=Image.image.html#%60%26>`&</a></tt>, + <tt><a href=Image.image.html#add_layers>add_layers</a></tt> </blockquote> <hr> @@ -219,11 +219,11 @@ the new image object <h4>SEE ALSO</h4> -<blockquote> <tt><a href=Image.html>`-</a></tt>, - <tt><a href=Image.html>`|</a></tt>, - <tt><a href=Image.html>`&</a></tt>, - <tt><a href=Image.html>`*</a></tt>, - <tt><a href=Image.html>add_layers</a></tt> +<blockquote> <tt><a href=Image.image.html#%60->`-</a></tt>, + <tt><a href=Image.image.html#%60|>`|</a></tt>, + <tt><a href=Image.image.html#%60%26>`&</a></tt>, + <tt><a href=Image.image.html#%60*>`*</a></tt>, + <tt><a href=Image.image.html#add_layers>add_layers</a></tt> </blockquote> <hr> @@ -261,11 +261,11 @@ the new image object <h4>SEE ALSO</h4> -<blockquote> <tt><a href=Image.html>`+</a></tt>, - <tt><a href=Image.html>`|</a></tt>, - <tt><a href=Image.html>`&</a></tt>, - <tt><a href=Image.html>`*</a></tt>, - <tt><a href=Image.html>add_layers</a></tt> +<blockquote> <tt><a href=Image.image.html#%60+>`+</a></tt>, + <tt><a href=Image.image.html#%60|>`|</a></tt>, + <tt><a href=Image.image.html#%60%26>`&</a></tt>, + <tt><a href=Image.image.html#%60*>`*</a></tt>, + <tt><a href=Image.image.html#add_layers>add_layers</a></tt> </blockquote> <hr> @@ -303,11 +303,11 @@ the new image object <h4>SEE ALSO</h4> -<blockquote> <tt><a href=Image.html>`-</a></tt>, - <tt><a href=Image.html>`+</a></tt>, - <tt><a href=Image.html>`&</a></tt>, - <tt><a href=Image.html>`*</a></tt>, - <tt><a href=Image.html>add_layers</a></tt> +<blockquote> <tt><a href=Image.image.html#%60->`-</a></tt>, + <tt><a href=Image.image.html#%60+>`+</a></tt>, + <tt><a href=Image.image.html#%60%26>`&</a></tt>, + <tt><a href=Image.image.html#%60*>`*</a></tt>, + <tt><a href=Image.image.html#add_layers>add_layers</a></tt> </blockquote> <hr> @@ -372,14 +372,14 @@ a new image object <h4>SEE ALSO</h4> -<blockquote> <tt><a href=Image.html>paste_mask</a></tt>, - <tt><a href=Image.html>paste_alpha</a></tt>, - <tt><a href=Image.html>paste_alpha_color</a></tt>, - <tt><a href=Image.html>`|</a></tt>, - <tt><a href=Image.html>`&</a></tt>, - <tt><a href=Image.html>`*</a></tt>, - <tt><a href=Image.html>`+</a></tt>, - <tt><a href=Image.html>`-</a></tt> +<blockquote> <tt><a href=Image.image.html#paste_mask>paste_mask</a></tt>, + <tt><a href=Image.image.html#paste_alpha>paste_alpha</a></tt>, + <tt><a href=Image.image.html#paste_alpha_color>paste_alpha_color</a></tt>, + <tt><a href=Image.image.html#%60|>`|</a></tt>, + <tt><a href=Image.image.html#%60%26>`&</a></tt>, + <tt><a href=Image.image.html#%60*>`*</a></tt>, + <tt><a href=Image.image.html#%60+>`+</a></tt>, + <tt><a href=Image.image.html#%60->`-</a></tt> </blockquote> <hr> @@ -454,7 +454,7 @@ Applies a pixel-transform matrix, or filter, to the image. </td> <p> <tr><td rowspan=2> - emboss (might prefer to begin with a <tt><a href=Image.html>grey</a></tt> image): + emboss (might prefer to begin with a <tt><a href=Image.image.html#grey>grey</a></tt> image): <pre> ({({2, 1, 0}), ({1, 0,-1}), @@ -536,7 +536,7 @@ the new image object <h4>SEE ALSO</h4> -<blockquote> <tt><a href=Image.html>copy</a></tt> +<blockquote> <tt><a href=Image.image.html#copy>copy</a></tt> </blockquote> <hr> @@ -612,12 +612,12 @@ always casts to string... <h4>SEE ALSO</h4> -<blockquote> <tt><a href=Image.html>to8bit_rgbcube</a></tt>, - <tt><a href=Image.html>tozbgr</a></tt>, - <tt><a href=Image.html>map_fast</a></tt>, - <tt><a href=Image.html>map_closest</a></tt>, - <tt><a href=Image.html>select_colors</a></tt>, - <tt><a href=Image.html>tobitmap</a></tt> +<blockquote> <tt><a href=Image.image.html#to8bit_rgbcube>to8bit_rgbcube</a></tt>, + <tt><a href=Image.image.html#tozbgr>tozbgr</a></tt>, + <tt><a href=Image.image.html#map_fast>map_fast</a></tt>, + <tt><a href=Image.image.html#map_closest>map_closest</a></tt>, + <tt><a href=Image.image.html#select_colors>select_colors</a></tt>, + <tt><a href=Image.image.html#tobitmap>tobitmap</a></tt> </blockquote> <hr> @@ -633,8 +633,8 @@ object <b>change_color</b>(int fromr, int fromg, int fromb,   <blockquote> Changes one color (exakt match) to another. - If non-exakt-match is preferred, check <tt><a href=Image.html>distancesq</a></tt> - and <tt><a href=Image.html>paste_alpha_color</a></tt>. + If non-exakt-match is preferred, check <tt><a href=Image.image.html#distancesq>distancesq</a></tt> + and <tt><a href=Image.image.html#paste_alpha_color>paste_alpha_color</a></tt>. </blockquote> <h4>ARGUMENTS</h4> <blockquote><dl> @@ -718,8 +718,8 @@ gives a new, cleared image with the same size of drawing area <h4>SEE ALSO</h4> -<blockquote> <tt><a href=Image.html>copy</a></tt>, - <tt><a href=Image.html>clone</a></tt> +<blockquote> <tt><a href=Image.image.html#copy>copy</a></tt>, + <tt><a href=Image.image.html#clone>clone</a></tt> </blockquote> <hr> @@ -763,8 +763,8 @@ the new object <h4>SEE ALSO</h4> -<blockquote> <tt><a href=Image.html>copy</a></tt>, - <tt><a href=Image.html>create</a></tt> +<blockquote> <tt><a href=Image.image.html#copy>copy</a></tt>, + <tt><a href=Image.image.html#create>create</a></tt> </blockquote> <hr> @@ -815,9 +815,9 @@ the new image object <h4>SEE ALSO</h4> -<blockquote> <tt><a href=Image.html>grey</a></tt>, - <tt><a href=Image.html>`*</a></tt>, - <tt><a href=Image.html>modify_by_intensity</a></tt> +<blockquote> <tt><a href=Image.image.html#grey>grey</a></tt>, + <tt><a href=Image.image.html#%60*>`*</a></tt>, + <tt><a href=Image.image.html#modify_by_intensity>modify_by_intensity</a></tt> </blockquote> <hr> @@ -862,14 +862,14 @@ a new image object <h4>NOTE</h4> <blockquote> -<tt><a href=Image.html>clone</a></tt>(void) and <tt><a href=Image.html>copy</a></tt>(void) does the same +<tt><a href=Image.image.html#clone>clone</a></tt>(void) and <tt><a href=Image.image.html#copy>copy</a></tt>(void) does the same operation </blockquote> <h4>SEE ALSO</h4> -<blockquote> <tt><a href=Image.html>clone</a></tt>, - <tt><a href=Image.html>autocrop</a></tt> +<blockquote> <tt><a href=Image.image.html#clone>clone</a></tt>, + <tt><a href=Image.image.html#autocrop>autocrop</a></tt> </blockquote> <hr> @@ -912,9 +912,9 @@ SIGSEGS can be caused if the size is too big, due <h4>SEE ALSO</h4> -<blockquote> <tt><a href=Image.html>copy</a></tt>, - <tt><a href=Image.html>clone</a></tt>, - <tt><a href=Image.html>Image.image</a></tt> +<blockquote> <tt><a href=Image.image.html#copy>copy</a></tt>, + <tt><a href=Image.image.html#clone>clone</a></tt>, + <tt><a href=Image.image.html>Image.image</a></tt> </blockquote> <hr> @@ -1015,7 +1015,7 @@ the new image object <h4>SEE ALSO</h4> -<blockquote> <tt><a href=Image.html>select_from</a></tt> +<blockquote> <tt><a href=Image.image.html#select_from>select_from</a></tt> </blockquote> <hr> @@ -1054,8 +1054,8 @@ yes, it does -- it may even do segment overrides... <h4>SEE ALSO</h4> -<blockquote> <tt><a href=Image.html>togif</a></tt>, - <tt><a href=Image.html>frompnm</a></tt> +<blockquote> <tt><a href=Image.image.html#togif>togif</a></tt>, + <tt><a href=Image.image.html#frompnm>frompnm</a></tt> </blockquote> <hr> @@ -1073,7 +1073,7 @@ object|string <b>fromppm</b>(string pnm)</tt> <blockquote> <b>compability method</b> - do not use in new programs. - See <tt><a href=Image.PNM.html#decode>Image.PNM.decode</a></tt>(). + See <tt><a href=Image.PNM.decode.html>Image.PNM.decode</a></tt>(). </blockquote> <h4>ARGUMENTS</h4> <blockquote><dl> @@ -1201,10 +1201,10 @@ I (Mirar) recommend reading about the GIF file format before <h4>SEE ALSO</h4> -<blockquote> <tt><a href=Image.html>gif_add</a></tt>, - <tt><a href=Image.html>gif_end</a></tt>, - <tt><a href=Image.html>gif_netscape_loop</a></tt>, - <tt><a href=Image.html>togif */</a></tt> +<blockquote> <tt><a href=Image.image.html#gif_add>gif_add</a></tt>, + <tt><a href=Image.image.html#gif_end>gif_end</a></tt>, + <tt><a href=Image.image.html#gif_netscape_loop>gif_netscape_loop</a></tt>, + <tt><a href=Image.image.html#togif */>togif */</a></tt> </blockquote> <hr> @@ -1239,10 +1239,10 @@ the GIF data <h4>SEE ALSO</h4> -<blockquote> <tt><a href=Image.html>gif_add</a></tt>, - <tt><a href=Image.html>gif_end</a></tt>, - <tt><a href=Image.html>togif</a></tt>, - <tt><a href=Image.html>gif_netscape_loop</a></tt> +<blockquote> <tt><a href=Image.image.html#gif_add>gif_add</a></tt>, + <tt><a href=Image.image.html#gif_end>gif_end</a></tt>, + <tt><a href=Image.image.html#togif>togif</a></tt>, + <tt><a href=Image.image.html#gif_netscape_loop>gif_netscape_loop</a></tt> </blockquote> <hr> @@ -1267,7 +1267,7 @@ the GIF data. <h4>SEE ALSO</h4> -<blockquote> <tt><a href=Image.html>gif_begin</a></tt> +<blockquote> <tt><a href=Image.image.html#gif_begin>gif_begin</a></tt> </blockquote> <hr> @@ -1292,9 +1292,9 @@ a gif chunk that defines that the GIF animation should loop <h4>SEE ALSO</h4> -<blockquote> <tt><a href=Image.html>gif_add</a></tt>, - <tt><a href=Image.html>gif_begin</a></tt>, - <tt><a href=Image.html>gif_end</a></tt> +<blockquote> <tt><a href=Image.image.html#gif_add>gif_add</a></tt>, + <tt><a href=Image.image.html#gif_begin>gif_begin</a></tt>, + <tt><a href=Image.image.html#gif_end>gif_end</a></tt> </blockquote> <hr> @@ -1325,9 +1325,9 @@ Yes - i know this function is too hard to use. :/ <h4>SEE ALSO</h4> -<blockquote> <tt><a href=Image.html>gif_add</a></tt>, - <tt><a href=Image.html>gif_begin</a></tt>, - <tt><a href=Image.html>gif_end</a></tt> +<blockquote> <tt><a href=Image.image.html#gif_add>gif_add</a></tt>, + <tt><a href=Image.image.html#gif_begin>gif_begin</a></tt>, + <tt><a href=Image.image.html#gif_end>gif_end</a></tt> </blockquote> <hr> @@ -1372,9 +1372,9 @@ the new image object <h4>SEE ALSO</h4> -<blockquote> <tt><a href=Image.html>color</a></tt>, - <tt><a href=Image.html>`*</a></tt>, - <tt><a href=Image.html>modify_by_intensity</a></tt> +<blockquote> <tt><a href=Image.image.html#color>color</a></tt>, + <tt><a href=Image.image.html#%60*>`*</a></tt>, + <tt><a href=Image.image.html#modify_by_intensity>modify_by_intensity</a></tt> </blockquote> <hr> @@ -1553,15 +1553,15 @@ the new image object <h4>NOTE</h4> <blockquote> -this function may change slightly when <tt><a href=Image.html>Image::colortable</a></tt> +this function may change slightly when <tt><a href=Image.image.html#colortable>Image.image->colortable</a></tt> is implemented (pike 0.6, probably) </blockquote> <h4>SEE ALSO</h4> -<blockquote> <tt><a href=Image.html>map_fast</a></tt>, - <tt><a href=Image.html>select_colors</a></tt>, - <tt><a href=Image.html>map_fs</a></tt> +<blockquote> <tt><a href=Image.image.html#map_fast>map_fast</a></tt>, + <tt><a href=Image.image.html#select_colors>select_colors</a></tt>, + <tt><a href=Image.image.html#map_fs>map_fs</a></tt> </blockquote> <hr> @@ -1598,14 +1598,14 @@ the new image object <h4>NOTE</h4> <blockquote> -this function may change slightly when <tt><a href=Image.html>Image::colortable</a></tt> +this function may change slightly when <tt><a href=Image.image.html#colortable>Image.image->colortable</a></tt> is implemented (pike 0.6, probably) </blockquote> <h4>SEE ALSO</h4> -<blockquote> <tt><a href=Image.html>map_fast</a></tt>, - <tt><a href=Image.html>select_colors</a></tt> +<blockquote> <tt><a href=Image.image.html#map_fast>map_fast</a></tt>, + <tt><a href=Image.image.html#select_colors>select_colors</a></tt> </blockquote> <hr> @@ -1651,15 +1651,15 @@ the new image object <h4>NOTE</h4> <blockquote> -this function may change slightly when <tt><a href=Image.html>Image::colortable</a></tt> +this function may change slightly when <tt><a href=Image.image.html#colortable>Image.image->colortable</a></tt> is implemented (pike 0.6, probably) </blockquote> <h4>SEE ALSO</h4> -<blockquote> <tt><a href=Image.html>map_fast</a></tt>, - <tt><a href=Image.html>select_colors</a></tt>, - <tt><a href=Image.html>map_closest</a></tt> +<blockquote> <tt><a href=Image.image.html#map_fast>map_fast</a></tt>, + <tt><a href=Image.image.html#select_colors>select_colors</a></tt>, + <tt><a href=Image.image.html#map_closest>map_closest</a></tt> </blockquote> <hr> @@ -1724,7 +1724,7 @@ mirrors an image: Recolor an image from intensity values. <p> For each color an intensity is calculated, from r, g and b factors - (see <tt><a href=Image.html>grey</a></tt>), this gives a value between 0 and max. + (see <tt><a href=Image.image.html#grey>grey</a></tt>), this gives a value between 0 and max. <p> The color is then calculated from the values given, v1 representing the intensity value of 0, vn representing max, and colors between @@ -1757,9 +1757,9 @@ the new image object <h4>SEE ALSO</h4> -<blockquote> <tt><a href=Image.html>grey</a></tt>, - <tt><a href=Image.html>`*</a></tt>, - <tt><a href=Image.html>color</a></tt> +<blockquote> <tt><a href=Image.image.html#grey>grey</a></tt>, + <tt><a href=Image.image.html#%60*>`*</a></tt>, + <tt><a href=Image.image.html#color>color</a></tt> </blockquote> <hr> @@ -1798,7 +1798,7 @@ Gives a new image with the old image's size, <h4>SEE ALSO</h4> -<blockquote> <tt><a href=Image.html>turbulence</a></tt> +<blockquote> <tt><a href=Image.image.html#turbulence>turbulence</a></tt> </blockquote> <hr> @@ -1832,9 +1832,9 @@ the object called <h4>SEE ALSO</h4> -<blockquote> <tt><a href=Image.html>paste_mask</a></tt>, - <tt><a href=Image.html>paste_alpha</a></tt>, - <tt><a href=Image.html>paste_alpha_color</a></tt> +<blockquote> <tt><a href=Image.image.html#paste_mask>paste_mask</a></tt>, + <tt><a href=Image.image.html#paste_alpha>paste_alpha</a></tt>, + <tt><a href=Image.image.html#paste_alpha_color>paste_alpha_color</a></tt> </blockquote> <hr> @@ -1875,9 +1875,9 @@ the object called <h4>SEE ALSO</h4> -<blockquote> <tt><a href=Image.html>paste_mask</a></tt>, - <tt><a href=Image.html>paste</a></tt>, - <tt><a href=Image.html>paste_alpha_color</a></tt> +<blockquote> <tt><a href=Image.image.html#paste_mask>paste_mask</a></tt>, + <tt><a href=Image.image.html#paste>paste</a></tt>, + <tt><a href=Image.image.html#paste_alpha_color>paste_alpha_color</a></tt> </blockquote> <hr> @@ -1924,9 +1924,9 @@ the object called <h4>SEE ALSO</h4> -<blockquote> <tt><a href=Image.html>paste_mask</a></tt>, - <tt><a href=Image.html>paste_alpha</a></tt>, - <tt><a href=Image.html>paste_alpha_color</a></tt> +<blockquote> <tt><a href=Image.image.html#paste_mask>paste_mask</a></tt>, + <tt><a href=Image.image.html#paste_alpha>paste_alpha</a></tt>, + <tt><a href=Image.image.html#paste_alpha_color>paste_alpha_color</a></tt> </blockquote> <hr> @@ -1968,9 +1968,9 @@ the object called <h4>SEE ALSO</h4> -<blockquote> <tt><a href=Image.html>paste</a></tt>, - <tt><a href=Image.html>paste_alpha</a></tt>, - <tt><a href=Image.html>paste_alpha_color</a></tt> +<blockquote> <tt><a href=Image.image.html#paste>paste</a></tt>, + <tt><a href=Image.image.html#paste_alpha>paste_alpha</a></tt>, + <tt><a href=Image.image.html#paste_alpha_color>paste_alpha_color</a></tt> </blockquote> <hr> @@ -2010,8 +2010,8 @@ This function is new (april-97) and rather untested. <h4>SEE ALSO</h4> -<blockquote> <tt><a href=Image.html>box</a></tt>, - <tt><a href=Image.html>setcolor</a></tt> +<blockquote> <tt><a href=Image.image.html#box>box</a></tt>, + <tt><a href=Image.image.html#setcolor>setcolor</a></tt> </blockquote> <hr> @@ -2082,7 +2082,7 @@ Rotates an image a certain amount of degrees (360 image border pixels rather then filling with the given or current color. -<p> This rotate uses the <tt><a href=Image.html>skewx</a></tt>() and <tt><a href=Image.html>skewy</a></tt>() functions. +<p> This rotate uses the <tt><a href=Image.image.html#skewx>skewx</a></tt>() and <tt><a href=Image.image.html#skewy>skewy</a></tt>() functions. </blockquote> <h4>ARGUMENTS</h4> <blockquote><dl> @@ -2258,14 +2258,14 @@ an array of colors <h4>NOTE</h4> <blockquote> -this function may change somewhat when <tt><a href=Image.html>Image::colortable</a></tt> +this function may change somewhat when <tt><a href=Image.image.html#colortable>Image.image->colortable</a></tt> is implemented (pike 0.6, probably) </blockquote> <h4>SEE ALSO</h4> -<blockquote> <tt><a href=Image.html>map_fast</a></tt>, - <tt><a href=Image.html>select_colors</a></tt> +<blockquote> <tt><a href=Image.image.html#map_fast>map_fast</a></tt>, + <tt><a href=Image.image.html#select_colors>select_colors</a></tt> </blockquote> <hr> @@ -2287,7 +2287,7 @@ Makes an grey-scale image, for alpha-channel use. The image is scanned from the given pixel, filled with 255 if the color is the same, or 255 minus distance in the colorcube, squared, rightshifted - 8 steps (see <tt><a href=Image.html>distancesq</a></tt>). + 8 steps (see <tt><a href=Image.image.html#distancesq>distancesq</a></tt>). <p> When the edge distance is reached, the scan is stopped. Default edge value is 30. @@ -2309,7 +2309,7 @@ the new image object <h4>SEE ALSO</h4> -<blockquote> <tt><a href=Image.html>distancesq</a></tt> +<blockquote> <tt><a href=Image.image.html#distancesq>distancesq</a></tt> </blockquote> <hr> @@ -2524,7 +2524,7 @@ the new image object <h4>SEE ALSO</h4> -<blockquote> <tt><a href=Image.html>grey</a></tt> +<blockquote> <tt><a href=Image.image.html#grey>grey</a></tt> </blockquote> <hr> @@ -2573,9 +2573,9 @@ the calculated string <h4>SEE ALSO</h4> -<blockquote> <tt><a href=Image.html>tozbgr</a></tt>, - <tt><a href=Image.html>to8bit</a></tt>, - <tt><a href=Image.html>tobitmap</a></tt> +<blockquote> <tt><a href=Image.image.html#tozbgr>tozbgr</a></tt>, + <tt><a href=Image.image.html#to8bit>to8bit</a></tt>, + <tt><a href=Image.image.html#tobitmap>tobitmap</a></tt> </blockquote> <hr> @@ -2605,10 +2605,10 @@ the calculated string <h4>SEE ALSO</h4> -<blockquote> <tt><a href=Image.html>tozbgr</a></tt>, - <tt><a href=Image.html>to8bit</a></tt>, - <tt><a href=Image.html>to8bit_rgbcube</a></tt>, - <tt><a href=Image.html>cast</a></tt> +<blockquote> <tt><a href=Image.image.html#tozbgr>tozbgr</a></tt>, + <tt><a href=Image.image.html#to8bit>to8bit</a></tt>, + <tt><a href=Image.image.html#to8bit_rgbcube>to8bit_rgbcube</a></tt>, + <tt><a href=Image.image.html#cast>cast</a></tt> </blockquote> <hr> @@ -2657,11 +2657,11 @@ the GIF data <h4>SEE ALSO</h4> -<blockquote> <tt><a href=Image.html>gif_begin</a></tt>, - <tt><a href=Image.html>gif_add</a></tt>, - <tt><a href=Image.html>gif_end</a></tt>, - <tt><a href=Image.html>toppm</a></tt>, - <tt><a href=Image.html>fromgif</a></tt> +<blockquote> <tt><a href=Image.image.html#gif_begin>gif_begin</a></tt>, + <tt><a href=Image.image.html#gif_add>gif_add</a></tt>, + <tt><a href=Image.image.html#gif_end>gif_end</a></tt>, + <tt><a href=Image.image.html#toppm>toppm</a></tt>, + <tt><a href=Image.image.html#fromgif>fromgif</a></tt> </blockquote> <hr> @@ -2677,7 +2677,7 @@ the GIF data <blockquote> <b>compability method</b> - do not use in new programs. - See <tt><a href=Image.PNM.html#encode>Image.PNM.encode</a></tt>(). + See <tt><a href=Image.PNM.encode.html>Image.PNM.encode</a></tt>(). </blockquote> <h4>RETURNS</h4> @@ -2777,7 +2777,7 @@ gives a new image with the old image's size, <h4>SEE ALSO</h4> -<blockquote> <tt><a href=Image.html>noise</a></tt> +<blockquote> <tt><a href=Image.image.html#noise>noise</a></tt> </blockquote> <hr> diff --git a/src/modules/Image/encodings/gif.c b/src/modules/Image/encodings/gif.c index 4517f7b6f388a12366d34c897e9e35f04a0a1ae2..eeb30fd2703880bdd298e0035e20db365dac94f3 100644 --- a/src/modules/Image/encodings/gif.c +++ b/src/modules/Image/encodings/gif.c @@ -1,9 +1,9 @@ -/* $Id: gif.c,v 1.12 1997/11/06 21:12:50 mirar Exp $ */ +/* $Id: gif.c,v 1.13 1997/11/07 06:06:20 mirar Exp $ */ /* **! module Image **! note -**! $Id: gif.c,v 1.12 1997/11/06 21:12:50 mirar Exp $ +**! $Id: gif.c,v 1.13 1997/11/07 06:06:20 mirar Exp $ **! submodule GIF **! **! This submodule keep the GIF encode/decode capabilities @@ -31,7 +31,7 @@ #include "stralloc.h" #include "global.h" -RCSID("$Id: gif.c,v 1.12 1997/11/06 21:12:50 mirar Exp $"); +RCSID("$Id: gif.c,v 1.13 1997/11/07 06:06:20 mirar Exp $"); #include "pike_macros.h" #include "object.h" #include "constants.h" @@ -83,6 +83,30 @@ string _encode(array data); */ +#if 0 +#include <sys/resource.h> +#define CHRONO(X) chrono(X); + +static void chrono(char *x) +{ + struct rusage r; + static struct rusage rold; + getrusage(RUSAGE_SELF,&r); + fprintf(stderr,"%s: %ld.%06ld - %ld.%06ld\n",x, + (long)r.ru_utime.tv_sec,(long)r.ru_utime.tv_usec, + + (long)(((r.ru_utime.tv_usec-rold.ru_utime.tv_usec<0)?-1:0) + +r.ru_utime.tv_sec-rold.ru_utime.tv_sec), + (long)(((r.ru_utime.tv_usec-rold.ru_utime.tv_usec<0)?1000000:0) + + r.ru_utime.tv_usec-rold.ru_utime.tv_usec) + ); + + rold=r; +} +#else +#define CHRONO(X) +#endif + /* **! method string header_block(int xsize,int ysize,int numcolors); **! method string header_block(int xsize,int ysize,object colortable); @@ -376,6 +400,8 @@ static void image_gif__render_block(INT32 args) int i; int numstrings=0; +CHRONO("gif _render_block begun"); + if (args<8) error("Image.GIF._render_block(): Too few arguments\n"); @@ -478,6 +504,8 @@ static void image_gif__render_block(INT32 args) if (lzw.broken) error("out of memory\n"); +CHRONO("gif _render_block push of packed data begin"); + for (i=0;;) if (lzw.outpos-i>=255) { @@ -504,6 +532,8 @@ static void image_gif__render_block(INT32 args) break; } +CHRONO("gif _render_block push of packed data end"); + image_gif_lzw_free(&lzw); /*** done */ @@ -514,6 +544,8 @@ static void image_gif__render_block(INT32 args) pop_n_elems(args+1); push_string(ps); + +CHRONO("gif _render_block end"); } /* @@ -613,6 +645,8 @@ void image_gif_render_block(INT32 args) int bpp; struct pike_string *ps; +CHRONO("gif render_block begin"); + if (args<2) error("Image.GIF.render_block(): Too few arguments\n"); if (sp[-args].type!=T_OBJECT || @@ -753,8 +787,10 @@ void image_gif_render_block(INT32 args) } ps=begin_shared_string(img->xsize*img->ysize); +CHRONO("render_block index begin"); image_colortable_index_8bit_image(nct,img->img,(unsigned char *)ps->str, img->xsize*img->ysize,img->xsize); +CHRONO("render_block index end"); if (alpha) { @@ -780,6 +816,7 @@ void image_gif_render_block(INT32 args) push_string(ps); if (localpalette) { +CHRONO("gif render_block write local colortable begin"); ps=begin_shared_string((1<<bpp)*3); image_colortable_write_rgb(nct,(unsigned char *)ps->str); MEMSET(ps->str+(numcolors+alphaentry)*3,0,((1<<bpp)-numcolors)*3); @@ -790,12 +827,15 @@ void image_gif_render_block(INT32 args) ps->str[3*alphaidx+2]=alphacolor.b; } push_string(end_shared_string(ps)); +CHRONO("gif render_block write local colortable end"); } else push_int(0); push_int(interlace); +CHRONO("gif render_block _render_block begin"); image_gif__render_block(8); +CHRONO("gif render_block _render_block end"); numstrings++; @@ -807,6 +847,8 @@ void image_gif_render_block(INT32 args) pop_n_elems(args+1); push_string(ps); + +CHRONO("gif render_block end"); } /* @@ -900,6 +942,7 @@ static void _image_gif_encode(INT32 args,int fs) image_program))) error("Image.GIF.encode(): Illegal argument 1 (expected image object)\n"); imgobj->refs++; + if (args>=2) if (sp[1-args].type==T_INT) diff --git a/src/modules/Image/image.c b/src/modules/Image/image.c index c3dd3c56558b5b7cc1ed6ab5135a9ca8834e7736..7e62c5f4e251b2d8142b1121cf8460aa1cd6cfa9 100644 --- a/src/modules/Image/image.c +++ b/src/modules/Image/image.c @@ -1,9 +1,9 @@ -/* $Id: image.c,v 1.51 1997/11/05 03:41:35 mirar Exp $ */ +/* $Id: image.c,v 1.52 1997/11/07 06:06:10 mirar Exp $ */ /* **! module Image **! note -**! $Id: image.c,v 1.51 1997/11/05 03:41:35 mirar Exp $ +**! $Id: image.c,v 1.52 1997/11/07 06:06:10 mirar Exp $ **! class image **! **! The main object of the <ref>Image</ref> module, this object @@ -66,27 +66,9 @@ **! <ref>rgb_to_hsv</ref>, **! <ref>hsv_to_rgb</ref> **! -**! converting to other datatypes: <ref>cast</ref>, -**! <ref>fromgif</ref>, -**! <ref>frompnm</ref>/<ref>fromppm</ref>, -**! <ref>gif_add</ref>, -**! <ref>gif_add_fs</ref>, -**! <ref>gif_add_fs_nomap</ref>, -**! <ref>gif_add_nomap</ref>, -**! <ref>gif_begin</ref>, -**! <ref>gif_end</ref>, -**! <ref>gif_netscape_loop</ref>, -**! <ref>gif_transparency</ref>, -**! <ref>to8bit</ref>, -**! <ref>to8bit_closest</ref>, -**! <ref>to8bit_fs</ref>, -**! <ref>to8bit_rgbcube</ref>, -**! <ref>to8bit_rgbcube_rdither</ref>, -**! <ref>tobitmap</ref>, -**! <ref>togif</ref>, -**! <ref>togif_fs</ref>, -**! <ref>toppm</ref>, -**! <ref>tozbgr</ref> +**! converting to other datatypes: +**! <ref>Image.GIF</ref>, +**! <ref>Image.PNG</ref> **! **! special pattern drawing: **! <ref>noise</ref>, @@ -102,7 +84,7 @@ #include "stralloc.h" #include "global.h" -RCSID("$Id: image.c,v 1.51 1997/11/05 03:41:35 mirar Exp $"); +RCSID("$Id: image.c,v 1.52 1997/11/07 06:06:10 mirar Exp $"); #include "pike_macros.h" #include "object.h" #include "constants.h" @@ -117,7 +99,7 @@ RCSID("$Id: image.c,v 1.51 1997/11/05 03:41:35 mirar Exp $"); #include "builtin_functions.h" struct program *image_program; -extern struct program *colortable_program; +extern struct program *image_colortable_program; #define THIS ((struct image *)(fp->current_storage)) #define THISOBJ (fp->current_object) @@ -2346,7 +2328,7 @@ CHRONO("apply_matrix, end"); void image_modify_by_intensity(INT32 args) { - INT32 x,y,i; + INT32 x,y; rgbl_group rgb; rgb_group *list; rgb_group *s,*d; @@ -2441,236 +2423,44 @@ void image_modify_by_intensity(INT32 args) /* **! method object map_closest(array(array(int)) colors) -**! Maps all pixel colors to the colors given. -**! -**! Method to find the correct color is linear search -**! over the colors given, selecting the nearest in the -**! color cube. Slow... -**! -**! <table><tr valign=center> -**! <td><illustration> return lena(); </illustration></td> -**! <td><illustration> return lena()->map_closest(({({255,0,0}),({255,255,255}),({0,0,0})})); </illustration></td> -**! </tr><tr valign=center> -**! <td>original</td> -**! <td>->map_closest(({({255,0,0}),({255,255,255}),({0,0,0})}));</td> -**! </tr></table> -**! -**! returns the new image object -**! -**! arg array(array(int)) color -**! list of destination (available) colors -**! -**! note -**! this function may change slightly when <ref>Image.image->colortable</ref> -**! is implemented (pike 0.6, probably) -**! -**! see also: map_fast, select_colors, map_fs -*/ - - -static void image_map_closest(INT32 args) -{ - struct colortable *ct; - long i; - rgb_group *d,*s; - struct object *o; - - if (!THIS->img) error("no image\n"); - if (args<1 - || sp[-args].type!=T_ARRAY) - error("illegal argument to Image.image->map_closest()\n"); - - push_int(THIS->xsize); - push_int(THIS->ysize); - o=clone_object(image_program,2); - - ct=colortable_from_array(sp[-args].u.array,"Image.image->map_closest()\n"); - pop_n_elems(args); - - i=THIS->xsize*THIS->ysize; - s=THIS->img; - d=((struct image*)(o->storage))->img; - THREADS_ALLOW(); - while (i--) - { - *d=ct->clut[colortable_rgb_nearest(ct,*s)]; - d++; s++; - } - THREADS_DISALLOW(); - - colortable_free(ct); - push_object(o); -} - -/* **! method object map_fast(array(array(int)) colors) -**! Maps all pixel colors to the colors given. -**! -**! Method to find the correct color is to branch -**! in a binary space partitioning tree in the -**! colorcube. This is fast, but in some cases -**! it gives the wrong color (mostly when few colors -**! are available). -**! -**! returns the new image object -**! -**! arg array(array(int)) color -**! list of destination (available) colors -**! -**! note -**! this function may change slightly when <ref>Image.image->colortable</ref> -**! is implemented (pike 0.6, probably) -**! -**! see also: map_fast, select_colors -*/ - -static void image_map_fast(INT32 args) -{ - struct colortable *ct; - long i; - rgb_group *d,*s; - struct object *o; - - if (!THIS->img) error("no image\n"); - if (args<1 - || sp[-args].type!=T_ARRAY) - error("illegal argument to Image.image->map_closest()\n"); - - push_int(THIS->xsize); - push_int(THIS->ysize); - o=clone_object(image_program,2); - - ct=colortable_from_array(sp[-args].u.array,"Image.image->map_closest()\n"); - pop_n_elems(args); - - i=THIS->xsize*THIS->ysize; - s=THIS->img; - d=((struct image*)(o->storage))->img; - THREADS_ALLOW(); - while (i--) - { - *d=ct->clut[colortable_rgb(ct,*s)]; - d++; s++; - } - THREADS_DISALLOW(); - - colortable_free(ct); - push_object(o); -} - -/* **! method object map_fs(array(array(int)) colors) -**! Maps all pixel colors to the colors given. -**! -**! Method to find the correct color is linear search -**! over the colors given, selecting the nearest in the -**! color cube. Slow... -**! -**! Floyd-steinberg error correction is added to create -**! a better-looking image, in many cases, anyway. -**! -**! <table><tr valign=center> -**! <td><illustration> return lena(); </illustration></td> -**! <td><illustration> return lena()->map_fs(({({255,0,0}),({255,255,255}),({0,0,0})})); </illustration></td> -**! </tr><tr valign=center> -**! <td>original</td> -**! <td>->map_fs(({({255,0,0}),({255,255,255}),({0,0,0})}));</td> -**! </tr></table> -**! -**! returns the new image object -**! -**! arg array(array(int)) color -**! list of destination (available) colors -**! -**! note -**! this function may change slightly when <ref>Image.image->colortable</ref> -**! is implemented (pike 0.6, probably) -**! -**! see also: map_fast, select_colors, map_closest +**! method array select_colors(int num) +**! Compatibility functions. Do not use! */ -static void image_map_fs(INT32 args) +void image_map_compat(INT32 args) /* compat function */ { - struct colortable *ct; - INT32 i,j,xs; - rgb_group *d,*s; - struct object *o; - int *res,w; - rgbl_group *errb; + struct neo_colortable *nct; + struct object *o,*co; + struct pike_string *res = begin_shared_string((THIS->xsize*THIS->ysize)); + rgb_group *d; - if (!THIS->img) error("no image\n"); - if (args<1 - || sp[-args].type!=T_ARRAY) - error("illegal argument to Image.image->map_fs()\n"); + if(!res) error("Out of memory\n"); - push_int(THIS->xsize); - push_int(THIS->ysize); - o=clone_object(image_program,2); - - res=(int*)xalloc(sizeof(int)*THIS->xsize); - errb=(rgbl_group*)xalloc(sizeof(rgbl_group)*THIS->xsize); + co=clone_object(image_colortable_program,args); + nct=(struct neo_colortable*)get_storage(co,image_colortable_program); + + push_int(THIS->xsize); + push_int(THIS->ysize); + o=clone_object(image_program,2); - ct=colortable_from_array(sp[-args].u.array,"Image.image->map_closest()\n"); - pop_n_elems(args); + d=((struct image*)(o->storage))->img; - for (i=0; i<THIS->xsize; i++) - errb[i].r=(rand()%(FS_SCALE*2+1))-FS_SCALE, - errb[i].g=(rand()%(FS_SCALE*2+1))-FS_SCALE, - errb[i].b=(rand()%(FS_SCALE*2+1))-FS_SCALE; + THREADS_ALLOW(); - i=THIS->ysize; - s=THIS->img; - d=((struct image*)(o->storage))->img; - w=0; - xs=THIS->xsize; - THREADS_ALLOW(); - while (i--) - { - image_floyd_steinberg(s,xs,errb,w=!w,res,ct,1); - for (j=0; j<xs; j++) - *(d++)=ct->clut[res[j]]; - s+=xs; - } - THREADS_DISALLOW(); + image_colortable_map_image(nct,THIS->img,d, + THIS->xsize*THIS->ysize,THIS->xsize); - free(errb); - free(res); - colortable_free(ct); - push_object(o); -} + THREADS_DISALLOW(); -/* -**! method array(array(int)) select_colors(int num_colors) -**! Selects the best colors to represent the image. -**! -**! returns an array of colors -**! -**! <table><tr valign=center> -**! <td><illustration> return lena(); </illustration></td> -**! <td><illustration> return lena()->map_closest(lena()->select_colors(2)); </illustration></td> -**! <td><illustration> return lena()->map_closest(lena()->select_colors(8)); </illustration></td> -**! <td><illustration> return lena()->map_closest(lena()->select_colors(32)); </illustration></td> -**! </tr><tr valign=center> -**! <td>original</td> -**! <td>2</td> -**! <td>8</td> -**! <td>32</td> -**! </tr></table> -**! -**! arg int num_colors -**! number of colors to return -**! -**! note -**! this function may change somewhat when <ref>Image.image->colortable</ref> -**! is implemented (pike 0.6, probably) -**! -**! see also: map_fast, select_colors -*/ + free_object(o); + push_object(co); +} void image_select_colors(INT32 args) { - struct colortable *ct; - int colors,i; + int colors; if (args<1 || sp[-args].type!=T_INT) @@ -2678,18 +2468,11 @@ void image_select_colors(INT32 args) colors=sp[-args].u.integer; pop_n_elems(args); - if (!THIS->img) { error("no image\n"); return; } - ct=colortable_quant(THIS,colors); - for (i=0; i<colors; i++) - { - push_int(ct->clut[i].r); - push_int(ct->clut[i].g); - push_int(ct->clut[i].b); - f_aggregate(3); - } - f_aggregate(colors); - colortable_free(ct); + push_object(THISOBJ); THISOBJ->refs++; + push_int(colors); + + push_object(clone_object(image_colortable_program,2)); } /* @@ -2891,8 +2674,6 @@ void pike_module_init(void) "function(string:object|string)",0); add_function("fromppm",image_frompnm, "function(string:object|string)",0); - add_function("fromgif",image_fromgif, - "function(string:object)",0); add_function("togif",image_togif, "function(:string)",0); add_function("togif_fs",image_togif_fs, @@ -2915,9 +2696,9 @@ void pike_module_init(void) add_function("cast",image_cast, "function(string:string)",0); add_function("to8bit",image_to8bit, "function(array(array(int)):string)",0); - add_function("to8bit_closest",image_to8bit_closest, + add_function("to8bit_closest",image_to8bit, "function(array(array(int)):string)",0); - add_function("to8bit_fs",image_to8bit_fs, + add_function("to8bit_fs",image_to8bit, "function(:string)",0); add_function("torgb",image_torgb, "function(:string)",0); @@ -3024,11 +2805,11 @@ void pike_module_init(void) add_function("ysize",image_ysize, "function(:int)",0); - add_function("map_closest",image_map_closest, + add_function("map_closest",image_map_compat, "function(array(array(int)):object)",0); - add_function("map_fast",image_map_fast, + add_function("map_fast",image_map_compat, "function(array(array(int)):object)",0); - add_function("map_fs",image_map_fs, + add_function("map_fs",image_map_compat, "function(array(array(int)):object)",0); add_function("select_colors",image_select_colors, "function(int:array(array(int)))",0); diff --git a/src/modules/Image/image.h b/src/modules/Image/image.h index dcb3ccedb766f94decc1b154e9bfe2a765f57570..8dfb07c6205b327f11fe23773d8518fc9a6cec50 100644 --- a/src/modules/Image/image.h +++ b/src/modules/Image/image.h @@ -1,9 +1,9 @@ -/* $Id: image.h,v 1.10 1997/10/27 22:41:22 mirar Exp $ */ +/* $Id: image.h,v 1.11 1997/11/07 06:06:12 mirar Exp $ */ /* **! module Image **! note -**! $Id: image.h,v 1.10 1997/10/27 22:41:22 mirar Exp $ +**! $Id: image.h,v 1.11 1997/11/07 06:06:12 mirar Exp $ */ #define MAX_NUMCOL 32768 @@ -42,51 +42,7 @@ struct image unsigned char alpha; }; -struct colortable -{ - int numcol; - struct rgb_cache - { - rgb_group index; - int value; - } cache[QUANT_SELECT_CACHE]; - unsigned long *rgb_node; /* numcol*2 entries */ -/* bit - 31..30 29..22 21..0 - 0=color split value - 1=split red on this - 2=split green =x <=x >x - 3=split blue value value+1 - It will fail for more than 2097152 colors. Sorry... *grin* - */ - unsigned short *index; /* numcol entries */ - rgb_group clut[1]; -}; - - -/* colortable declarations - from quant */ - -struct colortable *colortable_quant(struct image *img,int numcol); -int colortable_rgb(struct colortable *ct,rgb_group rgb); -int colortable_rgb_nearest(struct colortable *ct,rgb_group rgb); -void colortable_free(struct colortable *ct); -struct colortable *colortable_from_array(struct array *arr,char *from); - -/* encoding of a gif - from togif */ - -struct pike_string * - image_encode_gif(struct image *img,struct colortable *ct, - rgb_group *transparent, - int floyd_steinberg, - int closest); -void image_floyd_steinberg(rgb_group *rgb,int xsize, - rgbl_group *errl, - int way,int *res, - struct colortable *ct, - int closest); - -int image_decode_gif(struct image *dest,struct image *dest_alpha, - unsigned char *src,unsigned long len); +/* COMPAT: encoding of a gif - from togif */ void image_togif(INT32 args); void image_togif_fs(INT32 args); diff --git a/src/modules/Image/lzw.c b/src/modules/Image/lzw.c index d7f85c10f65c5ec9e0caa43e2eddb8fbdfb70a4a..df67eae388128a7ce06582895753895161abf13a 100644 --- a/src/modules/Image/lzw.c +++ b/src/modules/Image/lzw.c @@ -1,384 +1,3 @@ -/* $Id: lzw.c,v 1.6 1997/11/02 18:48:33 grubba Exp $ */ - -/* - -lzw, used by togif - -Pontus Hagland, law@infovav.se - -this file can be used generally for lzw algoritms, -the existanse of #define GIF_LZW is for that purpose. :-) -/Pontus - -*/ - -/* -**! module Image -**! note -**! $Id: lzw.c,v 1.6 1997/11/02 18:48:33 grubba Exp $ -*/ - -#include "global.h" - -#include "threads.h" - -#include "lzw.h" - -#define DEFAULT_OUTBYTES 16384 -#ifndef GIF_LZW -#define STDLZWCODES 8192 -#endif - -static INLINE void lzw_output(struct lzw *lzw,lzwcode_t codeno) -{ - int bits,bitp; - unsigned char c; - - HIDE_GLOBAL_VARIABLES(); -/* - fprintf(stderr,"%03x bits=%d codes %d %c\n", - codeno,lzw->codebits,lzw->codes+1, - (codeno==lzw->codes+1) ? '=' : ' '); - */ -#if 0 - fprintf(stderr,"\nwrote %4d<'",codeno); - lzw_recurse_find_code(lzw,codeno); - fprintf(stderr,"' "); -#endif - - if (lzw->outpos+4>=lzw->outlen) - lzw->out=realloc(lzw->out,lzw->outlen*=2); - - bitp=lzw->outbit; - c=lzw->lastout; - bits=lzw->codebits; -#ifdef GIF_LZW - if (bits>12) bits=12; -#endif - - while (bits) - { - c|=(codeno<<bitp); - if (bits+bitp>=8) - { - bits-=8-bitp; - codeno>>=8-bitp; - bitp=0; - lzw->out[lzw->outpos++]=c; - c=0; - } - else - { - lzw->outbit=bitp+bits; - lzw->lastout=c; - return; - } - } - lzw->lastout=0; - lzw->outbit=0; - REVEAL_GLOBAL_VARIABLES(); -} - - -void lzw_init(struct lzw *lzw,int bits) -{ - unsigned long i; - HIDE_GLOBAL_VARIABLES(); -#ifdef GIF_LZW - lzw->codes=(1L<<bits)+2; -#else - lzw->codes=(1L<<bits); -#endif - lzw->bits=bits; - lzw->codebits=bits+1; - lzw->code=(struct lzwc*) malloc(sizeof(struct lzwc)* -#ifdef GIF_LZW - 4096 -#else - (lzw->alloced=STDLZWCODES) -#endif - ); - - for (i=0; i<lzw->codes; i++) - { - lzw->code[i].c=(unsigned char)i; - lzw->code[i].firstchild=LZWCNULL; - lzw->code[i].next=LZWCNULL; - } - lzw->out=malloc(DEFAULT_OUTBYTES); - lzw->outlen=DEFAULT_OUTBYTES; - lzw->outpos=0; - lzw->current=LZWCNULL; - lzw->outbit=0; - lzw->lastout=0; -#ifdef GIF_LZW - lzw_output(lzw,1L<<bits); -#endif - REVEAL_GLOBAL_VARIABLES(); -} - -void lzw_quit(struct lzw *lzw) -{ - int i; - - free(lzw->code); - free(lzw->out); -} - -#if 0 -static void lzw_recurse_find_code(struct lzw *lzw,lzwcode_t codeno) -{ - lzwcode_t i; - if (codeno<(1L<<lzw->bits)) - fprintf(stderr,"%c",codeno); - else if (codeno==(1L<<lzw->bits)) - fprintf(stderr,"(clear)"); - else if (codeno==(1L<<lzw->bits)+1) - fprintf(stderr,"(end)"); - else for (;;) - { - /* direct child? */ - for (i=0; i<lzw->codes; i++) - if (lzw->code[i].firstchild==codeno) - { - lzw_recurse_find_code(lzw,i); - fprintf(stderr,"%c",lzw->code[codeno].c); - return; - } - for (i=0; i<lzw->codes; i++) - if (lzw->code[i].next==codeno) codeno=i; - } -} -#endif - -void lzw_write_last(struct lzw *lzw) -{ - HIDE_GLOBAL_VARIABLES(); - if (lzw->current) - lzw_output(lzw,lzw->current); -#ifdef GIF_LZW - lzw_output( lzw, (1L<<lzw->bits)+1 ); /* GIF end code */ -#endif - if (lzw->outbit) - lzw->out[lzw->outpos++]=lzw->lastout; - REVEAL_GLOBAL_VARIABLES(); -} - -void lzw_add(struct lzw *lzw,int c) -{ - lzwcode_t lno,lno2; - struct lzwc *l; - HIDE_GLOBAL_VARIABLES(); - - if (lzw->current==LZWCNULL) /* no current, load */ - { - lzw->current=c; - return; - } - - lno=lzw->code[lzw->current].firstchild; /* check if we have this sequence */ - while (lno!=LZWCNULL) - { - if (lzw->code[lno].c==c && lno!=lzw->codes-1 ) - { - lzw->current=lno; - return; - } - lno=lzw->code[lno].next; - } - - -#ifdef GIF_LZW - if (lzw->codes==4096) /* needs more than 12 bits */ - { - int i; - - lzw_output(lzw,lzw->current); - - for (i=0; i<(1L<<lzw->bits); i++) - lzw->code[i].firstchild=LZWCNULL; - lzw->codes=(1L<<lzw->bits)+2; - - /* output clearcode, 1000... (bits) */ - lzw_output(lzw,1L<<lzw->bits); - - lzw->codebits=lzw->bits+1; - lzw->current=c; - return; - } -#else - if (lzw->codes==MAXLZWCODES) - realloc lzwc->code... move lzw->current -#endif - - /* output current code no, make new & reset */ - - lzw_output(lzw,lzw->current); - - lno=lzw->code[lzw->current].firstchild; - lno2=lzw->codes; - l=lzw->code+lno2; - l->next=lno; - l->firstchild=LZWCNULL; - l->c=c; - lzw->code[lzw->current].firstchild=lno2; - - lzw->codes++; - if (lzw->codes>(unsigned long)(1L<<lzw->codebits)) lzw->codebits++; - - lzw->current=c; - REVEAL_GLOBAL_VARIABLES(); -} - -#undef UNPACK_DEBUG - -#ifdef GIF_LZW -unsigned long lzw_unpack(unsigned char *dest,unsigned long destlen, - unsigned char *src,unsigned long srclen, - int bits) -{ - struct lzwuc - { - unsigned char c; - lzwcode_t parent; - lzwcode_t len; /* no string is longer then that ... */ - } *code; - - static unsigned short mask[16]={0,1,3,7,017,037,077,0177,0377,0777,01777, - 03777,07777,01777,03777,07777}; - - unsigned long wrote=0; - int i,cbits,cbit,clear=(1<<bits),end=(1<<bits)+1; - lzwcode_t current,last,used,nextlast; - unsigned long store; - unsigned char *srcend=src+srclen,*destend=dest+destlen; - unsigned char first=0; - - code=malloc(sizeof(struct lzwuc)*4096); - if (!code) return 0; - - for (i=0; i<(1<<bits); i++) - { - code[i].c=i; - code[i].parent=LZWCNULL; - code[i].len=1; - } - - cbit=0; - cbits=bits+1; - store=0; - last=LZWCNULL; - used=end+1; - - while (src!=srcend) - { - if (cbit>cbits) - { - current=store>>(32-cbits); - cbit-=cbits; - } - else - { - while (cbits-cbit>=8) - { - store=(store>>8)|((*(src++))<<24); - cbit+=8; - if (src==srcend) { free(code); return wrote; } - } - store=(store>>8)|((*(src++))<<24); - cbit+=8; - current=(store>>(32-(cbit)))&mask[cbits]; - cbit-=cbits; - } - -#ifdef UNPACK_DEBUG - fprintf(stderr,"%03x ",current); -#endif - - if (current==clear) /* clear tree */ - { - for (i=0; i<end-2; i++) - code[i].parent=LZWCNULL; - last=LZWCNULL; - used=end+1; - if (cbits!=bits+1) - { - cbits=bits+1; - cbit++; - } - } - else if (current==end) /* end of data */ - break; - else if (last==LZWCNULL) - { - last=current; - if ((int)last>end) break; - *(dest++)=(unsigned char)current; - wrote++; - first=current; - } - else - { - lzwcode_t n; - unsigned char *dest2; - - if (code[current].len+dest>destend) /* no space, cancel */ - break; - - nextlast=current; - - if (current>=used) - { - *(dest++)=(unsigned char)first; - wrote++; - current=last; - } - - dest+=code[current].len; - wrote+=code[current].len; - - dest2=dest; - n=current; - *--dest2=code[n].c; - while ((int)n>end) - { - n=code[n].parent; - *--dest2=code[n].c; - } - - -/* - *dest=0; - fprintf(stderr,"read %4d>'",current); - for (i=0; i<code[current].len; i++) - fprintf(stderr,"%c",(dest-code[current].len)[i]); - fprintf(stderr,"' == "); - for (i=0; i<code[current].len; i++) - fprintf(stderr,"%02x",(dest-code[current].len)[i]); - fprintf(stderr,"\n"); -*/ - - if (used<4096) - { - code[used].c=code[n].c; - code[used].parent=last; - code[used].len=code[last].len+1; - used++; - - if (((int)used)>=(1<<cbits)) - { - cbits++; -#ifdef UNPACK_DEBUG - fprintf(stderr,"[%d bits]",cbits); -#endif - } - } - - last=nextlast; - } - } - free(code); - return wrote; -} -#endif +/* $Id: lzw.c,v 1.7 1997/11/07 06:06:13 mirar Exp $ */ +#error This file should not be compiled. Have you run autoconf? diff --git a/src/modules/Image/lzw.h b/src/modules/Image/lzw.h index 33b80197c1a4dee30f132587e6099ecbd68a6cde..a88456ec5d0416c1eb445df29406a808164bc2b9 100644 --- a/src/modules/Image/lzw.h +++ b/src/modules/Image/lzw.h @@ -1,47 +1,3 @@ -/* $Id: lzw.h,v 1.4 1997/10/27 22:41:23 mirar Exp $ */ - -/* -**! module Image -**! note -**! $Id: lzw.h,v 1.4 1997/10/27 22:41:23 mirar Exp $ -*/ - -#define GIF_LZW - -#ifdef GIF_LZW -typedef unsigned short lzwcode_t; /* no more than 12 bits used */ -#else -typedef unsigned long lzwcode_t; -#endif - -struct lzw -{ - unsigned long codes; - unsigned long bits; /* initial encoding bits */ - unsigned long codebits; /* current encoding bits */ - unsigned long outlen,outpos,outbit; - unsigned char *out,lastout; - struct lzwc - { - unsigned char c; - lzwcode_t firstchild; - lzwcode_t next; - } *code; - lzwcode_t current,firstfree; -#ifndef GIF_LZW - unsigned long alloced; -#endif -}; - -#define LZWCNULL ((lzwcode_t)(~0)) - -void lzw_add(struct lzw *lzw,int c); -void lzw_quit(struct lzw *lzw); -void lzw_init(struct lzw *lzw,int bits); -void lzw_write_last(struct lzw *lzw); -unsigned long lzw_unpack(unsigned char *dest,unsigned long destlen, - unsigned char *src,unsigned long srclen, - int bits); - - +/* $Id: lzw.h,v 1.5 1997/11/07 06:06:14 mirar Exp $ */ +#error This file should not be compiled. Have you run autoconf? diff --git a/src/modules/Image/quant.c b/src/modules/Image/quant.c index 0313977d8b92a458eb45954e6879f2bd1bf4b112..8611e89d2f2307e40c1455eca26aa8e37f2deb5e 100644 --- a/src/modules/Image/quant.c +++ b/src/modules/Image/quant.c @@ -1,946 +1,3 @@ -#include <config.h> -/* $Id: quant.c,v 1.14 1997/10/27 22:41:29 mirar Exp $ */ -/* (optimized) color quantization and following lookup */ +/* $Id: quant.c,v 1.15 1997/11/07 06:06:15 mirar Exp $ */ -/* -**! module Image -**! note -**! $Id: quant.c,v 1.14 1997/10/27 22:41:29 mirar Exp $ -*/ - -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif /* HAVE_UNISTD_H */ -#include <stdio.h> - -#ifdef HAVE_STDLIB_H -#include <stdlib.h> -#endif - -#include "error.h" -#include "global.h" -#include "pike_memory.h" -#include "array.h" - -#include "threads.h" - - -#include "image.h" - -/* -#define QUANT_DEBUG_GAP -#define QUANT_DEBUG_POINT -#define QUANT_DEBUG -#define QUANT_DEBUG_RGB -*/ - -#define QUANT_MAXIMUM_NUMBER_OF_COLORS 65535 - -/**********************************************************************/ - -#if 0 -#include <sys/resource.h> -#define CHRONO(X) chrono(X) - -static void chrono(char *x) -{ - struct rusage r; - static struct rusage rold; - getrusage(RUSAGE_SELF,&r); - fprintf(stderr,"%s: %ld.%06ld - %ld.%06ld\n",x, - r.ru_utime.tv_sec,r.ru_utime.tv_usec, - - ((r.ru_utime.tv_usec-rold.ru_utime.tv_usec<0)?-1:0) - +r.ru_utime.tv_sec-rold.ru_utime.tv_sec, - ((r.ru_utime.tv_usec-rold.ru_utime.tv_usec<0)?1000000:0) - + r.ru_utime.tv_usec-rold.ru_utime.tv_usec - ); - - rold=r; -} -#else -#define CHRONO(X) -#endif - -/**********************************************************************/ - -#define SQ(x) ((x)*(x)) -#define DISTANCE(A,B) \ - (SQ(((int)(A).r)-((int)(B).r)) \ - +SQ(((int)(A).g)-((int)(B).g)) \ - +SQ(((int)(A).b)-((int)(B).b))) - - -typedef struct -{ - rgb_group rgb; - unsigned short index; - unsigned long count; - unsigned long next; -} rgb_entry; - -typedef struct -{ - unsigned long len; - rgb_entry tbl[1]; -} rgb_hashtbl; - -#define HASH(rgb,l) \ - ((((int)(rgb).r)*127+((int)(rgb).g)*997+((int)(rgb).b)*2111)&((l)-1)) -#define SAME_COL(rgb1,rgb2) \ - (((rgb1).r==(rgb2).r) && ((rgb1).g==(rgb2).g) && ((rgb1).b==(rgb2).b)) - - -static INLINE int hash_enter(rgb_entry *rgbe,rgb_entry *end, - int len,rgb_group rgb) -{ - register rgb_entry *re; - - re=rgbe+HASH(rgb,len); -/* fprintf(stderr,"%d\n",HASH(rgb,len));*/ - - while (re->count && !SAME_COL(re->rgb,rgb)) - if (++re==end) re=rgbe; - - if (!re->count) /* allocate it */ - { - re->rgb=rgb; - re->count=1; - return 1; - } - - re->count++; - return 0; -} - -static INLINE int hash_enter_strip(rgb_entry *rgbe,rgb_entry *end, - int len,rgb_group rgb,int strip) -{ - register rgb_entry *re; -/* Not using static here is not a very good idea. Initialization of these - * took 75% of the CPU in this function. :-) - */ - /*CONST*/ static unsigned char strip_r[24]= -{ 0xff, 0xfe, 0xfe, 0xfe, 0xfc, 0xfc, 0xfc, 0xf8, 0xf8, 0xf8, - 0xf0, 0xf0, 0xf0, 0xe0, 0xe0, 0xe0, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x80 }; - /*CONST*/ static unsigned char strip_g[24]= -{ 0xff, 0xff, 0xfe, 0xfe, 0xfe, 0xfc, 0xfc, 0xfc, 0xf8, 0xf8, 0xf8, - 0xf0, 0xf0, 0xf0, 0xe0, 0xe0, 0xe0, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x80 }; - /*CONST*/ static unsigned char strip_b[24]= -{ 0xfe, 0xfe, 0xfe, 0xfc, 0xfc, 0xfc, 0xf8, 0xf8, 0xf8, - 0xf0, 0xf0, 0xf0, 0xe0, 0xe0, 0xe0, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x80 }; - - rgb.r&=strip_r[strip]; - rgb.g&=strip_g[strip]; - rgb.b&=strip_b[strip]; - - re=rgbe+HASH(rgb,len); - - while (re->count && !SAME_COL(re->rgb,rgb)) - if (++re==end) re=rgbe; - - if (!re->count) /* allocate it */ - { - re->rgb=rgb; - re->count=1; - return 1; - } - - re->count++; - return 0; -} - -static rgb_hashtbl *img_rehash(rgb_hashtbl *old, unsigned long newsize) -{ - unsigned long i; - rgb_hashtbl *new = malloc(sizeof(rgb_hashtbl) + - sizeof(rgb_entry) * newsize ); - MEMSET(new->tbl, 0, sizeof(rgb_entry) * newsize ); - - if (!new) error("Out of memory\n"); -#ifdef QUANT_DEBUG - fprintf(stderr,"img_rehash: old size = %lu, new size = %lu\n", - (old ? old->len : 0), newsize); -#endif - - new->len = newsize; - if (old) - { - for (i=0;i<old->len;i++) - if (old->tbl[i].count) - { - register rgb_entry *re; - - re=new->tbl+HASH(old->tbl[i].rgb,newsize); - - while (re->count) - if (++re==new->tbl+newsize) re=new->tbl; - - *re=old->tbl[i]; - } - free(old); - } - return new; -} - -static int cmp_red(rgb_entry *e1, rgb_entry *e2) -{ - return e1->rgb.r - e2->rgb.r; -} - -static int cmp_green(rgb_entry *e1, rgb_entry *e2) -{ - return e1->rgb.g - e2->rgb.g; -} - -static int cmp_blue(rgb_entry *e1, rgb_entry *e2) -{ - return e1->rgb.b - e2->rgb.b; -} - -static int get_tbl_median(rgb_entry *tbl,int len) -{ - int a=0,x=0; - rgb_entry *m,*n; - - len--; - m=tbl; n=tbl+len-1; - while (m<n) - { -#if 0 - fprintf(stderr,"pos %3d,%3d sum %3d low=%3d,%3d,%3dc%3d high=%3d,%3d,%3dc%3d\n", - x,len,a, - tbl[x].rgb.r,tbl[x].rgb.g,tbl[x].rgb.b,tbl[x].count, - tbl[len].rgb.r,tbl[len].rgb.g,tbl[len].rgb.b,tbl[len].count); -#endif - if (a>0) a-=m++->count; - else a+=n--->count; - } - return m-tbl; -} - -static rgb_group get_tbl_point(rgb_entry *tbl,int len) -{ - unsigned long r=0,g=0,b=0,n=0; - int x; - rgb_group rgb; - for (x=0; x<len; x++) - { - r+=((unsigned long)tbl[x].rgb.r)*tbl[x].count, - g+=((unsigned long)tbl[x].rgb.g)*tbl[x].count, - b+=((unsigned long)tbl[x].rgb.b)*tbl[x].count; - n+=tbl[x].count; -#ifdef QUANT_DEBUG_POINT - fprintf(stderr,"(%d,%d,%d)*%lu; ", - tbl[x].rgb.r, - tbl[x].rgb.g, - tbl[x].rgb.b, - tbl[x].count); -#endif - } - rgb.r=(unsigned char)(r/n); - rgb.g=(unsigned char)(g/n); - rgb.b=(unsigned char)(b/n); -#ifdef QUANT_DEBUG_POINT - fprintf(stderr,"-> (%lu,%lu,%lu)/%lu = %d,%d,%d\n", - r,g,b,n, - rgb.r,rgb.g,rgb.b); -#endif - return rgb; -} - -#define MAKE_BINSORT(C,NAME) \ - void NAME(rgb_entry *e, unsigned long len) \ - { \ - unsigned long pos[256];\ - unsigned long i,j,k;\ - \ - rgb_entry *e2;\ - e2=(rgb_entry*)xalloc(sizeof(rgb_entry)*len);\ - \ - for (i=0; i<256; i++) pos[i]=~0;\ - \ - for (i=0; i<len; i++)\ - {\ - e[i].next=pos[j=e[i].rgb.C];\ - pos[j]=i;\ - }\ - \ - for (i=j=0; i<256; i++)\ - {\ - k=pos[i];\ - while (k!=(unsigned long)~0)\ - {\ - e2[j++]=e[k];\ - k=e[k].next;\ - }\ - }\ - MEMCPY(e,e2,len*sizeof(rgb_entry));\ - free(e2);\ - } - -MAKE_BINSORT(r,binsort_red) -MAKE_BINSORT(g,binsort_green) -MAKE_BINSORT(b,binsort_blue) - - -static void sort_tbl(rgb_hashtbl *ht, - unsigned long start, unsigned long len, - int level, unsigned long idx, - unsigned long gap, int ldir, - struct colortable *ct, rgb_group lower,rgb_group upper, - unsigned long **rn_next, - unsigned long *rgb_node) -{ - rgb_entry *tbl = ht->tbl; - - int (*sortfun)(const void *, const void *); - unsigned long x,y; - int dir=0; - -#ifdef QUANT_DEBUG - - fprintf(stderr,"%*ssort_tbl: level %d start = %lu " - " len=%lu, idx = %lu, gap = %lu", - level, "", - level, start, len, idx, gap); - fprintf(stderr,"\n%*s%d,%d,%d-%d,%d,%d ",level,"", - lower.r,lower.g,lower.b,upper.r,upper.g,upper.b); - -#endif - - if (len>1) - { - /* check which direction has the most span */ - /* we make it easy for us, only three directions: r,g,b */ - - rgbl_group sum={0,0,0}; - rgb_group mid; - -#define PRIO_RED 2 -#define PRIO_GREEN 4 -#define PRIO_BLUE 1 - -#if 0 - rgb_group min,max; - - max.r=min.r=tbl[start].rgb.r; - max.g=min.g=tbl[start].rgb.g; - max.b=min.b=tbl[start].rgb.b; - - for (x=1; x<len; x++) - { - if (min.r>tbl[start+x].rgb.r) min.r=tbl[start+x].rgb.r; - if (min.g>tbl[start+x].rgb.g) min.g=tbl[start+x].rgb.g; - if (min.b>tbl[start+x].rgb.b) min.b=tbl[start+x].rgb.b; - if (max.r<tbl[start+x].rgb.r) max.r=tbl[start+x].rgb.r; - if (max.g<tbl[start+x].rgb.g) max.g=tbl[start+x].rgb.g; - if (max.b<tbl[start+x].rgb.b) max.b=tbl[start+x].rgb.b; - } -#ifdef QUANT_DEBUG -fprintf(stderr,"space: %d,%d,%d-%d,%d,%d ", - min.r,min.g,min.b, - max.r,max.g,max.b); -#endif - - /* do this weighted, red=2 green=3 blue=1 */ - if ((max.r-min.r)*PRIO_RED>(max.g-min.g)*PRIO_GREEN) /* r>g */ - if ((max.r-min.r)*PRIO_RED>(max.b-min.b)*PRIO_BLUE) /* r>g, r>b */ - dir=0; - else /* r>g, b>r */ - dir=2; - else - if ((max.g-min.g)*PRIO_GREEN>(max.b-min.b)*PRIO_BLUE) /* g>r, g>b */ - dir=1; - else /* g>r, b>g */ - dir=2; -#endif - - for (x=0; x<len; x++) - { - sum.r+=tbl[start+x].rgb.r; - sum.g+=tbl[start+x].rgb.g; - sum.b+=tbl[start+x].rgb.b; - } - mid.r=(unsigned char)(sum.r/len); - mid.g=(unsigned char)(sum.g/len); - mid.b=(unsigned char)(sum.b/len); - - sum.r=sum.g=sum.b=0; - for (x=0; x<len; x++) - { - sum.r+=SQ(tbl[start+x].rgb.r-mid.r); - sum.g+=SQ(tbl[start+x].rgb.g-mid.g); - sum.b+=SQ(tbl[start+x].rgb.b-mid.b); - } - - if (sum.r*PRIO_RED>sum.g*PRIO_GREEN) /* r>g */ - if (sum.r*PRIO_RED>sum.b*PRIO_BLUE) /* r>g, r>b */ - dir=0; - else /* r>g, b>r */ - dir=2; - else - if (sum.g*PRIO_GREEN>sum.b*PRIO_BLUE) /* g>r, g>b */ - dir=1; - else /* g>r, b>g */ - dir=2; - - -#ifdef QUANT_DEBUG - fprintf(stderr," dir=%d ",dir); -#endif - if (dir!=ldir) - switch (dir) - { - case 0: binsort_red(tbl+start,len); break; - case 1: binsort_green(tbl+start,len); break; - case 2: binsort_blue(tbl+start,len); break; - } - -#ifdef QUANT_DEBUG - fprintf(stderr,"low: %d,%d,%d high: %d,%d,%d\n", - tbl[start].rgb.r, - tbl[start].rgb.g, - tbl[start].rgb.b, - tbl[start+len-1].rgb.r, - tbl[start+len-1].rgb.g, - tbl[start+len-1].rgb.b); -#endif - - } - - if (len>1 && gap>1) /* recurse */ - { - unsigned long pos,g1,g2; - rgb_group less,more,rgb; - unsigned char split_on=0; - int i; - - pos=get_tbl_median(tbl+start,len); - - rgb=tbl[start+pos].rgb; - - less=upper; - more=lower; - - switch (dir) - { - case 0: more.r=rgb.r+1; split_on=less.r=rgb.r; - while (pos<len-1 && tbl[start].rgb.r==tbl[start+pos].rgb.r) pos++; - while (pos>0 && tbl[start+len-1].rgb.r==tbl[start+pos].rgb.r) pos--; - break; - case 1: more.g=rgb.g+1; split_on=less.g=rgb.g; - while (pos<len-1 && tbl[start].rgb.g==tbl[start+pos].rgb.g) pos++; - while (pos>0 && tbl[start+len-1].rgb.g==tbl[start+pos].rgb.g) pos--; - break; - case 2: more.b=rgb.b+1; split_on=less.b=rgb.b; - while (pos<len-1 && tbl[start].rgb.b==tbl[start+pos].rgb.b) pos++; - while (pos>0 && tbl[start+len-1].rgb.b==tbl[start+pos].rgb.b) pos--; - break; - } - -#ifdef QUANT_DEBUG - fprintf(stderr, " pos=%lu len=%lu\n",pos,len); -#endif - -#ifdef QUANT_DEBUG_GAP - - fprintf(stderr,"\n left: "); - for (i=0; i<=pos; i++) - fprintf(stderr,"%d,%d,%d; ", - tbl[start+i].rgb.r,tbl[start+i].rgb.g,tbl[start+i].rgb.b); - fprintf(stderr,"\n right: "); - for (; i<len; i++) - fprintf(stderr,"%d,%d,%d; ", - tbl[start+i].rgb.r,tbl[start+i].rgb.g,tbl[start+i].rgb.b); - fprintf(stderr,"\n"); - -#endif - g1=gap>>1; - -#ifdef QUANT_DEBUG_GAP - fprintf(stderr,"gap: %d / %d pos+1=%d len-pos-1=%d gap-g1=%d\n", - g1,gap-g1,pos+1,len-pos-1,gap-g1); -#endif - - if (pos+1<g1) g1=pos+1,g2=gap-g1; - else if (len-pos-1<gap-g1) g2=(len-pos-1),g1=gap-g2; - else g2=gap-g1; - -#ifdef QUANT_DEBUG - fprintf(stderr,"gap: %d / %d ",g1,g2); -#endif - - if (gap>1) - { - /* split tree */ - - *rgb_node = (( (*rn_next)-ct->rgb_node ) | - ( ((unsigned long)split_on) << 22 ) | - ( (dir+1)<<30 )) & 0xffffffff; - rgb_node=*rn_next; - (*rn_next)+=2; - - sort_tbl(ht,start,pos+1, - level+1,idx,g1,dir, - ct,lower,less,rn_next,rgb_node++); - - sort_tbl(ht,start+pos+1,len-pos-1, - level+1,idx+g1,g2,dir, - ct,more,upper,rn_next,rgb_node); - } - else - { - /* this shouldn't occur? /law */ - abort(); - sort_tbl(ht,start,pos+1, - level+1,idx,g1,dir, - ct,lower,less,rn_next,rgb_node); - } - return; - } - else - { - int r,g,b; - if (len>1) - { - ct->clut[idx]=get_tbl_point(tbl+start,len); - ct->index[idx]=tbl[start].index; - } - else - { - ct->clut[idx]=tbl[start].rgb; - ct->index[idx]=tbl[start].index; - } - -#ifdef QUANT_DEBUG - fprintf(stderr,"-> end node [%d,%d,%d] - [%d,%d,%d] => %d,%d,%d\n", - lower.r, lower.g, lower.b, upper.r, upper.g, upper.b, - ct->clut[idx].r,ct->clut[idx].g,ct->clut[idx].b); -#endif - - /* write end node */ - *rgb_node=idx; /* done */ - } -} - -static struct colortable *colortable_allocate(int numcol) -{ - struct colortable *ct; - ct = malloc(sizeof(struct colortable)+ - sizeof(rgb_group)*numcol); - if (!ct) error("Out of memory.\n"); - MEMSET(ct,0,sizeof(struct colortable)+ - sizeof(rgb_group)*numcol); - ct->numcol=numcol; - ct->rgb_node=malloc(sizeof(unsigned long)*numcol*2); - ct->index=malloc(sizeof(unsigned short)*numcol); - MEMSET(ct->rgb_node,0, - sizeof(unsigned long)*numcol*2); - return ct; -} - -struct colortable *colortable_quant(struct image *img,int numcol) -{ - rgb_hashtbl *tbl; - INT32 i,j; - INT32 sz = img->xsize * img->ysize; - rgb_entry entry; - struct colortable *ct=NULL; - rgb_group black,white; - rgb_group *p; - INT32 entries=0; - unsigned long *next_free_rgb_node; - -#ifdef QUANT_DEBUG - fprintf(stderr,"img_quant called\n"); -#endif - CHRONO("quant"); - - if (numcol<2) numcol=2; - - if (numcol>MAX_NUMCOL) numcol=MAX_NUMCOL; - - ct = colortable_allocate(numcol); - -#ifdef QUANT_DEBUG - fprintf(stderr,"Moving colors into hashtable\n"); -#endif - - THREADS_ALLOW(); - for (;;) - { - int strip=0; -rerun: - entries=0; - - - CHRONO("hash init"); - - tbl = img_rehash(NULL, 8192); - - p=img->img; - i=sz; - do - { - register rgb_entry *rgbe,*end; - int len,trig; - -#ifdef QUANT_DEBUG - fprintf(stderr,"hash: %d pixels left...\n",i); -#endif - CHRONO("hash..."); - - len=tbl->len; - trig=(len*2)/10; /* 20% full => rehash bigger */ - end=(rgbe=tbl->tbl)+tbl->len; - - if (!strip) - { - while (i--) - if ( (entries+=hash_enter(rgbe,end,len,*(p++))) > trig ) - { -#ifdef QUANT_DEBUG - fprintf(stderr,"rehash: 20%% = %d / %d...\n",entries,len); -#endif - CHRONO("rehash..."); - if ((len<<2) > QUANT_MAXIMUM_NUMBER_OF_COLORS) - { - strip++; -#ifdef QUANT_DEBUG - fprintf(stderr,"strip: %d\n",strip); -#endif - free(tbl); - goto rerun; - } - tbl=img_rehash(tbl,len<<2); /* multiple size by 4 */ - break; - } - } - else - while (i--) - if ( (entries+=hash_enter_strip(rgbe,end,len,*(p++),strip)) > trig ) - { -#ifdef QUANT_DEBUG - fprintf(stderr,"rehash: 20%% = %d / %d...\n",entries,len); -#endif - CHRONO("rehash..."); - if ((len<<2) > QUANT_MAXIMUM_NUMBER_OF_COLORS) - { - strip++; - free(tbl); - goto rerun; - } - tbl=img_rehash(tbl,len<<2); /* multiple size by 4 */ - break; - } - } - while (i>=0); - break; - } - - /* Compact the hash table */ - CHRONO("compact"); - -#ifdef QUANT_DEBUG - fprintf(stderr,"Compacting\n"); -#endif - i = tbl->len - 1; - j = 0; - while (i > entries) - { - while ((i >= entries) && tbl->tbl[i].count == 0) i--; - while ((j < entries) && tbl->tbl[j].count != 0) j++; - if (j<i) - { - tbl->tbl[j] = tbl->tbl[i]; - tbl->tbl[i].count = 0; - } - } - - white.r=white.g=white.b=255; - black.r=black.g=black.b=0; - -#ifdef QUANT_DEBUG - fprintf(stderr,"%d colors found, sorting and quantizing...\n",j); -#endif - - CHRONO("sort"); - if (j<numcol) ct->numcol=numcol=j; - - next_free_rgb_node=ct->rgb_node+1; - sort_tbl(tbl, 0, j, 0, 0, numcol, -1, ct, black, white, - &next_free_rgb_node,ct->rgb_node); - -#ifdef QUANT_DEBUG - fprintf(stderr,"img_quant done, %d colors selected\n", numcol); -#endif - CHRONO("done"); - - free(tbl); - CHRONO("really done"); - THREADS_DISALLOW(); - return ct; -} - - -struct colortable *colortable_from_array(struct array *arr,char *from) -{ - rgb_hashtbl *tbl; - INT32 i,j; - struct colortable *ct=NULL; - rgb_group black,white; - rgb_group *p; - INT32 entries=0; - struct svalue s,s2; - unsigned long *next_free_rgb_node; - -#ifdef QUANT_DEBUG - fprintf(stderr,"ctfa called\n"); -#endif - CHRONO("ctfa"); - - white.r=white.g=white.b=255; - black.r=black.g=black.b=0; - - tbl=img_rehash(NULL,arr->size); - - s2.type=s.type=T_INT; - for (i=0; i<arr->size; i++) - { - array_index(&s,arr,i); - if (s.type!=T_ARRAY || s.u.array->size<3) - { - free(tbl); - error("Illegal type in colorlist, element %d, %s\n",i,from); - } - array_index(&s2,s.u.array,0); - if (s2.type!=T_INT) tbl->tbl[i].rgb.r=0; else tbl->tbl[i].rgb.r=s2.u.integer; - array_index(&s2,s.u.array,1); - if (s2.type!=T_INT) tbl->tbl[i].rgb.g=0; else tbl->tbl[i].rgb.g=s2.u.integer; - array_index(&s2,s.u.array,2); - if (s2.type!=T_INT) tbl->tbl[i].rgb.b=0; else tbl->tbl[i].rgb.b=s2.u.integer; - tbl->tbl[i].count=1; - tbl->tbl[i].index=i; - } - free_svalue(&s); - free_svalue(&s2); - - ct = colortable_allocate(arr->size); - - THREADS_ALLOW(); - CHRONO("sort"); - next_free_rgb_node=ct->rgb_node+1; - sort_tbl(tbl, 0, arr->size, 0, 0, arr->size, -1, ct, black, white, - &next_free_rgb_node,ct->rgb_node); - -#ifdef QUANT_DEBUG - fprintf(stderr,"img_quant done, %d colors selected\n", arr->size); -#endif - CHRONO("done"); - - free(tbl); - - for (i=0; i<QUANT_SELECT_CACHE; i++) - ct->cache[i].index=white; - j=colortable_rgb(ct,black); /* ^^ dont find it in the cache... */ - for (i=0; i<QUANT_SELECT_CACHE; i++) - ct->cache[i].index=black, - ct->cache[i].value=j; - - CHRONO("really done"); - THREADS_DISALLOW(); - return ct; -} - - -int colortable_rgb(struct colortable *ct,rgb_group rgb) -{ - /* NOTE: - * This code MUST be MT-SAFE! - */ - int i,best; - - if (ct->cache->index.r==rgb.r && - ct->cache->index.g==rgb.g && - ct->cache->index.b==rgb.b) - return ct->cache->value; - -#ifdef QUANT_DEBUG_RGB - fprintf(stderr,"rgb: %d,%d,%d\n",rgb.r,rgb.g,rgb.b); -#endif - -#if QUANT_SELECT_CACHE>1 - for (i=1; i<QUANT_SELECT_CACHE; i++) - if (ct->cache[i].index.r==rgb.r && - ct->cache[i].index.g==rgb.g && - ct->cache[i].index.b==rgb.b) - { - best=ct->cache[i].value; - - MEMMOVE(ct->cache+1,ct->cache, - i*sizeof(struct rgb_cache)); - ct->cache[0].index=rgb; - ct->cache[0].value=best; - -#ifdef QUANT_DEBUG_RGB - fprintf(stderr,"cache: %lu: %d,%d,%d\n",best,ct->clut[best].r,ct->clut[best].g,ct->clut[best].b); -#endif - return best; - } -#endif - - /* find node */ - -#if 1 - - do - { - rgb_group min={0,0,0},max={255,255,255}; - unsigned long *rn; - unsigned char split; - - rn=ct->rgb_node; - - for (;;) - { -#ifdef QUANT_DEBUG_RGB - fprintf(stderr,"-> %d: %c%d %d\n", - rn-ct->rgb_node, - (((*rn)>>30)==0)?'c': - (((*rn)>>30)==1)?'r': - (((*rn)>>30)==2)?'g':'b', - ((*rn)>>22) & 0xff, - ((*rn) & 0x3fffff)); -#endif - - switch ((*rn)>>30) - { - case 0: /* end node */ break; - case 1: /* red */ - split=(unsigned char)( ((*rn)>>22) & 0xff ); - rn=ct->rgb_node+((*rn) & 0x3fffff); - if (rgb.r<=split) max.r=split; - else rn++,min.r=split+1; - continue; - case 2: /* green */ - split=(unsigned char)( ((*rn)>>22) & 0xff ); - rn=ct->rgb_node+((*rn) & 0x3fffff); - if (rgb.g<=split) max.g=split; - else rn++,min.g=split+1; - continue; - case 3: /* blue */ - split=(unsigned char)( ((*rn)>>22) & 0xff ); - rn=ct->rgb_node+((*rn) & 0x3fffff); - if (rgb.b<=split) max.b=split; - else rn++,min.b=split+1; - continue; - } - break; - } - best=*rn; - } - while (0); - -#endif - - /* place in cache */ -#if QUANT_SELECT_CACHE>1 - MEMMOVE(ct->cache+1,ct->cache, - (QUANT_SELECT_CACHE-1)*sizeof(struct rgb_cache)); -#endif - ct->cache[0].index=rgb; - ct->cache[0].value=best; - -#ifdef QUANT_DEBUG_RGB - fprintf(stderr," -> %lu: %d,%d,%d\n",best, - ct->clut[best].r,ct->clut[best].g,ct->clut[best].b); -#endif - return best; -} - -int colortable_rgb_nearest(struct colortable *ct,rgb_group rgb) -{ - /* NOTE: - * This code MUST be MT-SAFE! - */ - int i,best=0,di,di2; - rgb_group *prgb; - - if (ct->cache->index.r==rgb.r && - ct->cache->index.g==rgb.g && - ct->cache->index.b==rgb.b) - return ct->cache->value; - -#ifdef QUANT_DEBUG_RGB - fprintf(stderr,"rgb_n: #%02x%02x%02x; ",rgb.r,rgb.g,rgb.b); -#endif - -#if QUANT_SELECT_CACHE>1 - for (i=1; i<QUANT_SELECT_CACHE; i++) - /* - * Why is index 0 skipped? /grubba - */ - if (ct->cache[i].index.r==rgb.r && - ct->cache[i].index.g==rgb.g && - ct->cache[i].index.b==rgb.b) - { - best=ct->cache[i].value; - - MEMMOVE(ct->cache+1,ct->cache, - i*sizeof(struct rgb_cache)); - ct->cache[0].index=rgb; - ct->cache[0].value=best; - -#ifdef QUANT_DEBUG_RGB - fprintf(stderr,"cache: %lu: %d,%d,%d\n",best,ct->clut[best].r,ct->clut[best].g,ct->clut[best].b); -#endif - return best; - } -#endif - - /* find node */ - - di=1000000L; - for (i=0; i<ct->numcol; i++) - { - prgb=ct->clut+i; - if ((di2=DISTANCE(*prgb,rgb))<di) - { - best=i; - di=di2; -#ifdef QUANT_DEBUG_RGB - fprintf(stderr,"#%02x%02x%02x (%d) (%d), ", - ct->clut[i].r, - ct->clut[i].g, - ct->clut[i].b, - i,di); -#endif - } - } -#ifdef QUANT_DEBUG_RGB - fprintf(stderr,"\n"); -#endif - - /* place in cache */ -#if QUANT_SELECT_CACHE>1 - MEMMOVE(ct->cache+1,ct->cache, - (QUANT_SELECT_CACHE-1)*sizeof(struct rgb_cache)); -#endif - ct->cache[0].index=rgb; - ct->cache[0].value=best; - -#ifdef QUANT_DEBUG_RGB - fprintf(stderr," -> %lu: %d,%d,%d\n",best, - ct->clut[best].r,ct->clut[best].g,ct->clut[best].b); -#endif - return best; -} - -void colortable_free(struct colortable *ct) -{ - int r,g,b; - free((char *)ct->rgb_node); - free((char *)ct->index); - free((char *)ct); -} +#error This file should not be compiled. Have you run autoconf? diff --git a/src/modules/Image/togif.c b/src/modules/Image/togif.c index eb963ddbf57219533c3bcd591f06aed2c6e07a56..5b0d4b91cca0df1028f0e365f7fda396f2f33b25 100644 --- a/src/modules/Image/togif.c +++ b/src/modules/Image/togif.c @@ -2,16 +2,16 @@ togif -Pontus Hagland, law@infovav.se +$Id: togif.c,v 1.22 1997/11/07 06:06:17 mirar Exp $ -$Id: togif.c,v 1.21 1997/10/27 22:41:30 mirar Exp $ +old GIF API compat stuff */ /* **! module Image **! note -**! $Id: togif.c,v 1.21 1997/10/27 22:41:30 mirar Exp $ +**! $Id: togif.c,v 1.22 1997/11/07 06:06:17 mirar Exp $ **! class image */ @@ -34,653 +34,90 @@ $Id: togif.c,v 1.21 1997/10/27 22:41:30 mirar Exp $ #include "operators.h" #include "image.h" -#include "lzw.h" - -#define INITIAL_BUF_LEN 8192 #define THIS ((struct image *)(fp->current_storage)) #define THISOBJ (fp->current_object) -#if 0 -#include <sys/resource.h> -#define CHRONO(X) chrono(X) - -static void chrono(char *x) -{ - struct rusage r; - static struct rusage rold; - getrusage(RUSAGE_SELF,&r); - fprintf(stderr,"%s: %ld.%06ld - %ld.%06ld\n",x, - r.ru_utime.tv_sec,r.ru_utime.tv_usec, - - ((r.ru_utime.tv_usec-rold.ru_utime.tv_usec<0)?-1:0) - +r.ru_utime.tv_sec-rold.ru_utime.tv_sec, - ((r.ru_utime.tv_usec-rold.ru_utime.tv_usec<0)?1000000:0) - + r.ru_utime.tv_usec-rold.ru_utime.tv_usec - ); - - rold=r; -} -#else -#define CHRONO(X) -#endif - - -#define min(a,b) ((a)<(b)?(a):(b)) -#define max(a,b) ((a)<(b)?(b):(a)) -#define testrange(x) max(min((x),255),0) - -static void buf_word( unsigned short w, dynamic_buffer *buf ) -{ - low_my_putchar( w&0xff, buf ); - low_my_putchar( (w>>8)&0xff, buf ); -} - -#define WEIGHT_NEXT(X) (((X)*8)/20) -#define WEIGHT_DOWNNEXT(X) (((X)*3)/20) -#define WEIGHT_DOWN(X) (((X)*3)/20) -#define WEIGHT_DOWNBACK(X) (((X)*0)/20) - -static int floyd_steinberg_add(rgbl_group *errl, - rgbl_group *errlfwd, - rgbl_group *errlback, - rgbl_group *err, - rgb_group rgb, - struct colortable *ct, - int closest) -{ - /* NOTE: - * This code MUST be MT-SAFE! - */ - rgb_group rgb2,rgb3; - rgbl_group cerr; - int c; - rgb2.r=testrange((long)rgb.r+err->r/FS_SCALE); - rgb2.g=testrange((long)rgb.g+err->g/FS_SCALE); - rgb2.b=testrange((long)rgb.b+err->b/FS_SCALE); -#ifdef FS_DEBUG - fprintf(stderr,"%g,%g,%g+%g,%g,%g=%g,%g,%g ", - 1.0*rgb.r, 1.0*rgb.g, 1.0*rgb.b, - err->r*1.0/FS_SCALE, err->g*1.0/FS_SCALE, err->b*1.0/FS_SCALE, - rgb2.r*1.0, rgb2.g*1.0, rgb2.b*1.0); -#endif - if (closest) - c=colortable_rgb_nearest(ct,rgb2); - else - c=colortable_rgb(ct,rgb2); - rgb3=ct->clut[c]; - cerr.r=(long)rgb.r*FS_SCALE-(long)rgb3.r*FS_SCALE+err->r; - cerr.g=(long)rgb.g*FS_SCALE-(long)rgb3.g*FS_SCALE+err->g; - cerr.b=(long)rgb.b*FS_SCALE-(long)rgb3.b*FS_SCALE+err->b; - -#ifdef FS_DEBUG - fprintf(stderr,"got %g,%g,%g err %g,%g,%g ", - 1.0*rgb3.r, - 1.0*rgb3.g, - 1.0*rgb3.b, - 1.0*cerr.r, - 1.0*cerr.g, - 1.0*cerr.b); -#endif - - errl->r+=WEIGHT_DOWN(cerr.r); - errl->g+=WEIGHT_DOWN(cerr.g); - errl->b+=WEIGHT_DOWN(cerr.b); - if (errlback) - { - errlback->r+=WEIGHT_DOWNBACK(cerr.r); - errlback->g+=WEIGHT_DOWNBACK(cerr.g); - errlback->b+=WEIGHT_DOWNBACK(cerr.b); -#ifdef FS_DEBUG - fprintf(stderr,"errlback=>%g ",errlback->g*1.0/FS_SCALE); -#endif - } - if (errlfwd) - { - err->r=WEIGHT_NEXT(cerr.r); - err->g=WEIGHT_NEXT(cerr.g); - err->b=WEIGHT_NEXT(cerr.b); - err->r+=errlfwd->r; - err->g+=errlfwd->g; - err->b+=errlfwd->b; - errlfwd->r=WEIGHT_DOWNNEXT(cerr.r); - errlfwd->g=WEIGHT_DOWNNEXT(cerr.g); - errlfwd->b=WEIGHT_DOWNNEXT(cerr.b); -#ifdef FS_DEBUG - fprintf(stderr,"errlfwd=>%g ",errlfwd->g*1.0/FS_SCALE); -#endif - } -#ifdef FS_DEBUG - fprintf(stderr,"errl=>%g ",errl->g*1.0/FS_SCALE); - fprintf(stderr,"err=>%g\n",err->g*1.0/FS_SCALE); -#endif - return c; -} - -void image_floyd_steinberg(rgb_group *rgb,int xsize, - rgbl_group *errl, - int way,int *res, - struct colortable *ct, - int closest) -{ - rgbl_group err; - int x; - HIDE_GLOBAL_VARIABLES(); - - if (way) - { - err.r=errl[xsize-1].r; - err.g=errl[xsize-1].g; - err.b=errl[xsize-1].b; - for (x=xsize-1; x>=0; x--) - res[x]=floyd_steinberg_add(errl+x, - (x==0)?NULL:errl+x-1, - (x==xsize-1)?NULL:errl+x+1, - &err,rgb[x],ct,closest); - } - else - { - err.r=errl->r; - err.g=errl->g; - err.b=errl->b; - for (x=0; x<xsize; x++) - res[x]=floyd_steinberg_add(errl+x, - (x==xsize-1)?NULL:errl+x+1, - (x==0)?NULL:errl+x-1, - &err,rgb[x],ct,closest); - } - REVEAL_GLOBAL_VARIABLES(); -} - -#define STD_ARENA_SIZE 16384 - -int image_decode_gif(struct image *dest,struct image *dest_alpha, - unsigned char *src,unsigned long len) -{ - unsigned char *arena,*tmpstore,*q; - rgb_group *global_palette,*palette; - rgb_group *rgb; - int bpp; - unsigned long i,j; - INT32 mod; - INT32 leftofs,topofs,width,height; - int interlaced,transparent; - unsigned long arenalen,pos; - - if (src[0]!='G' - ||src[1]!='I' - ||src[2]!='F' - ||len<12) - return 0; /* not a gif, you fool */ - - dest->xsize=src[6]+(src[7]<<8); - dest->ysize=src[8]+(src[9]<<8); - - if (! (arena=malloc(arenalen=STD_ARENA_SIZE)) ) return 0; - - dest->img=malloc(dest->xsize*dest->ysize*sizeof(rgb_group)); - if (!dest->img) { free(arena); return 0; } - /* out of memory (probably illegal size) */ - - bpp=(src[10]&7)+1; - - THREADS_ALLOW(); - if (src[10]&128) - { - global_palette=(rgb_group*)(src+13); - src+=3*(1<<bpp); - len-=3*(1<<bpp); - rgb=dest->img; - i=dest->xsize*dest->ysize; - } - else - global_palette=NULL; - MEMSET(dest->img,0,sizeof(rgb_group)*dest->xsize*dest->ysize); - src+=13; len-=13; - - do - { - switch (*src) - { - case '!': /* function block */ - if (len<7) break; /* no len left */ - if (src[1]==0xf9) - transparent=src[6]; - len-=src[3]+1; - src+=src[3]+1; - continue; - case ',': /* image block(s) */ - if (len<10) len-=10; /* no len left */ - leftofs=src[1]+(src[2]<<8); - topofs=src[3]+(src[4]<<8); - width=src[5]+(src[6]<<8); - height=src[7]+(src[8]<<8); - interlaced=src[9]&64; - - if (src[9]&128) - { - palette=(rgb_group*)(src+10); - src+=((src[9]&7)+1)*3; - } - else - palette=global_palette; - - src+=11; - len-=11; - pos=0; - if (len<3) break; /* no len left */ - bpp=src[-1]; - - while (len>1) - { - if (!(i=*src)) break; /* length of block */ - if (pos+i>arenalen) - { - arena=realloc(arena,arenalen*=2); - if (!arena) return 1; - } - MEMCPY(arena+pos,src+1,min(i,len-1)); - pos+=min(i,len-1); - len-=i+1; - src+=i+1; - } - - if (leftofs+width<=dest->xsize && topofs+height<=dest->ysize) - { - tmpstore=malloc(width*height); - if (!tmpstore) break; - i=lzw_unpack(tmpstore,width*height,arena,pos,bpp); - if (i!=(unsigned long)(width*height)) - MEMSET(tmpstore+i,0,width*height-i); - rgb=dest->img+leftofs+topofs*dest->ysize; - mod=width-dest->xsize; - j=height; - q=tmpstore; - if (palette) - while (j--) - { - i=width; - while (i--) *(rgb++)=palette[*(q++)]; - rgb+=mod; - } - free(tmpstore); - } - - continue; - case ';': - - break; /* file done */ - default: - break; /* unknown, file is ok? */ - } - } - while (0); - THREADS_DISALLOW(); - - if (arena) free(arena); - return 1; /* ok */ -} - - - -/* -**! method object fromgif(string gif) -**! Reads GIF data to the called image object. -**! -**! GIF animation delay or loops are ignored, -**! and the resulting image is the written result. -**! returns the called object -**! arg string pnm -**! pnm data, as a string -**! see also: togif, frompnm -**! bugs -**! yes, it does -- it may even do segment overrides... -*/ - -void image_fromgif(INT32 args) -{ - if (sp[-args].type!=T_STRING) - error("Illegal argument to image->fromgif()\n"); - - if (THIS->img) free(THIS->img); - THIS->img=NULL; - - image_decode_gif(THIS,NULL, - (unsigned char*)sp[-args].u.string->str, - sp[-args].u.string->len); - - pop_n_elems(args); - THISOBJ->refs++; - push_object(THISOBJ); -} - -static INLINE void getrgb(struct image *img, - INT32 args_start,INT32 args,char *name) -{ - INT32 i; - if (args-args_start<3) return; - for (i=0; i<3; i++) - if (sp[-args+i+args_start].type!=T_INT) - error("Illegal r,g,b argument to %s\n",name); - img->rgb.r=(unsigned char)sp[-args+args_start].u.integer; - img->rgb.g=(unsigned char)sp[1-args+args_start].u.integer; - img->rgb.b=(unsigned char)sp[2-args+args_start].u.integer; - if (args-args_start>=4) - if (sp[3-args+args_start].type!=T_INT) - error("Illegal alpha argument to %s\n",name); - else - img->alpha=sp[3-args+args_start].u.integer; - else - img->alpha=0; -} - +extern struct program *image_colortable_program; /* **! method string gif_begin() **! method string gif_begin(int num_colors) **! method string gif_begin(array(array(int)) colors) -**! Makes GIF header. With no argument, there is no -**! global colortable (palette). -**! returns the GIF data +**! method string gif_end() +**! method string gif_netscape_loop(int loops) +**! method string togif() +**! method string togif(int trans_r,int trans_g,int trans_b) +**! method string togif(int num_colors,int trans_r,int trans_g,int trans_b) +**! method string togif(array(array(int)) colors,int trans_r,int trans_g,int trans_b) +**! method string togif_fs() +**! method string togif_fs(int trans_r,int trans_g,int trans_b) +**! method string togif_fs(int num_colors,int trans_r,int trans_g,int trans_b) +**! method string togif_fs(array(array(int)) colors,int trans_r,int trans_g,int trans_b) +**! old GIF API compatibility function. Don't use +**! in any new code. **! -**! arg int num_colors -**! number of colors to quantize to (default is 256) -**! array array(array(int)) colors -**! colors to map to, format is ({({r,g,b}),({r,g,b}),...}). -**! see also: gif_add, gif_end, togif, gif_netscape_loop +**! <table> +**! <tr><td></td><td>is replaced by</td></tr> +**! <tr><td>gif_begin</td><td><ref>Image.GIF.header_block</ref></td></tr> +**! <tr><td>gif_end</td><td><ref>Image.GIF.end_block</ref></td></tr> +**! <tr><td>gif_netscape_loop</td><td><ref>Image.GIF.netscape_loop_block</ref></td></tr> +**! <tr><td>togif</td><td><ref>Image.GIF.encode</ref></td></tr> +**! <tr><td>togif_fs</td><td><ref>Image.GIF.encode</ref>�</td></tr> +**! </table> **! +**! � Use <ref>Image.colortable</ref> to get whatever dithering +**! you want. **! -**! method string gif_end() -**! Ends GIF data. -**! returns the GIF data. -**! see also: gif_begin +**! returns GIF data. */ +extern void image_gif_header_block(INT32 args); +extern void image_gif_end_block(INT32 args); +extern void image_gif_netscape_loop_block(INT32 args); + void image_gif_begin(INT32 args) { - dynamic_buffer buf; - long i; - int colors,bpp; - struct colortable *ct=NULL; - if (args) - if (sp[-args].type==T_INT && sp[-args].u.integer!=0) - ct=colortable_quant(THIS,max(256,min(2,sp[-args].u.integer))); - else if (sp[-args].type==T_ARRAY) - ct=colortable_from_array(sp[-args].u.array,"image->gif_begin()\n"); - - pop_n_elems(args); - - buf.s.str=NULL; - initialize_buf(&buf); - - if (ct) - { - colors=4; bpp=2; - while (colors<ct->numcol) { colors<<=1; bpp++; } - } - else { - colors=256; bpp=8; - } - - low_my_binary_strcat("GIF89a",6,&buf); - buf_word((unsigned short)THIS->xsize,&buf); - buf_word((unsigned short)THIS->ysize,&buf); - low_my_putchar( (char)((0x80*!!ct) | 0x70 | (bpp-1) ), &buf); - /* | global colormap | 3 bits color res | sort | 3 bits bpp */ - /* color res is'nt cared of */ - - low_my_putchar( 0, &buf ); /* background color */ - low_my_putchar( 0, &buf ); /* just zero */ - - if (!!ct) - { - for (i=0; i<ct->numcol; i++) + struct object *o; + if (sp[-args].type==T_INT) { - low_my_putchar(ct->clut[i].r,&buf); - low_my_putchar(ct->clut[i].g,&buf); - low_my_putchar(ct->clut[i].b,&buf); + int i=sp[-args].u.integer; + pop_n_elems(args); + push_int(THIS->xsize); + push_int(THIS->ysize); + THISOBJ->refs++; + push_object(THISOBJ); + push_int(i); + o=clone_object(image_colortable_program,2); } - - for (; i<colors; i++) + else { - low_my_putchar(0,&buf); - low_my_putchar(0,&buf); - low_my_putchar(0,&buf); + o=clone_object(image_colortable_program,args); } + push_int(THIS->xsize); + push_int(THIS->ysize); + push_object(o); + image_gif_header_block(3); + } + else + { + push_int(THIS->xsize); + push_int(THIS->ysize); + push_int(256); + image_gif_header_block(3); } - push_string(low_free_buf(&buf)); } void image_gif_end(INT32 args) { - pop_n_elems(args); - push_string(make_shared_binary_string(";",1)); + image_gif_end_block(args); } -/* -**! method string gif_netscape_loop() -**! method string gif_netscape_loop(int loops) -**! -**! returns a gif chunk that defines that the GIF animation should loop -**! -**! arg int loops -**! number of loops, default is 65535. -**! see also: gif_add, gif_begin, gif_end -*/ - void image_gif_netscape_loop(INT32 args) { - unsigned short loops=0; - char buf[30]; - if (args) - if (sp[-args].type!=T_INT) - error("Illegal argument to image->gif_netscape_loop()\n"); - else - loops=sp[-args].u.integer; - else - loops=65535; - pop_n_elems(args); - - sprintf(buf,"%c%c%cNETSCAPE2.0%c%c%c%c%c", - 33,255,11,3,1,loops&255,(loops>>8)&255,0); - - push_string(make_shared_binary_string(buf,19)); -} - -/* -**! method string gif_transparency(int color) -**! -**! returns a gif chunk that transparent a color in the next image chunk -**! -**! arg int color -**! index of color in the palette -**! note -**! Yes - i know this function is too hard to use. :/ -**! The palette _is_ unknown mostly... -**! see also: gif_add, gif_begin, gif_end -*/ - -void image_gif_transparency(INT32 args) -{ - unsigned short i=0; - char buf[30]; - if (args) - if (sp[-args].type!=T_INT) - error("Illegal argument to image->gif_transparency()\n"); - else - i=sp[-args].u.integer; - else - error("Too few arguments to image->gif_transparency()\n"); - pop_n_elems(args); - - sprintf(buf,"%c%c%c%c%c%c%c%c",33,0xf9,4,1,0,0,i,0); - - push_string(make_shared_binary_string(buf,8)); -} - -static struct colortable *img_gif_add(INT32 args,int fs,int lm) -{ - INT32 x=0,y=0,i; - struct lzw lzw; - int xs, ys; - rgb_group *rgb; - struct colortable *ct=NULL; - dynamic_buffer buf; - int colors,bpp; - int closest=0; - -CHRONO("gif add init"); - - buf.s.str=NULL; - initialize_buf(&buf); - - if (args==0) x=y=0; - else if (args<2 - || sp[-args].type!=T_INT - || sp[1-args].type!=T_INT) - error("Illegal argument(s) to image->gif_add()\n"); - else - { - x=sp[-args].u.integer; - y=sp[1-args].u.integer; - } - - - if (args>2 && sp[2-args].type==T_ARRAY) - { - ct=colortable_from_array(sp[2-args].u.array,"image->gif_add()\n"); - if (ct->numcol<128) closest=1; - } - else if (args>3 && sp[2-args].type==T_INT) - ct=colortable_quant(THIS,max(256,min(2,sp[2-args].u.integer))); - - if (args>2+!!ct) - { - unsigned short delay=0; - if (sp[2+!!ct-args].type==T_INT) - delay=sp[2+!!ct-args].u.integer; - else if (sp[2+!!ct-args].type==T_FLOAT) - delay=(unsigned short)(sp[2+!!ct-args].u.float_number*100); - else - error("Illegal argument %d to image->gif_add()\n",3+!!ct); - - low_my_putchar( '!', &buf ); /* extension block */ - low_my_putchar( 0xf9, &buf ); /* graphics control */ - low_my_putchar( 4, &buf ); /* block size */ - low_my_putchar( 0, &buf ); /* disposal, transparency, blabla */ - buf_word( delay, &buf ); /* delay in centiseconds */ - low_my_putchar( 0, &buf ); /* (transparency index) */ - low_my_putchar( 0, &buf ); /* terminate block */ - } - - if(!ct) - ct=colortable_quant(THIS,256); - - colors=4; bpp=2; - while (colors<ct->numcol) { colors<<=1; bpp++; } - - - low_my_putchar( ',', &buf ); /* image separator */ - - buf_word(x,&buf); /* leftofs */ - buf_word(y,&buf); /* topofs */ - buf_word(THIS->xsize,&buf); /* width */ - buf_word(THIS->ysize,&buf); /* height */ - - low_my_putchar((0x80*lm)|(bpp-1), &buf); - /* not interlaced (interlaced == 0x40) */ - /* local colormap ( == 0x80) */ - /* 8 bpp in map ( == 0x07) */ - - if (lm) - { - for (i=0; i<ct->numcol; i++) - { - low_my_putchar(ct->clut[i].r,&buf); - low_my_putchar(ct->clut[i].g,&buf); - low_my_putchar(ct->clut[i].b,&buf); - } - for (; i<colors; i++) - { - low_my_putchar(0,&buf); - low_my_putchar(0,&buf); - low_my_putchar(0,&buf); - } - } - - low_my_putchar( bpp, &buf ); - - i=THIS->xsize*THIS->ysize; - rgb=THIS->img; - -CHRONO("begin pack"); - xs = THIS->xsize; - ys = THIS->ysize; - - THREADS_ALLOW(); - lzw_init(&lzw,bpp); - THREADS_DISALLOW(); - - if (!fs) - { - THREADS_ALLOW(); - if (closest) - while (i--) lzw_add(&lzw,colortable_rgb_nearest(ct,*(rgb++))); - else - while (i--) lzw_add(&lzw,colortable_rgb(ct,*(rgb++))); - THREADS_DISALLOW(); - } else { - rgbl_group *errb; - int w,*cres,j; - /* NOTE: xalloc() is NOT thread-safe. */ - errb=(rgbl_group*)xalloc(sizeof(rgbl_group)*xs); - cres=(int*)xalloc(sizeof(int)*xs); - THREADS_ALLOW(); - for (i=0; i<xs; i++) - errb[i].r=(rand()%(FS_SCALE*2+1))-FS_SCALE, - errb[i].g=(rand()%(FS_SCALE*2+1))-FS_SCALE, - errb[i].b=(rand()%(FS_SCALE*2+1))-FS_SCALE; - - w=0; - while (ys--) { - image_floyd_steinberg(rgb,xs,errb,w=!w,cres,ct,closest); - for (j=0; j<xs; j++) - lzw_add(&lzw,cres[j]); - rgb+=xs; - } - THREADS_DISALLOW(); - free(cres); - free(errb); - } - - THREADS_ALLOW(); - lzw_write_last(&lzw); - THREADS_DISALLOW(); - -CHRONO("end pack"); - - /* NOTE that the low_my_* functions are NOT thread-safe. - */ - for (i=0; i<(int)lzw.outpos; i+=254) - { - int wr; - if (i+254>(int)lzw.outpos) wr=lzw.outpos-i; - else wr=254; - low_my_putchar( (unsigned char)wr, &buf ); /* bytes in chunk */ - low_my_binary_strcat( (char *) lzw.out+i, wr, &buf ); - } - low_my_putchar( 0, &buf ); /* terminate stream */ - - lzw_quit(&lzw); - -CHRONO("done"); - - pop_n_elems(args); - push_string(low_free_buf(&buf)); - - return ct; + image_gif_netscape_loop_block(args); } /* @@ -715,7 +152,7 @@ CHRONO("done"); **! method string gif_add_fs_nomap(int x,int y,int num_colors,int delay_cs) **! method string gif_add_fs_nomap(int x,int y,int num_colors,float delay_s) **! method string gif_add_fs_nomap(int x,int y,array(array(int)) colors,int delay_cs) -**! method string gif_add_fs_nomap(int x,int y,array(array(int)) colors,float delay_s) +**! method string gif_add_fs_nomap(int x,int y,array(array(int)) colors,float delay_s,rgb_group *transparent) **! Makes a GIF (sub)image data chunk, to be placed **! at the given position. **! @@ -753,36 +190,113 @@ CHRONO("done"); **! colors to map to, format is ({({r,g,b}),({r,g,b}),...}). **! see also: gif_add, gif_end, gif_netscape_loop, togif */ +static void img_gif_add(INT32 args,int fs,int lm, + rgb_group *transparent) +{ + INT32 x=0,y=0; + int delay=0; + struct object *ncto=NULL; + + if (args==0) x=y=0; + else if (args<2 + || sp[-args].type!=T_INT + || sp[1-args].type!=T_INT) + error("Illegal argument(s) to image->gif_add()\n"); + else + { + x=sp[-args].u.integer; + y=sp[1-args].u.integer; + } + + if (args>2 && sp[2-args].type==T_ARRAY) + { + struct svalue *sv=sp+2-args; + push_svalue(sv); + ncto=clone_object(image_colortable_program,2); + } + else if (args>3 && sp[2-args].type==T_INT) + { + INT32 i=sp[2-args].u.integer; + THISOBJ->refs++; + push_object(THISOBJ); + push_int(i); + ncto=clone_object(image_colortable_program,2); + } + + if (args>2+!!ncto) + { + if (sp[2+!!ncto-args].type==T_INT) + delay=sp[2+!!ncto-args].u.integer; + else if (sp[2+!!ncto-args].type==T_FLOAT) + delay=(unsigned short)(sp[2+!!ncto-args].u.float_number*100); + else + error("Illegal argument %d to image->gif_add()\n",3+!!ncto); + } + + if (!ncto) + { + THISOBJ->refs++; + push_object(THISOBJ); + push_int(256); + ncto=clone_object(image_colortable_program,2); + } + + if (fs) image_colortable_internal_floyd_steinberg( + get_storage(ncto,image_colortable_program)); + + pop_n_elems(args); + + THISOBJ->refs++; + push_object(THISOBJ); + push_object(ncto); + push_int(x); + push_int(y); + push_int(lm); + push_int(delay); + + if (transparent) + { + unsigned char trd; + + image_colortable_index_8bit_image(get_storage(ncto, + image_colortable_program), + transparent,&trd,1,1); + + push_int(trd); + + image_gif_render_block(7); + } + else + image_gif_render_block(6); +} + + void image_gif_add(INT32 args) { - colortable_free(img_gif_add(args,0,1)); + img_gif_add(args,0,1,NULL); } void image_gif_add_fs(INT32 args) { - colortable_free(img_gif_add(args,1,1)); + img_gif_add(args,1,1,NULL); } void image_gif_add_nomap(INT32 args) { - colortable_free(img_gif_add(args,0,0)); + img_gif_add(args,0,0,NULL); } void image_gif_add_fs_nomap(INT32 args) { - colortable_free(img_gif_add(args,1,0)); + img_gif_add(args,1,0,NULL); } /* **! method string togif() -**! method string togif(int num_colors) -**! method string togif(array(array(int)) colors) **! method string togif(int trans_r,int trans_g,int trans_b) **! method string togif(int num_colors,int trans_r,int trans_g,int trans_b) **! method string togif(array(array(int)) colors,int trans_r,int trans_g,int trans_b) **! method string togif_fs() -**! method string togif_fs(int num_colors) -**! method string togif_fs(array(array(int)) colors) **! method string togif_fs(int trans_r,int trans_g,int trans_b) **! method string togif_fs(int num_colors,int trans_r,int trans_g,int trans_b) **! method string togif_fs(array(array(int)) colors,int trans_r,int trans_g,int trans_b) @@ -804,7 +318,6 @@ void image_gif_add_fs_nomap(INT32 args) static void img_encode_gif(rgb_group *transparent,int fs,INT32 args) { - struct colortable *ct; struct svalue sv; /* on stack is now: @@ -814,7 +327,7 @@ static void img_encode_gif(rgb_group *transparent,int fs,INT32 args) push_int(0); if (args) { sv=sp[-1]; sp[-1]=sp[-2]; sp[-2]=sv; } push_int(0); if (args) { sv=sp[-1]; sp[-1]=sp[-2]; sp[-2]=sv; } - ct=img_gif_add(args+2,fs,1); + img_gif_add(args+2,fs,1,transparent); image_gif_begin(0); /* on stack is now: @@ -824,23 +337,34 @@ static void img_encode_gif(rgb_group *transparent,int fs,INT32 args) /* swap them... */ sv=sp[-1]; sp[-1]=sp[-2]; sp[-2]=sv; - if (transparent) - { - push_int(colortable_rgb(ct,*transparent)); - image_gif_transparency(1); - sv=sp[-1]; sp[-1]=sp[-2]; sp[-2]=sv; - } - colortable_free(ct); image_gif_end(0); /* on stack is now: - gif beginning - - eventual transparency chunk - - image with local palette + - image with local palette and eventual gce block - gif end chunk */ - f_add(3+!!transparent); -/* f_aggregate(4);*/ + f_add(3); +} + +static INLINE void getrgb(struct image *img, + INT32 args_start,INT32 args,char *name) +{ + INT32 i; + if (args-args_start<3) return; + for (i=0; i<3; i++) + if (sp[-args+i+args_start].type!=T_INT) + error("Illegal r,g,b argument to %s\n",name); + img->rgb.r=(unsigned char)sp[-args+args_start].u.integer; + img->rgb.g=(unsigned char)sp[1-args+args_start].u.integer; + img->rgb.b=(unsigned char)sp[2-args+args_start].u.integer; + if (args-args_start>=4) + if (sp[3-args+args_start].type!=T_INT) + error("Illegal alpha argument to %s\n",name); + else + img->alpha=sp[3-args+args_start].u.integer; + else + img->alpha=0; } void image_togif(INT32 args) diff --git a/src/modules/Image/x.c b/src/modules/Image/x.c index 4805a38c390efca364e4458a118efbdd761794e2..21e0b0cbfff84cf04f7856c524d5a8a9ec297d09 100644 --- a/src/modules/Image/x.c +++ b/src/modules/Image/x.c @@ -1,4 +1,4 @@ -/* $Id: x.c,v 1.12 1997/10/21 13:36:07 mirar Exp $ */ +/* $Id: x.c,v 1.13 1997/11/07 06:06:18 mirar Exp $ */ /* **! module Image @@ -12,7 +12,7 @@ #include "stralloc.h" #include "global.h" -RCSID("$Id: x.c,v 1.12 1997/10/21 13:36:07 mirar Exp $"); +RCSID("$Id: x.c,v 1.13 1997/11/07 06:06:18 mirar Exp $"); #include "pike_macros.h" #include "object.h" #include "constants.h" @@ -26,6 +26,8 @@ RCSID("$Id: x.c,v 1.12 1997/10/21 13:36:07 mirar Exp $"); #include "image.h" #include "builtin_functions.h" +extern struct program *image_colortable_program; + #define THIS ((struct image *)(fp->current_storage)) #define THISOBJ (fp->current_object) @@ -46,21 +48,10 @@ void image_cast(INT32 args) *sizeof(rgb_group))); } -/* -**! method string to8bit(array(array(int)) colors) -**! method string to8bit_fs(array(array(int)) colors) -**! method string to8bit_closest(array(array(int)) colors) -**! Maps the image to the given colors and returns -**! the 8 bit data. -**! -**! to8bit_fs uses floyd-steinberg dithering -**! returns the calculated string -**! see also: to8bit_rgbcube, tozbgr, map_fast, map_closest, select_colors, tobitmap -*/ - -void image_to8bit_closest(INT32 args) +void image_to8bit(INT32 args) /* compat function */ { - struct colortable *ct; + struct neo_colortable *nct; + struct object *o; struct pike_string *res = begin_shared_string((THIS->xsize*THIS->ysize)); unsigned long i; rgb_group *s; @@ -68,121 +59,26 @@ void image_to8bit_closest(INT32 args) if(!res) error("Out of memory\n"); - if (args!=1) - error("Illegal number of arguments to image->to8bit(COLORTABLE);\n"); - if(sp[-args].type != T_ARRAY) - error("Wrong type to image->to8bit(COLORTABLE);\n"); - - ct=colortable_from_array(sp[-args].u.array,"image->to8bit()\n"); + o=clone_object(image_colortable_program,args); + nct=get_storage(o,image_colortable_program); i=THIS->xsize*THIS->ysize; s=THIS->img; d=(unsigned char *)res->str; THREADS_ALLOW(); - while (i--) - { - *d=ct->index[colortable_rgb_nearest(ct,*s)]; - d++; s++; - } - THREADS_DISALLOW(); - - colortable_free(ct); - - pop_n_elems(args); - push_string(end_shared_string(res)); -} - -void image_to8bit(INT32 args) -{ - struct colortable *ct; - struct pike_string *res = begin_shared_string((THIS->xsize*THIS->ysize)); - unsigned long i; - rgb_group *s; - unsigned char *d; - - if(!res) error("Out of memory\n"); - if (args!=1) - error("Illegal number of arguments to image->to8bit(COLORTABLE);\n"); - if(sp[-args].type != T_ARRAY) - error("Wrong type to image->to8bit(COLORTABLE);\n"); + image_colortable_index_8bit_image(nct,THIS->img, + THIS->xsize*THIS->ysize,THIS->xsize); - ct=colortable_from_array(sp[-args].u.array,"image->to8bit()\n"); - - i=THIS->xsize*THIS->ysize; - s=THIS->img; - d=(unsigned char *)res->str; - - THREADS_ALLOW(); - while (i--) - { - *d=ct->index[colortable_rgb(ct,*s)]; - d++; s++; - } THREADS_DISALLOW(); - colortable_free(ct); + free_object(o); pop_n_elems(args); push_string(end_shared_string(res)); } -void image_to8bit_fs(INT32 args) -{ - struct colortable *ct; - INT32 i,j,xs; - rgb_group *s; - int *res,w; - unsigned char *d; - rgbl_group *errb; - struct pike_string *sres = begin_shared_string((THIS->xsize*THIS->ysize)); - - if (!THIS->img) error("no image\n"); - if (args<1 - || sp[-args].type!=T_ARRAY) - error("illegal argument to image->map_fs()\n"); - - - res=(int*)xalloc(sizeof(int)*THIS->xsize); - errb=(rgbl_group*)xalloc(sizeof(rgbl_group)*THIS->xsize); - - ct=colortable_from_array(sp[-args].u.array,"image->map_closest()\n"); - pop_n_elems(args); - - for (i=0; i<THIS->xsize; i++) - errb[i].r=(rand()%(FS_SCALE*2+1))-FS_SCALE, - errb[i].g=(rand()%(FS_SCALE*2+1))-FS_SCALE, - errb[i].b=(rand()%(FS_SCALE*2+1))-FS_SCALE; - - i=THIS->ysize; - s=THIS->img; - d=(unsigned char *)sres->str; - w=0; - xs=THIS->xsize; - THREADS_ALLOW(); - while (i--) - { - image_floyd_steinberg(s,xs,errb,w=!w,res,ct,1); - for (j=0; j<xs; j++) - *(d++)=ct->index[res[j]]; - s+=xs; - } - THREADS_DISALLOW(); - - free(errb); - free(res); - colortable_free(ct); - push_string(end_shared_string(sres)); -} - - -/* -**! method string tozbgr(array(array(int)) colors) -**! returns the image data as a string ("zbgrzbgr...", where z is zero...) -**! see also: cast, to8bit, to8bit_rgbcube, tobitmap -*/ - void image_tozbgr(INT32 args) { unsigned char *d; @@ -211,12 +107,6 @@ void image_tozbgr(INT32 args) push_string(end_shared_string(sres)); } -/* -**! method string tozrgb(array(array(int)) colors) -**! returns the image data as a string ("rgbrgb...") -**! see also: cast, to8bit, to8bit_rgbcube, tobitmap, tozbgr -*/ - void image_torgb(INT32 args) { if (!THIS->img) error("no image\n"); @@ -226,29 +116,6 @@ void image_torgb(INT32 args) THIS->xsize*THIS->ysize*sizeof(rgb_group))); } -/* -**! method string to8bit_rgbcube(int red,int green,int blue) -**! method string to8bit_rgbcube(int red,int green,int blue,string map) -**! method string to8bit_rgbcube_rdither(int red,int green,int blue) -**! method string to8bit_rgbcube_rdither(int red,int green,int blue,string map) -**! Maps the image into a colorcube with the given -**! dimensions. Red is least significant, blue is most. -**! -**! The "rdither" type of method uses a random dither algoritm. -**! arg int red -**! arg int green -**! arg int blue -**! The sides of the colorcube. Not the number of bits! -**! arg string map -**! Map this position in the colorcube to another value, -**! ie: say we have position red=1,green=2,blue=3 in a colorcube of -**! 6�6�6, we have the index 1+2*6+3*6*6=121. If the -**! map-string contains '�' in position 121, the resulting -**! byte is '�' or 229. -**! returns the calculated string -**! see also: tozbgr, to8bit, tobitmap -*/ - void image_to8bit_rgbcube(INT32 args) /* @@ -404,18 +271,6 @@ void image_to8bit_rgbcube_rdither(INT32 args) push_string(end_shared_string(res)); } -/* -**! method string tobitmap(); -**! Maps the image to a bitmap. -**! -**! Bit 0 is the leftmost pixel, and the rows are aligned to -**! bytes. -**! -**! Any pixel value other then black results in a set bit. -**! returns the calculated string -**! see also: tozbgr, to8bit, to8bit_rgbcube, cast -*/ - void image_tobitmap(INT32 args) { int xs;