e576bb2002-10-11Martin Nilsson /* || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. */
a367b51999-04-12Per Hedbor #include "global.h"
d9db231999-05-30Mirar (Pontus Hagland) #include "image_machine.h"
a367b51999-04-12Per Hedbor #include <math.h> #include <ctype.h>
63888b1999-05-07Fredrik Hübinette (Hubbe) 
1784aa1999-05-06David Hedbor #ifdef HAVE_NETINET_IN_H
a367b51999-04-12Per Hedbor #include <netinet/in.h>
1784aa1999-05-06David Hedbor #endif
abfed12003-12-17Marcus Comstedt #ifdef HAVE_SYS_SOCKET_H #include <sys/socket.h> #endif
63888b1999-05-07Fredrik Hübinette (Hubbe) 
a367b51999-04-12Per Hedbor #include "stralloc.h" #include "object.h" #include "interpret.h"
b2d3e42000-12-01Fredrik Hübinette (Hubbe) #include "pike_error.h"
6dc2772000-07-28Fredrik Hübinette (Hubbe) #include "mapping.h" #include "operators.h"
42bd312015-05-22Henrik Grubbström (Grubba) #include "bignum.h"
a367b51999-04-12Per Hedbor  #include "image.h" #include "builtin_functions.h" #include "module_support.h"
6dc2772000-07-28Fredrik Hübinette (Hubbe) 
a367b51999-04-12Per Hedbor extern struct program *image_program; /* **! module Image **! submodule AVS **!
57c5852014-07-31Per Hedbor **! An AVS file is a raw (uncompressed) 24 bit image file with alpha. **! **! The file starts with width and height as 32-bit ingegers, followed **! by 4 x width x height bytes of image data. The format is big **! endian.
a367b51999-04-12Per Hedbor */ /* **! method object decode(string data) **! method mapping _decode(string data)
ed517e2013-02-09Henrik Grubbström (Grubba) **! method string encode(object image, object|void alpha)
a367b51999-04-12Per Hedbor **! **! Handle encoding and decoding of AVS-X images. **! AVS is rather trivial, and not really useful, but: **! **! An AVS file is a raw (uncompressed) 24 bit image file with alpha. **! The alpha channel is 8 bit, and there is no separate alpha for r, **! g and b. */ void image_avs_f__decode(INT32 args) { struct object *io, *ao; struct pike_string *s;
bae6381999-04-15Per Hedbor  unsigned int c;
f9d9c22017-11-05Arne Goedeke  unsigned int len;
0f0b532006-09-22Henrik Grubbström (Grubba)  int w, h;
a367b51999-04-12Per Hedbor  unsigned char *q;
f9d9c22017-11-05Arne Goedeke  rgb_group *img_i, *img_a;
391ac52018-08-05Martin Nilsson  get_all_args( NULL, args, "%S", &s);
42bd312015-05-22Henrik Grubbström (Grubba)  if (s->len < 12) /* Width + height + one pixel */ Pike_error("This is not an AVS file.\n");
01a9572000-02-03Henrik Grubbström (Grubba)  q = (unsigned char *)s->str;
a367b51999-04-12Per Hedbor  w = q[0]<<24 | q[1]<<16 | q[2]<<8 | q[3]; h = q[4]<<24 | q[5]<<16 | q[6]<<8 | q[7];
42bd312015-05-22Henrik Grubbström (Grubba)  /* Check for under- and overflow. */ if ((w <= 0) || (h <= 0) || INT32_MUL_OVERFLOW(w, h) ||
f9d9c22017-11-05Arne Goedeke  INT32_MUL_OVERFLOW(w*h, 4) || ((w * h) & -0x40000000))
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("This is not an AVS file (w=%d; h=%d)\n", w, h);
a367b51999-04-12Per Hedbor 
42bd312015-05-22Henrik Grubbström (Grubba)  if((size_t)w*h*4 != (size_t)(s->len-8))
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("This is not an AVS file (w=%d; h=%d; s=%ld)\n",
cc7cf42015-10-14Martin Nilsson  w, h, (long)s->len);
a367b51999-04-12Per Hedbor  push_int( w ); push_int( h ); io = clone_object( image_program, 2); push_int( w ); push_int( h ); ao = clone_object( image_program, 2);
f9d9c22017-11-05Arne Goedeke  img_i = ((struct image *)io->storage)->img; img_a = ((struct image *)ao->storage)->img; len = (s->len - 8) / 4; for(c=0; c< len; c++)
a367b51999-04-12Per Hedbor  { rgb_group pix, apix; apix.r = apix.g = apix.b = q[c*4+8]; pix.r = q[c*4+9]; pix.g = q[c*4+10]; pix.b = q[c*4+11];
f9d9c22017-11-05Arne Goedeke  img_i[c] = pix; img_a[c] = apix;
a367b51999-04-12Per Hedbor  } pop_n_elems(args);
5e9fc02015-08-18Per Hedbor  push_static_text("image");
a367b51999-04-12Per Hedbor  push_object( io );
5e9fc02015-08-18Per Hedbor  push_static_text("alpha");
a367b51999-04-12Per Hedbor  push_object( ao ); f_aggregate_mapping( 4 ); } void image_avs_f_decode(INT32 args) { image_avs_f__decode(args);
5e9fc02015-08-18Per Hedbor  push_static_text("image");
a367b51999-04-12Per Hedbor  f_index(2); } void image_avs_f_encode(INT32 args ) { struct object *io, *ao=NULL; struct image *i, *a=NULL; rgb_group *is,*as=NULL; struct pike_string *s; int x,y; unsigned int *q; rgb_group apix = {255, 255, 255};
391ac52018-08-05Martin Nilsson  get_all_args( NULL, args, "%o.%o", &io, &ao);
13670c2015-05-25Martin Nilsson 
13b5ed2014-05-26Per Hedbor  if(!(i = get_storage( io, image_program)))
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Wrong argument 1 to Image.AVS.encode\n");
ed517e2013-02-09Henrik Grubbström (Grubba)  if(ao) {
13b5ed2014-05-26Per Hedbor  if (!(a = get_storage( ao, image_program)))
ed517e2013-02-09Henrik Grubbström (Grubba)  Pike_error("Wrong argument 2 to Image.AVS.encode\n"); if ((a->xsize != i->xsize) || (a->ysize != i->ysize)) Pike_error("Bad size for alpha channel to Image.AVS.encode.\n"); }
a367b51999-04-12Per Hedbor  s = begin_shared_string( i->xsize*i->ysize*4+8 );
21b12a2014-09-03Martin Nilsson  memset(s->str, 0, s->len );
a367b51999-04-12Per Hedbor 
9dcbca1999-05-12David Hedbor  q = (unsigned int *)s->str;
a367b51999-04-12Per Hedbor  *(q++) = htonl( i->xsize ); *(q++) = htonl( i->ysize ); is = i->img; if(a) as = a->img; for(y=0; y<i->ysize; y++) for(x=0; x<i->xsize; x++) {
636bc52014-11-01Martin Nilsson  unsigned int rv = 0;
a367b51999-04-12Per Hedbor  rgb_group pix = *(is++); if(as) apix = *(as++); rv = ((apix.g<<24)|(pix.r<<16)|(pix.g<<8)|pix.b); *(q++) = htonl(rv); } pop_n_elems(args); push_string( end_shared_string(s) ); }
c9eefb2014-08-21Martin Nilsson void init_image_avs(void)
a367b51999-04-12Per Hedbor {
226ec82005-01-23Martin Nilsson  ADD_FUNCTION( "decode", image_avs_f_decode, tFunc(tStr,tObj), 0); ADD_FUNCTION( "_decode", image_avs_f__decode, tFunc(tStr,tMapping), 0);
ed517e2013-02-09Henrik Grubbström (Grubba)  ADD_FUNCTION( "encode", image_avs_f_encode, tFunc(tObj tOr(tObj,tVoid),tStr), 0);
a367b51999-04-12Per Hedbor }
c9eefb2014-08-21Martin Nilsson void exit_image_avs(void)
a367b51999-04-12Per Hedbor { }