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.35 2000/12/05 21:08:28 per 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:70:   {    /* FIXME: assumes string */    struct substring *s = SS(fp->current_object);    pop_n_elems( args );    push_string( make_shared_binary_string( (((char *)s->s->str)+s->offset),    s->len ) );   }      static void f_substring_index( INT32 args )   { -  int i = sp[-1].u.integer; +  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':    push_constant_text("SubString( %O /* [+%d .. %d] */ )" );    push_text("string"); f_substring_cast( 1 );    -  push_int( s->len ); -  push_int( s->offset ); +  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 )   { -  int i; +     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:559:    return res;   }      static struct layer_mask read_layer_mask( struct buffer *buff,    struct buffer *initial )   {    struct layer_mask res;    ONERROR err;    int offset;    struct property tmp; -  struct buffer ob; +        MEMSET(&res, 0, sizeof(res));    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 );
pike.git/src/modules/Image/encodings/xcf.c:597:    return res;   }      static struct channel read_channel( struct buffer *buff,    struct buffer *initial )   {    struct channel res;    ONERROR err;    int offset;    struct property tmp; -  struct buffer ob; +        MEMSET(&res, 0, sizeof(res));    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 );
pike.git/src/modules/Image/encodings/xcf.c:759:    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 );    f_aggregate_mapping( 4 );    p = p->next;    } -  f_aggregate(DO_NOT_WARN(sp - osp)); +  f_aggregate(DO_NOT_WARN((INT32)(sp - osp)));   }      static void push_tile( struct tile *t )   {    push_buffer( &t->data );   }      static void push_hierarchy( struct hierarchy * h )   {    struct tile *t = h->level.first_tile;
pike.git/src/modules/Image/encodings/xcf.c:800:    ref_push_string( s_height ); push_int( h->height );    ref_push_string( s_bpp ); push_int( h->bpp );       ref_push_string( s_tiles );    tsp = sp;    while(t)    {    push_tile( t );    t=t->next;    } -  f_aggregate(DO_NOT_WARN(sp - tsp)); -  f_aggregate_mapping(DO_NOT_WARN(sp - osp)); +  f_aggregate(DO_NOT_WARN((INT32)(sp - tsp))); +  f_aggregate_mapping(DO_NOT_WARN((INT32)(sp - osp)));   }      static void push_layer_mask(struct layer_mask *i)   {    struct svalue *osp = sp;    ref_push_string( s_width ); push_int( i->width );    ref_push_string( s_height ); push_int( i->height );    ref_push_string( s_properties );    push_properties( i->first_property );    ref_push_string( s_name ); push_buffer( &i->name );    ref_push_string( s_image_data );    push_hierarchy( &i->image_data ); -  f_aggregate_mapping(DO_NOT_WARN(sp-osp)); +  f_aggregate_mapping(DO_NOT_WARN((INT32)(sp-osp)));   }      static void push_channel(struct channel *i)   {    struct svalue *osp = sp;    ref_push_string( s_width ); push_int( i->width );    ref_push_string( s_height ); push_int( i->height );    ref_push_string( s_properties );    push_properties( i->first_property );    ref_push_string( s_name ); push_buffer( &i->name );    ref_push_string( s_image_data );    push_hierarchy( &i->image_data ); -  f_aggregate_mapping(DO_NOT_WARN(sp-osp)); +  f_aggregate_mapping(DO_NOT_WARN((INT32)(sp-osp)));   }      static void push_layer(struct layer *i)   {    struct svalue *osp = sp;    ref_push_string( s_width ); push_int( i->width );    ref_push_string( s_height ); push_int( i->height );    ref_push_string( s_type ); push_int( i->type );    ref_push_string( s_properties );    push_properties( i->first_property );    ref_push_string( s_name ); push_buffer( &i->name );    ref_push_string( s_image_data );    push_hierarchy( &i->image_data );    if( i->mask )    {    ref_push_string( s_mask );    push_layer_mask( i->mask );    } -  f_aggregate_mapping(DO_NOT_WARN(sp - osp)); +  f_aggregate_mapping(DO_NOT_WARN((INT32)(sp - osp)));   }         static void push_image( struct gimp_image *i )   {    struct layer *l;    struct channel *c;    int nitems = 0;    struct svalue *osp = sp;    ref_push_string( s_width ); push_int( i->width );
pike.git/src/modules/Image/encodings/xcf.c:881:    ref_push_string( s_channels );    nitems=0;    c = i->first_channel;    while(c)    {    nitems++;    push_channel( c );    c = c->next;    }    f_aggregate( nitems ); -  f_aggregate_mapping(DO_NOT_WARN(sp-osp)); +  f_aggregate_mapping(DO_NOT_WARN((INT32)(sp-osp)));   }         static void image_xcf____decode( INT32 args )   {    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:925:    {    res = from->str[0];    from->str++;    from->len--;    }    return res;   }      /*   **! method array(object) decode_layers( string data ) + **! method array(object) decode_layers( string data, mapping options )   **! Decodes a XCF image to an array of Image.Layer objects   **!   **! The layer object have the following extra variables (to be queried   **! using get_misc_value):   **!   **! image_xres, image_yres, image_colormap, image_guides, image_parasites,   **! name, parasites, visible, active -  + **! + **! Takes the same argument mapping as <ref>_decode</ref>, + **! note especially "draw_all_layers":1.   */      /*   **! method object decode(string data)   **! Decodes a XCF image to a single image object.   **!   **! note   **! Throws upon error in data, you will loose quite a lot of   **! information by doing this. See Image.XCF._decode and Image.XCF.__decode   */
pike.git/src/modules/Image/encodings/xcf.c:1175:   **! ])   **!</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 = (unsigned char *)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:1393:    }    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:1486:    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 );   }