pike.git / src / modules / Image / encodings / xcf.c

version» Context lines:

pike.git/src/modules/Image/encodings/xcf.c:1: - #include "global.h" - RCSID("$Id: xcf.c,v 1.38 2001/06/13 13:00:21 grubba Exp $"); + /* + || 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. + */    -  + #include "global.h"   #include "image_machine.h"      #include "pike_macros.h"   #include "object.h" - #include "constants.h" +    #include "module_support.h"   #include "interpret.h"   #include "object.h"   #include "svalue.h"   #include "threads.h" - #include "array.h" +    #include "interpret.h"   #include "svalue.h"   #include "mapping.h"   #include "pike_error.h"   #include "stralloc.h"   #include "builtin_functions.h" - #include "operators.h" - #include "dynamic_buffer.h" - #include "signal_handler.h" +    #include "bignum.h"      #include "image.h"   #include "colortable.h"    - /* MUST BE INCLUDED LAST */ - #include "module_magic.h" +     -  + #define sp Pike_sp + #define fp Pike_fp      extern struct program *image_colortable_program;   extern struct program *image_program;      /*   **! module Image   **! submodule XCF   **!   */   
pike.git/src/modules/Image/encodings/xcf.c:43:   #define TILE_HEIGHT 64      #define STRING(X) static struct pike_string *s_##X   #include "xcf_constant_strings.h"   #undef STRING         struct buffer   {    struct pike_string *s; -  ptrdiff_t base_offset; -  ptrdiff_t base_len; -  size_t len; +     unsigned char *str; -  +  size_t len;   };      struct substring   {    struct pike_string *s;    ptrdiff_t offset;    ptrdiff_t len;   };      static struct program *substring_program;
pike.git/src/modules/Image/encodings/xcf.c:76:   }      static void f_substring_index( INT32 args )   {    ptrdiff_t i = sp[-1].u.integer;    struct substring *s = SS(fp->current_object);    pop_n_elems( args );       if( i < 0 ) i = s->len + i;    if( i >= s->len ) { -  Pike_error("Index out of bounds, %d > %ld\n", i, +  Pike_error("Index out of bounds, %ld > %ld\n", i,    DO_NOT_WARN((long)s->len-1) );    }    push_int( ((unsigned char *)s->s->str)[s->offset+i] );   }      static void f_substring__sprintf( INT32 args )   {    int x;    struct substring *s = SS(fp->current_object);       if (args != 2 )    SIMPLE_TOO_FEW_ARGS_ERROR("_sprintf",2); -  if (sp[-2].type!=T_INT) +  if (TYPEOF(sp[-2]) != T_INT)    SIMPLE_BAD_ARG_ERROR("_sprintf",0,"integer"); -  if (sp[-1].type!=T_MAPPING) +  if (TYPEOF(sp[-1]) != T_MAPPING)    SIMPLE_BAD_ARG_ERROR("_sprintf",1,"mapping");    x = sp[-2].u.integer;    pop_n_elems( args );       switch( x )    {    case 't':    push_constant_text("SubString");    return;    case 'O':
pike.git/src/modules/Image/encodings/xcf.c:115:    push_int64( s->len );    push_int64( s->offset );    f_sprintf( 4 );    return;    default:    push_int(0);    return;    }   }    - static void f_substring_get_int( INT32 args ) + static void f_substring_get_int( INT32 UNUSED(args) )   {    struct substring *s = SS(fp->current_object);    int res;    unsigned char *p;    int x = sp[-1].u.integer;    if( x > s->len>>2 ) -  Pike_error("Index %d out of range", x ); +  Pike_error("Index %d out of range.\n", x );    -  p = s->s->str + s->offset + x*4; +  p = ((unsigned char *)s->s->str) + s->offset + x*4;    res = (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];    push_int( res );   }       - static void f_substring_get_uint( INT32 args ) + static void f_substring_get_uint( INT32 UNUSED(args) )   {    struct substring *s = SS(fp->current_object);    unsigned int res;    unsigned char *p;    int x = sp[-1].u.integer;    if( x > s->len>>2 ) -  Pike_error("Index %d out of range", x ); +  Pike_error("Index %d out of range.\n", x );    -  p = s->s->str + s->offset + x*4; +  p = ((unsigned char *)s->s->str) + s->offset + x*4;    res = (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];    push_int64( res );   }    - static void f_substring_get_ushort( INT32 args ) + static void f_substring_get_ushort( INT32 UNUSED(args) )   {    struct substring *s = SS(fp->current_object);    unsigned short res;    unsigned char *p;    int x = sp[-1].u.integer;    if( x > s->len>>1 ) -  Pike_error("Index %d out of range", x ); +  Pike_error("Index %d out of range.\n", x );    -  p = s->s->str + s->offset + x*2; +  p = ((unsigned char *)s->s->str) + s->offset + x*2;    res = (p[2]<<8) | p[3];    push_int( res );   }    - static void f_substring_get_short( INT32 args ) + static void f_substring_get_short( INT32 UNUSED(args) )   {    struct substring *s = SS(fp->current_object);    short res;    unsigned char *p;    int x = sp[-1].u.integer;    if( x > s->len>>1 ) -  Pike_error("Index %d out of range", x ); +  Pike_error("Index %d out of range.\n", x );    -  p = s->s->str + s->offset + x*2; +  p = ((unsigned char *)s->s->str) + s->offset + x*2;    res = (p[2]<<8) | p[3];    push_int( res );   }      static void push_substring( struct pike_string *s,    ptrdiff_t offset,    ptrdiff_t len )   {    struct object *o = clone_object( substring_program, 0 );    struct substring *ss = SS(o);    ss->s = s;    s->refs++;    ss->offset = offset;    ss->len = len;    push_object( o );   }    - static void free_substring(struct object *o) + static void free_substring(struct object *UNUSED(o))   {    if( SS(fp->current_object)->s )    {    free_string( SS(fp->current_object)->s );    SS(fp->current_object)->s = 0;    }   }         typedef enum
pike.git/src/modules/Image/encodings/xcf.c:322:    res = (char *)from->str;    from->str += len;    from->len -= len;    return res;   }      static struct buffer read_string( struct buffer *data )   {    struct buffer res = *data;    res.len = xcf_read_int( data ); -  res.base_offset = (data->base_offset+(data->base_len-data->len)); +     res.str = (unsigned char *)read_data( data, res.len );    if(res.len > 0) res.len--; /* len includes ending \0 */ -  res.base_len = res.len; +     if(!res.str)    Pike_error("String read failed\n");    return res;   }      static struct property read_property( struct buffer * data )   {    struct property res;    res.type = read_uint( data );    if(res.type == PROP_COLORMAP)    {    unsigned int foo;    read_uint(data); /* bogus 'len'... */    foo = read_uint( data );    res.data.len = foo*3; -  res.data.base_offset = data->base_offset+(data->base_len-data->len); -  res.data.base_len = res.data.len; +     res.data.str = (unsigned char *)read_data( data,foo*3 );    res.data.s = data->s;    } else {    res.data.len = read_uint( data ); -  res.data.base_offset = data->base_offset+(data->base_len-data->len); -  res.data.base_len = res.data.len; +     res.data.str = (unsigned char *)read_data( data,res.data.len );    res.data.s = data->s;    }    res.next = NULL;    return res;   }         struct tile   {
pike.git/src/modules/Image/encodings/xcf.c:518:    MEMSET(&res, 0, sizeof(res));    res.width = read_uint( buff );    res.height = read_uint( buff );       SET_ONERROR( err, free_level, &res );    offset = read_uint( buff );    while(offset)    {    struct buffer ob = *initial;    int offset2 = read_uint( buff ); -  struct tile *tile = (struct tile *)xalloc(sizeof(struct tile)); +  struct tile *tile = xalloc(sizeof(struct tile));    read_data( &ob, offset );    if(last_tile)    last_tile->next = tile;    last_tile = tile;    if(!res.first_tile)    res.first_tile = tile;    tile->data = ob;    tile->next = NULL;    offset = offset2;    }
pike.git/src/modules/Image/encodings/xcf.c:570:    res.width = read_uint( buff );    res.height = read_uint( buff );    res.name = read_string( buff );       SET_ONERROR( err, free_layer_mask, &res );    do    {    tmp = read_property( buff );    if(tmp.type)    { -  struct property *s = (struct property *)xalloc(sizeof(struct property)); +  struct property *s = xalloc(sizeof(struct property));    *s = tmp;    s->next = res.first_property;    res.first_property = s;    }    } while(tmp.type);    offset = read_uint( buff );       if(offset)    {    struct buffer ob = *initial;
pike.git/src/modules/Image/encodings/xcf.c:607:    res.width = read_uint( buff );    res.height = read_uint( buff );    res.name = read_string( buff );       SET_ONERROR( err, free_channel, &res );    do    {    tmp = read_property( buff );    if(tmp.type)    { -  struct property *s =(struct property *)xalloc( sizeof(struct property )); +  struct property *s = xalloc( sizeof(struct property ));    *s = tmp;    s->next = res.first_property;    res.first_property = s;    }    } while( tmp.type );    offset = read_uint( buff );       if(offset)    {    struct buffer ob = *initial;
pike.git/src/modules/Image/encodings/xcf.c:646:    res.height = read_uint( buff );    res.type = xcf_read_int( buff );    res.name = read_string( buff );          do    {    tmp = read_property( buff );    if(tmp.type)    { -  struct property *s=(struct property *)xalloc( sizeof(struct property )); +  struct property *s=xalloc( sizeof(struct property ));    *s = tmp;    s->next = res.first_property;    res.first_property = s;    }    } while( tmp.type );       h_offset = xcf_read_int( buff );    lm_offset = xcf_read_int( buff );       if(lm_offset)    {    struct buffer loffset = *initial; -  struct layer_mask *m=(struct layer_mask *)xalloc(sizeof(struct layer_mask)); +  struct layer_mask *m=xalloc(sizeof(struct layer_mask));    res.mask = m;    read_data( &loffset, lm_offset );    MEMSET(m, 0, sizeof( struct layer_mask ));    *m = read_layer_mask( &loffset, initial );    }       if(h_offset)    {    struct buffer loffset = *initial;    read_data( &loffset, h_offset );
pike.git/src/modules/Image/encodings/xcf.c:714:    res.height = read_uint( data );    res.type = xcf_read_int( data );       SET_ONERROR( err, free_image, &res );       do    {    tmp = read_property( data );    if(tmp.type)    { -  struct property *s= (struct property *)xalloc( sizeof(struct property )); +  struct property *s=xalloc( sizeof(struct property ));    *s = tmp;    s->next = res.first_property;    res.first_property = s;    }    } while( tmp.type );       while( (offset = read_uint( data )) )    {    struct buffer layer_data = initial;    struct layer tmp;    read_data( &layer_data, offset );    tmp = read_layer( &layer_data, &initial );    if( tmp.width && tmp.height )    { -  struct layer *s = (struct layer *)xalloc( sizeof(struct layer)); +  struct layer *s = xalloc( sizeof(struct layer));    *s = tmp;    s->next = res.first_layer;    res.first_layer = s;    }    }       while( (offset = read_uint( data )) )    {    struct buffer channel_data = initial;    struct channel tmp;    read_data( &channel_data, offset );    tmp = read_channel( &channel_data, &initial );    if( tmp.width && tmp.height )    { -  struct channel *s = (struct channel *)xalloc( sizeof(struct channel)); +  struct channel *s = xalloc( sizeof(struct channel));    *s = tmp;    s->next = res.first_channel;    res.first_channel = s;    }    }    UNSET_ONERROR( err );    return res;   }      static void push_buffer( struct buffer *b )   { -  push_substring( b->s, b->base_offset+(b->base_len-b->len), b->len ); +  push_substring( b->s, b->str - (unsigned char *)b->s->str, b->len );   /* push_string( make_shared_binary_string( (char *)b->str, b->len ) );*/   }      static void push_properties( struct property *p )   {    struct svalue *osp = sp;    while(p)    {    ref_push_string( s_type ); push_int( p->type );    ref_push_string( s_data ); push_buffer( &p->data );
pike.git/src/modules/Image/encodings/xcf.c:893:   {    struct pike_string *s;    struct buffer b;    struct gimp_image res;    ONERROR err;    get_all_args( "___decode", args, "%S", &s );    if(args > 1)    Pike_error("Too many arguments to Image.XCF.___decode()\n");       b.s = s; -  b.base_offset = 0; -  b.base_len = s->len; +     b.len = s->len;    b.str = (unsigned char *)s->str;       res = read_image( &b );    SET_ONERROR( err, free_image, &res );    push_image( &res );    UNSET_ONERROR( err );    free_image( &res );    stack_swap();    pop_stack();
pike.git/src/modules/Image/encodings/xcf.c:1176:   **! ])   **!</pre>   */      void image_xcf_f__decode_tiles( INT32 args )   {    struct object *io,*ao, *cmapo;    struct array *tiles;    struct image *i=NULL, *a=NULL;    struct neo_colortable *cmap = NULL; -  int rxs, rys; +  INT32 rxs, rys;    rgb_group *colortable=NULL;    rgb_group pix = {0,0,0};    rgb_group apix= {255,255,255}; /* avoid may use uninitialized warnings */       INT_TYPE rle, bpp, span, shrink;    unsigned int l, x=0, y=0, cx, cy; -  get_all_args( "_decode_tiles", args, "%o%O%a%i%i%O%d%d%d", +  ONERROR err; +  get_all_args( "_decode_tiles", args, "%o%O%a%i%i%O%i%d%d",    &io, &ao, &tiles, &rle, &bpp, &cmapo, &shrink, &rxs, &rys);          if( !(i = (struct image *)get_storage( io, image_program )))    Pike_error("Wrong type object argument 1 (image)\n");       if(ao && !(a = (struct image *)get_storage( ao, image_program )))    Pike_error("Wrong type object argument 2 (image)\n");       if( cmapo &&    !(cmap=(struct neo_colortable *)get_storage(cmapo,    image_colortable_program)))    Pike_error("Wrong type object argument 4 (colortable)\n");       for(l=0; l<(unsigned int)tiles->size; l++) -  if(tiles->item[l].type != T_OBJECT) +  if(TYPEOF(tiles->item[l]) != T_OBJECT)    Pike_error("Wrong type array argument 3 (tiles)\n");       if(a && ((i->xsize != a->xsize) || (i->ysize != a->ysize)))    Pike_error("Image and alpha objects are not identically sized.\n");       if(cmap)    { -  colortable = malloc(sizeof(rgb_group)*image_colortable_size( cmap )); +  colortable = xalloc(sizeof(rgb_group)*image_colortable_size( cmap ) + RGB_VEC_PAD); +  SET_ONERROR(err, free, colortable);    image_colortable_write_rgb( cmap, (unsigned char *)colortable );    }       x=y=0;       THREADS_ALLOW();    for(l=0; l<(unsigned)tiles->size; l++)    {    struct object *to = tiles->item[l].u.object;    struct substring *tile_ss = SS(to);    struct buffer tile;    char *df = 0;    unsigned int eheight, ewidth;    unsigned char *s;       if(!tile_ss)    continue;    -  tile.str = (tile_ss->s->str + tile_ss->offset); +  tile.s = NULL; +  tile.str = (unsigned char *)(tile_ss->s->str + tile_ss->offset);    tile.len = tile_ss->len;       ewidth = MINIMUM(TILE_WIDTH, (rxs-x));    eheight = MINIMUM(TILE_HEIGHT, (rys-y));    -  +  if( (double)ewidth * eheight * bpp > INT_MAX ) +  Pike_error("Insanely large tiles not supported\n");    if(rle)    {    struct buffer s = tile, od, d;    int i; -  +  od.s = NULL;    od.len = eheight*ewidth*bpp; /* Max and only size, really */ -  df = od.str = (unsigned char *)xalloc( eheight*ewidth*bpp+1 ); +  df = (char *)(od.str = xalloc( eheight*ewidth*bpp+1 ));    d = od;       for(i=0; i<bpp; i++)    {    int nelems = ewidth*eheight;    int length;    while(nelems)    {    unsigned char val = read_char( &s );    if(!s.len)
pike.git/src/modules/Image/encodings/xcf.c:1394:    }    x += TILE_WIDTH;       if( (int)x >= (int)rxs )    {    x = 0;    y += TILE_HEIGHT;    }    }    THREADS_DISALLOW(); -  if(colortable) +  if(colortable) { +  UNSET_ONERROR(err);    free( colortable ); -  +  }       pop_n_elems(args);    push_int(0);   }         static struct program *image_encoding_xcf_program=NULL;   void init_image_xcf()   { -  add_function( "___decode", image_xcf____decode, -  "function(string:mapping)", 0); +  ADD_FUNCTION( "___decode", image_xcf____decode, tFunc(tStr,tMapping), 0);    -  add_function( "_decode_tiles", image_xcf_f__decode_tiles, "mixed", 0); +  ADD_FUNCTION( "_decode_tiles", image_xcf_f__decode_tiles, tFunction, 0);       add_integer_constant( "PROP_END", PROP_END,0 );    add_integer_constant( "PROP_COLORMAP", PROP_COLORMAP, 0 );    add_integer_constant( "PROP_ACTIVE_LAYER", PROP_ACTIVE_LAYER, 0 );    add_integer_constant( "PROP_ACTIVE_CHANNEL", PROP_ACTIVE_CHANNEL, 0 );    add_integer_constant( "PROP_SELECTION", PROP_SELECTION, 0 );    add_integer_constant( "PROP_FLOATING_SELECTION", PROP_FLOATING_SELECTION, 0 );    add_integer_constant( "PROP_OPACITY", PROP_OPACITY, 0 );    add_integer_constant( "PROP_MODE", PROP_MODE, 0 );    add_integer_constant( "PROP_VISIBLE", PROP_VISIBLE, 0 );
pike.git/src/modules/Image/encodings/xcf.c:1487:    add_integer_constant( "GRAYA_GIMAGE", GRAYA_GIMAGE, 0 );    add_integer_constant( "INDEXED_GIMAGE", INDEXED_GIMAGE, 0 );    add_integer_constant( "INDEXEDA_GIMAGE", INDEXEDA_GIMAGE, 0 );      #define STRING(X) s_##X = make_shared_binary_string(#X,sizeof( #X )-sizeof(""))   #include "xcf_constant_strings.h"   #undef STRING       start_new_program();    ADD_STORAGE( struct substring ); -  add_function("cast", f_substring_cast, "function(string:mixed)",0); -  add_function("`[]", f_substring_index, "function(int:int)",0); -  add_function("get_short", f_substring_get_short, "function(int:int)", 0 ); -  add_function("get_ushort", f_substring_get_ushort, "function(int:int)", 0 ); -  add_function("get_int", f_substring_get_int, "function(int:int)", 0 ); -  add_function("get_uint", f_substring_get_uint, "function(int:int)", 0 ); -  add_function("_sprintf",f_substring__sprintf, -  "function(int,mapping:mixed)", 0); +  ADD_FUNCTION("cast", f_substring_cast, tFunc(tStr,tMix), 0); +  ADD_FUNCTION("`[]", f_substring_index, tFunc(tInt,tInt), 0); +  ADD_FUNCTION("get_short", f_substring_get_short, tFunc(tInt,tInt), 0 ); +  ADD_FUNCTION("get_ushort", f_substring_get_ushort, tFunc(tInt,tInt), 0 ); +  ADD_FUNCTION("get_int", f_substring_get_int, tFunc(tInt,tInt), 0 ); +  ADD_FUNCTION("get_uint", f_substring_get_uint, tFunc(tInt,tInt), 0 ); +  ADD_FUNCTION("_sprintf",f_substring__sprintf, tFunc(tInt tMapping,tMix), 0); +    /* set_init_callback(init_substring); */    set_exit_callback(free_substring);    substring_program = end_program();   }         void exit_image_xcf()   {   #define STRING(X) free_string(s_##X)   #include "xcf_constant_strings.h"   #undef STRING    free_program( substring_program );   }