pike.git / lib / modules / _Image_XCF.pmod

version» Context lines:

pike.git/lib/modules/_Image_XCF.pmod:1:   #pike __REAL_VERSION__    + //! @appears Image.XCF + //! eXperimental Computing Facility (aka GIMP native) format. +    inherit Image._XCF;      #define SIGNED(X) if(X>=(1<<31)) X=-((1<<32)-X)      class PathPoint   {    int type;    float x;    float y;   }
pike.git/lib/modules/_Image_XCF.pmod:32:    SIGNED(pos);    }   }      class Parasite( string name, int flags, string data ) { }      array(Parasite) decode_parasites( mixed data )   {    array res = ({});    data = (string)data; -  while(strlen(data)) +  while(sizeof(data))    {    int slen, flags; -  string value, name; +     sscanf(data, "%4c", slen); -  name = data[..slen-2]; +  string name = data[..slen-2];    data = data[slen..];    sscanf(data, "%4c%4c", flags, slen);    res += ({ Parasite( name,flags,data[8..slen+8-1] ) });    data = data[slen+8..];    }    return res;   }      #define FLAG(X,Y) case PROP_##X: flags->Y=p->data->get_int(0); break;   #define INT(X,Y) case PROP_##X: Y = p->data->get_uint( 0 ); break;
pike.git/lib/modules/_Image_XCF.pmod:97:    mapping flags = ([]);    array (Parasite) parasites;       void decode_properties( array properties )    {    foreach(properties, mapping p)    {    switch(p->type)    {    case PROP_ACTIVE_CHANNEL: -  parent->active_channel = this_object(); +  parent->active_channel = this;    break;    case PROP_SELECTION: -  parent->selection = this_object(); +  parent->selection = this;    break;    INT(OPACITY,opacity);    FLAG(VISIBLE,visible);    FLAG(LINKED,linked);    FLAG(PRESERVE_TRANSPARENCY,preserve_transparency);    FLAG(EDIT_MASK,edit_mask);    FLAG(SHOW_MASKED,show_masked);    INT(TATTOO,tattoo);    case PROP_COLOR:    sscanf( (string)p->data, "%c%c%c", r, g, b);
pike.git/lib/modules/_Image_XCF.pmod:139:    if(d->properties) decode_properties( d->properties );    }   }         class LayerMask   {    inherit Channel;   }    + //!   class Layer   {    string name;    int opacity;    int type;    int mode;    int tattoo;    mapping flags = ([]);    int width, height;    int xoffset, yoffset;
pike.git/lib/modules/_Image_XCF.pmod:162:       object parent;       void decode_properties( array properties )    {    foreach( properties, mapping p)    {    switch(p->type)    {    case PROP_ACTIVE_LAYER: -  parent->active_layer = this_object(); +  parent->active_layer = this;    break;    case PROP_SELECTION: -  parent->selection = this_object(); +  parent->selection = this;    break;    case PROP_OFFSETS:    xoffset = p->data->get_int( 0 );    yoffset = p->data->get_int( 1 );    break;    INT(OPACITY,opacity);    FLAG(VISIBLE,visible);    FLAG(LINKED,linked);    FLAG(PRESERVE_TRANSPARENCY,preserve_transparency);    FLAG(APPLY_MASK,apply_mask);
pike.git/lib/modules/_Image_XCF.pmod:201:    type = data->type;    width = data->width;    height = data->height;    decode_properties( data->properties );    image = decode_image_data( data->image_data, pa );    if(data->mask)    mask = LayerMask( data->mask, pa );    }   }    + //!   class GimpImage   {    int width;    int height;    int compression;    int type;    int tattoo_state;    float xres = 72.0;    float yres = 72.0;    int res_unit;
pike.git/lib/modules/_Image_XCF.pmod:224:    array(Channel) channels = ({}); // unspecified order, really    array(Guide) guides = ({});    array(Parasite) parasites = ({});    array(Path) paths = ({});       Layer active_layer;    Channel active_channel;    Channel selection;       -  static string read_point_bz1( string data, Path path ) +  protected string read_point_bz1( string data, Path path )    {    object p = PathPoint( );    int x, y; -  sscanf(data, "%4c%4c%4c%s", p->type, x, y); +  sscanf(data, "%4c%4c%4c%s", p->type, x, y, data);    SIGNED(x);    SIGNED(y);    p->x = (float)x;    p->y = (float)y;    return data;    }    -  static string read_point_bz2( string data, Path path ) +  protected string read_point_bz2( string data, Path path )    {    object p = PathPoint( ); -  sscanf(data, "%4c%4F%4F%s", p->type, p->x, p->y); +  sscanf(data, "%4c%4F%4F%s", p->type, p->x, p->y, data);    return data;    }    -  static string decode_one_path( string data, Path path ) +  protected string decode_one_path( string data, Path path )    {    int nlen, version, num_points;    sscanf(data, "%4c", nlen );    path->name = data[..nlen-2];    data = data[nlen..];    sscanf(data, "%4c%4c%4c%4c%4c",    path->locked, path->state, path->closed, num_points, version);    switch(version)    {    case 1:    while(num_points--)    data = read_point_bz1( data, path );    break;    case 2:    sscanf(data, "%4c%s", path->ptype, data );    while(num_points--)    data = read_point_bz2( data, path );    break;    case 3: -  sscanf(data, "%4%4cc%s", path->ptype, path->tattoo, data ); +  sscanf(data, "%4c%4c%s", path->ptype, path->tattoo, data );    while(num_points--)    data = read_point_bz2( data, path );    break;    default:    data ="";    }    return data;    }       array(Path) decode_paths( string data )
pike.git/lib/modules/_Image_XCF.pmod:342:    }    }       void create( mapping data )    {    type = data->type;    decode_properties( data->properties );    width = data->width;    height = data->height;    foreach(data->layers, mapping l ) -  layers += ({ Layer( l, this_object() ) }); +  layers += ({ Layer( l, this ) });    foreach(data->channels, mapping c ) -  channels += ({ Channel( c, this_object() ) }); +  channels += ({ Channel( c, this ) });    }   }       -  + //!   GimpImage __decode( string|mapping what )   {    if(stringp(what)) what = ___decode( what );    return GimpImage(what);   }    -  + //!   mapping decode_header( string|mapping|object(GimpImage) data )   {    if( !objectp(data) )    {    if( stringp( data ) ) data = ___decode( data );    data = GimpImage( data );    }    return ([    "type":"image/x-gimp-image",    "xsize":data->width,
pike.git/lib/modules/_Image_XCF.pmod:397:    case VALUE_MODE: return "value";    case SCREEN_MODE: return "screen";    case OVERLAY_MODE: return "overlay";       default:    werror("WARNING: XCF: Unsupported mode: "+mode+"\n");    return "normal";    }   }    + //!   array decode_layers( string|object|mapping what, mapping|void opts,    int|void concat )   {    if(!opts) opts = ([]);    int shrink = (opts->shrink_fact||1);       if(!objectp( what ) )    what = __decode( what );       array layers = ({});
pike.git/lib/modules/_Image_XCF.pmod:475:    lay->set_misc_value( "parasites", l->parasites );    lay->set_misc_value( "visible", l->flags->visible );    if( l == l->parent->active_layer )    lay->set_misc_value( "active", 1 );    }    }       return layers;   }    + //!   mapping _decode( string|mapping|object(GimpImage) what, mapping|void opts )   {    if(!opts) opts = ([]);    GimpImage data;    if( objectp( what ) )    data = what;    else    data = __decode( what );    what = 0;   
pike.git/lib/modules/_Image_XCF.pmod:589:    alpha->line( x2,y1,x2,y2 );    alpha->line( x2,y2,x1,y2 );    alpha->line( x1,y2,x1,y1 );    }    }    }   // Array.map( data->layers, lambda(object o) { destruct(o); } );   // destruct( data );    return    ([ +  "type":"image/x-gimp-image",    "image":img,    "alpha":alpha,    ]);   }    -  + //! @decl Image.Image decode(string bytes, mapping|void options)   object decode( string what,mapping|void opts )   {    return _decode( what,opts )->image;   } -  +  + // --- Encoding +  + #if 0 +  + #define PROP(X,Y) sprintf("%4c%4c%s", PROP_##X, sizeof(Y), (Y)) + #define UINT(X) sprintf("%4c", (X)) + #define STRING(X) sprintf("%4c%s\0", sizeof(X)+1, (X)) +  + protected string make_hiearchy(Image.Image img) { +  string data = ""; +  data += UINT(img->xsize()); +  data += UINT(img->ysize()); +  data += UINT(3); // rgb +  +  // Make just one tile +  string i = (string)img; +  string tile = ""; +  tile += UINT(img->xsize()); +  tile += UINT(img->ysize()); +  tile += UINT(sizeof(i)); +  tile += i; +  +  data += UINT(sizeof(tile)); +  data += tile; +  return data; + } +  + protected int make_mode(string mode) { +  switch(mode) { +  case "normal": return NORMAL_MODE; +  } +  werror("Mode %O not supported in XCF.\n", mode); +  return NORMAL_MODE; + } +  + protected string make_layer(Image.Image|Image.Layer img) { +  string data = ""; +  data += UINT(img->xsize()); +  data += UINT(img->ysize()); +  data += UINT(1); // FIXME: layer type +  if(img->get_misc_value) +  data += STRING(img->get_misc_value("name")); +  else +  data += STRING(" "); +  +  // Layer properties +  { +  // ACTIVE_LAYER +  // SELECTION +  +  if(img->xoffset && img->yoffset) +  data += PROP(OFFSETS, UINT(img->xoffset()) + UINT(img->yoffset())); +  +  if(img->alpha_value) +  data += PROP(OPACITY, UINT(255*img->alpha_value())); +  else +  data += PROP(OPACITY, UINT(255)); +  +  data += PROP(VISIBLE, UINT(1)); +  +  // LINKED +  // PRESERVE_TRANSPARENCY +  // APPLY_MASK +  // EDIT_MASK +  // SHOW_MASK +  +  if(img->mode) +  data += PROP(MODE, UINT(make_mode(img->mode))); +  else +  data += PROP(MODE, UINT(NORMAL_MODE)); +  +  // TATTOO +  // PARASITES +  +  data += PROP(END, ""); +  } +  +  string h; +  if(img->image) +  h = make_hiearchy(img->image()); +  else +  h = make_hiearchy(img); +  string lm = ""; // make_layer_mask +  +  data += UINT(sizeof(h)); // hiearchy size +  data += UINT(sizeof(lm)); // layer mask size +  +  data += lm; +  data += h; +  +  return data; + } +  + string encode(Image.Image img) { +  String.Buffer buf = String.Buffer(); +  buf->add("gimp xcf file\0"); +  +  // width, height, type +  buf->add( sprintf("%4c%4c%4c", img->xsize(), img->ysize(), 0) ); +  +  // Properties +  +  // PROP_COLORMAP +  // PROP_GUIDES +  // PROP_RESOLUTION +  // PROP_TATTOO +  // PROP_PARASITES +  // PROP_UNIT +  // PROP_PATHS +  // PROP_USER_UNIT +  +  buf->add( PROP(COMPRESSION, UINT(0)) ); +  buf->add( PROP(END,"") ); +  +  // Layers +  if(objectp(img)) { +  string lay = make_layer(img); +  buf->add( UINT(sizeof(lay)) ); +  buf->add(lay); +  } +  // foreach(indices(layers), Image.Layer layer) { +  // } +  buf->add( UINT(0) ); +  +  // Channels +  buf->add( UINT(0) ); +  +  return (string)buf; + } +  + #endif