Re: Inlining pixbufs



On 24 Jun 2000, Havoc Pennington wrote:

> 
> Tim Janik <timj@gtk.org> writes:
> > > You're still saving an array, right, just a compressed one?
> > 
> > nope, i'm using a string, that should be evident from the changelog
> > entries.
> >
> 
> I see a const guint8*, that looks like an array to me? (I suppose a
> string and an array are the same thing... you are just saying you're
> using a string literal I suppose) 

guint8 and guchar are the same thing for the architectures we care about.
yes, i'm saving the pixel data as a C source string for the reasons 
already outlined.

> > struct _BsePixdata
> > {
> >   BsePixdataType type : 8;
> >   guint          width : 12;
> >   guint          height : 12;
> >   const guint8  *encoded_pix_data;
> > };
> > 
> 
> OK, basically Owen suggested the following:
>  
> static const guchar apple_red [] =
> {
>   /* File magic (decimal: 1804289383) */
>   0x6b, 0x8b, 0x45, 0x67,
>   /* Rowstride (decimal: 192) */
>   0x00, 0x00, 0x00, 0xc0,
>   /* Width (decimal: 48) */
>   0x00, 0x00, 0x00, 0x30,
>   /* Height (decimal: 48) */
>   0x00, 0x00, 0x00, 0x30,
>   /* Has an alpha channel (TRUE) */
>   0x01,
>   /* Colorspace (0 == RGB, no other options implemented) (decimal: 0) */
>   0x00, 0x00, 0x00, 0x00,
>   /* Number of channels (decimal: 4) */
>   0x00, 0x00, 0x00, 0x04,
>   /* Bits per sample (decimal: 8) */
>   0x00, 0x00, 0x00, 0x08,
>   /* Image data */
>   0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
>   0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
>   0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
>   0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,

1) what's that magic steaming from?
2) why do we need a rowstride here? we don't have a length field and
   are talking about transporting one frame, so i don't see a need for
   that (and it defeats things like RLE)
3) why have has_alpha, colorspace and n_channels? that's better encoded
   in one 4 byte type field with an open flag convention (i.e. with something
   like the enum BsePixdataType i use)
4) how are bit sizes other than 8 handled, especially wrg to packing non
   powers of two?

> i.e. encode everything in a single stream of bytes. The encoded magic
> at the start of the stream is in network order, so the byte stream is
> architecture-independent, and theoretically you could dump it to and
> from a file. Also it's conceivable to load the C source as you would
> an XPM. The image data is just in RGBA order of course.

i think it's be better to define a 4 byte type field that also leaves
room for enhancements like RLE:

typedef enum                    /*< skip >*/
{
  GDK_PIXDATA_COLORSPACE_RGB    = 0x0001,
  GDK_PIXDATA_COLORSPACE_RGBA   = 0x0002,
  GDK_PIXDATA_COLORSPACE_MASK   = 0x0007,
  GDK_PIXDATA_SAMPLESIZE_8	= 0x0010,
  GDK_PIXDATA_SAMPLESIZE_16	= 0x0020, /* if we want this later on */
  GDK_PIXDATA_SAMPLESIZE_MASK   = 0x0070,
  GDK_PIXDATA_ENCODING_RLE_1B   = 0x0100,
  GDK_PIXDATA_ENCODING_MASK     = 0x0700,
  GDK_PIXDATA_MEMTYPE_STATIC    = 0x1000,
  GDK_PIXDATA_MEMTYPE_MASK      = 0x7000
} GdkPixdataType;

as byte stream:

guint8 selection_data[] =
{
  /* File magic ('G', 'd', 'k', 'P', 'i', 'x', 'd', '1') */
  0x47, 0x64, 0x6b, 0x50, 0x69, 0x78, 0x64, 0x31,
  /* GdkPixdataType (GDK_PIXDATA_COLORSPACE_RGBA |
   *                 GDK_PIXDATA_SAMPLESIZE_8 |
   *                 GDK_PIXDATA_ENCODING_RLE_1B)
   */
  0x00, 0x00, 0x01, 0x12,
  /* Width (decimal: 48) */
  0x00, 0x00, 0x00, 0x30,
  /* Height (decimal: 48) */
  0x00, 0x00, 0x00, 0x30,
  /* pixel data stream */
  0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
  0x8e, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x46, 0x44, 0x7b, 0x83,
  ...
};

and for C source inlining:

struct GdkPixdata {
  guchar         magic[8];
  GdkPixdataType type;   /* from stream: g_ntohl() */
  guint          width;  /* from stream: g_ntohl() */
  guint          height; /* from stream: g_ntohl() */
  guint8        *pixdata;
} organ_pixdata = {
  "GdkPixd1",
  (GDK_PIXDATA_COLORSPACE_RGBA |
   GDK_PIXDATA_SAMPLESIZE_8 |
   GDK_PIXDATA_ENCODING_RLE_1B),
  48,
  48,
  "\377\0\0\0\0\377\0\0\0\0\216\0\0\0\0\12FD{\200RN\203\277\\X\211\377fb\220"
  "\377ql\230\377|v\236\377\206\200\246\377\221\210\254\377\233\222\263\277\246"
  "\234\273\200\265\0\0\0\0\16""10l\200<:t\377FD{\377QN\202\377\\X\211\377fb"
  ...
};

with GdkPixdataType at hand, your application code (the receiving code) can
figure whether it supports that exact format, and we have all available options
written out. if we later change the format, use another magic, e.g.
"GdkPixd2" or something, and untill then the structure is extensible.

API wise, we should have:
 
  /* generate Pixbuf from C source saved structure */
  GdkPixbuf* gdk_pixbuf_new_from_pixdata (const GdkPixdata *pixdata);
  
  /* generate Pixbuf from byte stream, ignores GDK_PIXDATA_MEMTYPE_STATIC */
  GdkPixbuf* gdk_pixbuf_new_from_stream  (const guint8 *pixdata_stream);

(the functions would share the same decoder backend of course)

> > something similar probably wouldn't be a bad idea for gdk_pixbuf, we
> > can easily have a PixdataType flag that would indicate sharing of
> > of static uncompressed data. and that interface is extensible for
> > future refinements, such as more complicated compression algorithms
> > for instance.
> >
> 
> Agreed, I think the issue is just whether you want the struct or you
> want to encode it in the byte stream. The byte stream has some
> advantages, for example you could use it as a GtkSelectionData for
> drag and drop, this is a feature that Qt has.

i do think we should have both, the transition is straight forward.

> > you didn't look at bse_icon_from_pixdata() or CSource, right? all
> > that logic is already there ;)
> >
> 
> I saw it, yes. I see this morning that it's easier than I thought to
> yank that code into my code, so I'll look at doing so.
> 
> Havoc
> 

---
ciaoTJ






[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]