pike.git / src / modules / Image / blit.c

version» Context lines:

pike.git/src/modules/Image/blit.c:1: - /* $Id: blit.c,v 1.30 1999/04/13 12:32:09 mirar Exp $ */ + /* $Id: blit.c,v 1.31 1999/04/16 17:45:05 mirar Exp $ */   #include "global.h"      /*   **! module Image   **! note - **! $Id: blit.c,v 1.30 1999/04/13 12:32:09 mirar Exp $ + **! $Id: blit.c,v 1.31 1999/04/16 17:45:05 mirar Exp $   **! class Image   */      #include <math.h>   #include <ctype.h>      #include "stralloc.h"   #include "global.h"   #include "pike_macros.h"   #include "object.h"
pike.git/src/modules/Image/blit.c:611:    if (y1>y2) y1^=y2,y2^=y1,y1^=y2;    if (x2 >= THIS->xsize) x2 = THIS->xsize-1;    if (y2 >= THIS->ysize) y2 = THIS->ysize-1;    if (x2<0||y2<0||x1>=THIS->xsize||y1>=THIS->ysize) return;    if (x1<0) x1 = 0;    if (y1<0) y1 = 0;    img_box_nocheck(MAXIMUM(x1,0),MAXIMUM(y1,0),MINIMUM(x2,THIS->xsize-1),MINIMUM(y2,THIS->ysize-1));   }       - /* - **! method object add_layers(array(int|object)) layer0,...) - **! method object add_layers(int x1,int y1,int x2,int y2,array(int|object)) layer0,...) - **! Using the called object as base, adds layers using masks, - **! opaque channel values and special methods. - **! - **! The destination image can also be cropped, thus - **! speeding up the process. - **! - **! Each array in the layers array is one of: - **! <pre> - **! ({object image,object|int mask}) - **! ({object image,object|int mask,int opaque_value}) - **! ({object image,object|int mask,int opaque_value,int method}) - **! </pre> - **! Given 0 as mask means the image is totally opaque. - **! - **! Default opaque value is 255, only using the mask. - **! - **! Methods for now are: - **! <pre> - **! 0 no operation (just paste with mask, default) - **! 1 maximum (`|) - **! 2 minimum (`&) - **! 3 multiply (`*) - **! 4 add (`+) - **! 5 diff (`-) - **! </pre> - **! The layer image and the current source are calculated - **! through the given method and then pasted using the mask - **! and the opaque channel value. - **! - **! All given images must be the same size. - **! - **! returns a new image object - **! - **! arg array(int|object) layer0 - **! image to paste - **! arg int x1 - **! arg int y1 - **! arg int x2 - **! arg int y2 - **! rectangle for cropping - **! - **! see also: paste_mask, paste_alpha, paste_alpha_color, `|, `&, `*, `+, `- - */ -  - void image_add_layers(INT32 args) - /* -  - [x1,y1,x2,y2], - ({object image,object mask|0,[int alpha_value,[int method]]}), - ({object image,object mask|0,[int alpha_value,[int method]]}), - ... - :object -  -  */ - { -  struct img_layer -  { -  rgb_group *s; -  rgb_group *m; -  int opaque; -  enum layer_method method; -  } *layer; -  float q2=1/(255.0*255.0); -  float q=1/(255.0); -  rgb_group *s; -  rgb_group *d; -  struct object *o; -  -  int allopaque255=1,allmask=1,allnop=1; -  -  int i,j,l,mod,layers; -  int x1,y1,x2,y2; -  -  if (!THIS->img) error("No image."); -  s=THIS->img; -  -  if (args>=4 -  && sp[-args].type==T_INT -  && sp[1-args].type==T_INT -  && sp[2-args].type==T_INT -  && sp[3-args].type==T_INT) -  { -  x1=sp[-args].u.integer; -  y1=sp[1-args].u.integer; -  x2=sp[2-args].u.integer; -  y2=sp[3-args].u.integer; -  -  if (x2<x1) x2^=x1,x1^=x2,x2^=x1; -  if (y2<y1) y2^=y1,y1^=y2,y2^=y1; -  -  if (x2>THIS->xsize-1 || -  y2>THIS->ysize-1 || -  x1<0 || y1<0) -  error("Illegal coordinates to image->add_layers()\n"); -  layers=args-4; -  } -  else -  { -  x1=0; -  y1=0; -  x2=THIS->xsize-1; -  y2=THIS->ysize-1; -  layers=args; -  } -  -  layer=(struct img_layer*)xalloc(sizeof(struct img_layer)*layers); -  -  for (j=0,i=layers; i>0; i--,j++) -  { -  struct array *a; -  struct image *img; -  if (sp[-i].type!=T_ARRAY) -  { -  free(layer); -  error("Illegal argument(s) to image->add_layers()\n"); -  } -  a=sp[-i].u.array; -  if (a->size<2) -  { -  free(layer); -  error("Illegal size of array argument to image->add_layers()\n"); -  } -  -  if (a->item[0].type!=T_OBJECT) -  { -  free(layer); -  error("Illegal array contents, layer %d (argument %d) (wrong or no image) to image->add_layers()\n",layers-i,args-i+1); -  } -  img=(struct image*)get_storage(a->item[0].u.object,image_program); -  if (!img -  || !img->img -  || img->xsize != THIS->xsize -  || img->ysize != THIS->ysize) -  { -  free(layer); -  error("Illegal array contents, layer %d (argument %d) (no image or wrong image size) to image->add_layers()\n",layers-i,args-i+1); -  } -  layer[j].s=img->img; -  -  if (a->item[1].type==T_INT -  && a->item[1].u.integer==0) -  { -  layer[j].m=NULL; -  } -  else -  { -  if (a->item[1].type!=T_OBJECT) -  { -  free(layer); -  error("Illegal array contents, layer %d (argument %d) (wrong or no image for mask) to image->add_layers()\n",layers-i,args-i+1); -  } -  img=(struct image*)get_storage(a->item[1].u.object,image_program); -  if (!img -  || !img->img -  || img->xsize != THIS->xsize -  || img->ysize != THIS->ysize) -  { -  free(layer); -  error("Illegal array contents, layer %d (argument %d) (no mask or wrong mask size) to image->add_layers()\n",layers-i,args-i+1); -  } -  layer[j].m=img->img; -  } -  -  if (a->size>=3) -  { -  if (a->item[2].type!=T_INT) -  { -  free(layer); -  error("Illegal array contents, layer %d (argument %d) (illegal opaque) to image->add_layers()\n",layers-i,args-i+1); -  } -  layer[j].opaque=a->item[2].u.integer; -  } -  else -  layer[j].opaque=255; -  -  if (a->size>=4) -  { -  if (a->item[3].type!=T_INT) -  { -  free(layer); -  error("Illegal array contents, layer %d (argument %d) (illegal method) to image->add_layers()\n",layers-i,args-i+1); -  } -  layer[j].method=(enum layer_method)a->item[3].u.integer; -  } -  else -  layer[j].method=LAYER_NOP; -  } -  -  push_int(1+x2-x1); -  push_int(1+y2-y1); -  o=clone_object(image_program,2); -  d=((struct image*)get_storage(o,image_program))->img; -  -  -  mod=THIS->xsize-(x2-x1+1); -  s+=x1+THIS->xsize*y1; -  for (i=0; i<layers; i++) -  { -  layer[i].s+=x1+THIS->xsize*y1; -  if (layer[i].m) layer[i].m+=x1+THIS->xsize*y1; -  else allmask=0; -  if (layer[i].opaque!=255) allopaque255=0; -  if (layer[i].method!=LAYER_NOP) allnop=0; -  } -  -  if (allmask && allopaque255 && allnop) -  { - #define ALL_IS_NOP - #define ALL_HAVE_MASK - #define ALL_HAVE_OPAQUE - #include "blit_layer_include.h" - #undef ALL_IS_NOP - #undef ALL_HAVE_MASK - #undef ALL_HAVE_OPAQUE -  } -  else if (allopaque255 && allnop) -  { - #define ALL_IS_NOP - #define ALL_HAVE_OPAQUE - #include "blit_layer_include.h" - #undef ALL_IS_NOP - #undef ALL_HAVE_OPAQUE -  } -  else if (allmask && allnop) -  { - #define ALL_HAVE_MASK - #define ALL_HAVE_OPAQUE - #include "blit_layer_include.h" - #undef ALL_HAVE_MASK - #undef ALL_HAVE_OPAQUE -  } -  else if (allnop) -  { - #define ALL_IS_NOP - #include "blit_layer_include.h" - #undef ALL_IS_NOP -  } -  else if (allmask && allopaque255) -  { - #define ALL_HAVE_MASK - #define ALL_HAVE_OPAQUE - #include "blit_layer_include.h" - #undef ALL_HAVE_MASK - #undef ALL_HAVE_OPAQUE -  } -  else if (allopaque255) -  { - #define ALL_HAVE_OPAQUE - #include "blit_layer_include.h" - #undef ALL_HAVE_OPAQUE -  } -  else if (allmask) -  { - #define ALL_HAVE_MASK - #include "blit_layer_include.h" - #undef ALL_HAVE_MASK -  } -  else -  { - #include "blit_layer_include.h" -  } -  -  -  pop_n_elems(args); -  -  free(layer); -  -  push_object(o); - } +