1 #ifndef __GEGL_BUFFER_INDEX_H 2 #define __GEGL_BUFFER_INDEX_H 3 /* File format building blocks 4 5 GeglBuffer on disk representation 6 ================================= 7 8 */ 9 10 11 /* Increase this number when the structures change.*/ 12 #define GEGL_FILE_SPEC_REV 0 13 #define GEGL_MAGIC {'G','E','G','L'} 14 15 #define GEGL_FLAG_TILE 1 16 #define GEGL_FLAG_FREE_TILE 0xf+2 17 18 /* a VOID message, indicating that the specified tile has been rewritten */ 19 #define GEGL_FLAG_INVALIDATED 2 20 21 /* these flags are used for the header, the lower bits of the 22 * header store the revision 23 */ 24 #define GEGL_FLAG_LOCKED (1<<(8+0)) 25 #define GEGL_FLAG_FLUSHED (1<<(8+1)) 26 #define GEGL_FLAG_IS_HEADER (1<<(8+3)) 27 28 /* The default header we expect to see on a file is that it is 29 * flushed, and has the revision the file conforms to written 30 * to it. 31 */ 32 #define GEGL_FLAG_HEADER (GEGL_FLAG_FLUSHED |\ 33 GEGL_FLAG_IS_HEADER|\ 34 GEGL_FILE_SPEC_REV) 35 36 /* 37 * This header is the first 256 bytes of the GEGL buffer. 38 */ 39 typedef struct { 40 gchar magic[4]; /* - a 4 byte identifier */ 41 guint32 flags; /* the header flags is used to encode state and revision 42 */ 43 guint64 next; /* offset to first GeglBufferBlock */ 44 45 guint32 tile_width; 46 guint32 tile_height; 47 guint16 bytes_per_pixel; 48 49 gchar description[64]; /* GEGL stores the string of the babl format 50 * here, as well as after the \0 a debug string 51 * describing the buffer. 52 */ 53 54 /* the ROI could come as a separate block */ 55 gint32 x; /* indication of bounding box for tiles stored. */ 56 gint32 y; /* this isn't really needed as each GeglBuffer as */ 57 guint32 width; /* represented on disk doesn't really have any */ 58 guint32 height; /* dimension restriction. */ 59 60 guint32 rev; /* if it changes on disk it means the index has changed */ 61 62 gint32 padding[36]; /* Pad the structure to be 256 bytes long */ 63 } GeglBufferHeader; 64 65 /* the revision of the format is stored in the flags of the header in the 66 * lower 8 bits 67 */ 68 #define gegl_buffer_header_get_rev(header) (((GeglBufferHeader*)(header))->flags&0xff) 69 70 /* The GeglBuffer index is written to the file as a linked list of 71 * GeglBufferBlock's, each block encodes it's own length and the offset 72 * of the file which the next block can be found. The last block in the 73 * list has the next offset set to 0. 74 */ 75 76 typedef struct { 77 guint32 length; /* the length of this block */ 78 guint32 flags; /* flags (can be used to handle different block types 79 * differently 80 */ 81 guint64 next; /*next block element in file, this is the offset in the 82 *file that the next block in the chain resides at 83 */ 84 } GeglBufferBlock; 85 86 /* The header is followed by entries describing tiles stored in the swap, 87 */ 88 typedef struct { 89 GeglBufferBlock block; /* The block definition for this tile entry */ 90 guint64 offset; /* offset into file for this tile */ 91 gint32 x; /* upperleft of tile % tile_width coordinates */ 92 gint32 y; 93 94 gint32 z; /* mipmap subdivision level of tile (0=100%) */ 95 96 guint32 rev; /* revision, if a buffer is monitored for header 97 revision changes, the existing loaded index 98 can be compare the revision of tiles and update 99 own state when revision differs. */ 100 } GeglBufferTile; 101 102 /* A convenience union to allow quick and simple casting */ 103 typedef union { 104 guint32 length; 105 GeglBufferBlock block; 106 GeglBufferHeader header; 107 GeglBufferTile tile; 108 } GeglBufferItem; 109 110 /* functions to initialize data structures */ 111 GeglBufferTile * gegl_tile_entry_new (gint x, 112 gint y, 113 gint z); 114 115 /* intializing the header causes the format to be written out 116 * as well as a hidden comment after the zero terminated format 117 * with additional human readable version of information from the header. 118 */ 119 void gegl_buffer_header_init (GeglBufferHeader *header, 120 gint tile_width, 121 gint tile_height, 122 gint bpp, 123 const Babl* format); 124 125 void gegl_tile_entry_destroy (GeglBufferTile *entry); 126 127 GeglBufferItem *gegl_buffer_read_header(int i, 128 goffset *offset); 129 GList *gegl_buffer_read_index (int i, 130 goffset *offset); 131 132 #define struct_check_padding(type, size) \ 133 if (sizeof (type) != size) \ 134 {\ 135 g_warning ("%s %s is %i bytes, should be %i padding is off by: %i bytes %i ints", G_STRFUNC, #type,\ 136 (int) sizeof (type),\ 137 size,\ 138 (int) sizeof (type) - size,\ 139 (int)(sizeof (type) - size) / 4);\ 140 return;\ 141 } 142 #define GEGL_BUFFER_STRUCT_CHECK_PADDING \ 143 {struct_check_padding (GeglBufferBlock, 16);\ 144 struct_check_padding (GeglBufferHeader, 256);} 145 #define GEGL_BUFFER_SANITY {static gboolean done=FALSE;if(!done){GEGL_BUFFER_STRUCT_CHECK_PADDING;done=TRUE;}} 146 147 #endif 148