1 #ifndef ASSTORAGE_H_HEADER_INCLUDED
2 #define ASSTORAGE_H_HEADER_INCLUDED
3 
4 
5 #define AS_STORAGE_PAGE_SIZE		4096
6 
7 /*
8  *	there could be up to 16 arrays of 1024 pointers to slots each in Storage Block
9  *	There could be 2^18 StorageBlocks in ASStorage
10  */
11 #define AS_STORAGE_SLOTS_BATCH		1024  /* we allocate pointers to slots in batches of one page eache  */
12 #define AS_STORAGE_SLOT_ID_BITS		14  /* 32*512 == 2^14 */
13 #define AS_STORAGE_MAX_SLOTS_CNT	(0x01<<AS_STORAGE_SLOT_ID_BITS)
14 
15 #define AS_STORAGE_BLOCK_ID_BITS	(32-AS_STORAGE_SLOT_ID_BITS)
16 #define AS_STORAGE_MAX_BLOCK_CNT   	(0x01<<AS_STORAGE_BLOCK_ID_BITS)
17 /* #define AS_STORAGE_DEF_BLOCK_SIZE	(1024*256)  */
18 #define AS_STORAGE_DEF_BLOCK_SIZE	(1024*128)  /* 128 Kb */
19 #define AS_STORAGE_NOUSE_THRESHOLD	(1024*8)  /* 8 Kb if total_free < 8K we should not try and use that
20 											   *  block as we may fall into trap constantly defragmenting it
21 											   *  so we prefer to leave memory unused since 2 pages is not too much to loose */
22 
23 
24 #define ASStorageSlot_SIZE 16 /* 16 bytes */
25 #define ASStorageSlot_USABLE_SIZE(slot) (((slot)->size+15)&0x8FFFFFF0)
26 #define ASStorageSlot_FULL_SIZE(slot) (ASStorageSlot_USABLE_SIZE(slot)+ASStorageSlot_SIZE)
27 /* space for slots is allocated in 16 byte increments */
28 #define AS_STORAGE_GetNextSlot(slot) ((slot)+1+(ASStorageSlot_USABLE_SIZE(slot)>>4))
29 
30 
31 /* RLE encoding of difference
32  * We calculate difference between following bytes. If differece is zero - its RLE encoded.
33  * If its +-1 - its encoded as 2 bit values
34  * If Its +-(from 2 to 7) - its encoded using 4 bit values
35  * If Its +-(from 8 to 127) - its encoded using 8 bit values
36  * If Its +-(from 128 to 255) - its encoded using 9 bit values
37  *
38  * The hope is that most of the bytes will be reduced to 0
39  * The next likely value will be from 2 to 7
40  * and only few cases will fall in other categories
41  *
42  * For bitmaps we store lengths of ones and zerous, assuming that each string tsarts with 0
43  *
44  * */
45 
46 /* The following lines is used only for non-bitmaps : */
47 #define RLE_ZERO_MASK				0x0080  /* M        */
48 #define RLE_ZERO_LENGTH				0x007F  /*  LLLLLLL */
49 #define RLE_ZERO_SIG				0x0000  /* 0LLLLLLL - identical to a string of LLLLLLL zeros */
50 
51 #define RLE_NOZERO_SHORT_MASK		0x00C0  /* MM       */
52 #define RLE_NOZERO_SHORT_LENGTH		0x003F  /*   LLLLLL */
53 #define RLE_NOZERO_SHORT_SIG		0x00C0  /* 11LLLLLL followed by stream of LLLLLL 4 or 2 bit values */
54 
55 #define RLE_NOZERO_LONG_MASK		0x00F0  /* MMMM     */
56 #define RLE_NOZERO_LONG_LENGTH		0x000F  /*     LLLL */
57 #define RLE_NOZERO_LONG1_SIG		0x00A0  /* 1010LLLL followed by stream of LLLL 2 or 4 bit values */
58 #define RLE_NOZERO_LONG2_SIG		0x00B0  /* 1011LLLL followed by stream of LLLL 1 byte values */
59 
60 #define RLE_9BIT_SIG				0x0080  /* 1000LLLL followed by stream of LLLL 1 byte values
61                                                that change sign from byte to byte starting with positive */
62 #define RLE_9BIT_NEG_SIG	  		0x0090  /* 1001LLLL followed by stream of LLLL 1 byte values
63                                                that change sign from byte to byte starting with negative */
64 
65 #define AS_STORAGE_DEFAULT_BMAP_THRESHOLD 0x7F
66 #define AS_STORAGE_DEFAULT_BMAP_VALUE	  0xFF
67 
68 
69 typedef struct ASStorageSlot
70 {
71 /* Pointer to ASStorageSlot is the pointer to used memory beginning - ASStorageSlot_SIZE
72  * thus we need not to store it separately
73  */
74 #define ASStorage_ZlibCompress		(0x01<<0)  /* do we really want that ? */
75 #define ASStorage_RLEDiffCompress 	(0x01<<1)  /* RLE of difference */
76 
77 #define ASStorage_CompressionType	(0x0F<<0)  /* allow for 16 compression schemes */
78 #define ASStorage_Used				(0x01<<4)
79 #define ASStorage_NotTileable		(0x01<<5)
80 #define ASStorage_Reference			(0x01<<6)  /* data is the id of some other slot */
81 #define ASStorage_Bitmap			(0x01<<7)  /* data is 1 bpp */
82 #define ASStorage_32Bit				(0x01<<8)  /* data is 32 bpp with only first 8 bits being significant */
83 #define ASStorage_BitShiftFlagPos   9
84 #define ASStorage_BitShift			(0x03<<ASStorage_BitShiftFlagPos)
85 #define ASStorage_8BitShift			(0x01<<ASStorage_BitShiftFlagPos)
86 												/* data is 32 bpp shifted left by 8 bit
87 												 * (must combine with _32Bit flag )*/
88 #define ASStorage_16BitShift		(0x01<<(ASStorage_BitShiftFlagPos+1))
89 												/* data is 32 bpp shifted left by 16 bit
90 												* (must combine with _32Bit flag )
91 												* If combined with 8BitShift - results in 24 bit shift */
92 #define ASStorage_24BitShift		(ASStorage_8BitShift|ASStorage_16BitShift)
93 #define ASStorage_Flags2ShiftIdx(f) (((f)>>ASStorage_BitShiftFlagPos)&0x03)
94 #define ASStorage_Flags2Shift(f) 	(ASStorage_Flags2ShiftIdx(f)*8)
95 #define ASStorage_Masked			(0x01<<11) /* mask 32bit value to filter out higher 24 bits
96                                                 * if combined with BitShift - bitshift is done
97 												* prior to masking */
98 
99 
100 #define ASStorage_32BitRLE			(ASStorage_RLEDiffCompress|ASStorage_32Bit)
101 
102 	CARD16  flags ;
103 	CARD16  ref_count ;
104 	CARD32  size ;
105 	CARD32  uncompressed_size ;
106 	CARD16  index ;  /* reverse mapping of slot address into index in array */
107 	/* slots may be placed in array pointing into different areas of the memory
108 	 * block, since we will need to implement some sort of garbadge collection and
109 	 * defragmentation mechanism - we need to be able to process them in orderly
110 	 * fashion.
111 	 * So finally :
112 	 * 1) slot's index does not specify where in the memory slot
113 	 * is located, it is only used to address slot from outside.
114 	 * 2) Using slots memory address and its size we can go through the chain of slots
115 	 * and perform all the maintenance tasks  as long as we have reverse mapping
116 	 * of addresses into indexes.
117 	 *
118 	 */
119 	CARD16 reserved ;          /* to make us have size rounded by 16 bytes margin */
120 	/* Data immidiately follows here :
121 	 * CARD8   data[0] ; */
122 
123 #define ASStorage_Data(s)  ((CARD8*)((s)+1))
124 
125 }ASStorageSlot;
126 
127 /* turns out there is no performance gains from using int here instead of short -
128 so save some memory if we can : */
129 typedef short ASStorageDiff;
130 
131 
132 typedef void (*compute_diff_func_type)(ASStorageDiff*,CARD8*,int);
133 typedef int  (*copy_data32_func_type)(CARD8*,CARD32*,int);
134 typedef int  (*copy_data32_tinted_func_type)(CARD8*,CARD32*,int,CARD32);
135 
136 
137 typedef struct ASStorageBlock
138 {
139 #define ASStorage_MonoliticBlock		(0x01<<0) /* block consists of a single batch of storage */
140  	CARD32  flags ;
141 	int 	size ;
142 
143 	int   	total_free;
144 	ASStorageSlot  *start, *end;
145 	/* array of pointers to slots is allocated separately, so that we can reallocate it
146 	   in case we have lots of small slots */
147 	ASStorageSlot **slots;
148 	int slots_count, unused_count ;
149 	int first_free, last_used ;
150 	int long_searches ;
151 
152 }ASStorageBlock;
153 
154 typedef struct ASStorage
155 {
156 	int default_block_size ;
157 
158 
159 	ASStorageBlock **blocks ;
160 	int 			blocks_count;
161 
162 	ASStorageDiff  *diff_buf ;
163 	CARD8  *comp_buf ;
164 	size_t 	comp_buf_size ;
165 
166 }ASStorage;
167 
168 
169 typedef CARD32 ASStorageID ;
170 
171 ASStorageID store_data(ASStorage *storage, CARD8 *data, int size, ASFlagType flags, CARD8 bitmap_threshold);
172 ASStorageID store_data_tinted(ASStorage *storage, CARD8 *data, int size, ASFlagType flags, CARD16 tint);
173 
174 /* data will be fetched fromthe slot identified by id and placed into buffer.
175  * Data will be fetched from offset  and will count buf_size bytes if buf_size is greater then
176  * available data - data will be tiled to accomodate this size, unless NotTileable is set */
177 int  fetch_data(ASStorage *storage, ASStorageID id, CARD8 *buffer, int offset, int buf_size, CARD8 bitmap_value, int *original_size);
178 int  fetch_data32(ASStorage *storage, ASStorageID id, CARD32 *buffer, int offset, int buf_size, CARD8 bitmap_value, int *original_size);
179 int  threshold_stored_data(ASStorage *storage, ASStorageID id, unsigned int *runs, int width, unsigned int threshold);
180 
181 /* slot identified by id will be marked as unused */
182 void forget_data(ASStorage *storage, ASStorageID id);
183 
184 void print_storage(ASStorage *storage);
185 
186 int print_storage_slot(ASStorage *storage, ASStorageID id);
187 Bool query_storage_slot(ASStorage *storage, ASStorageID id, ASStorageSlot *dst );
188 
189 /* returns new ID without copying data. Data will be stored as copy-on-right.
190  * Reference count of the data will be increased. If optional dst_id is specified -
191  * its data will be erased, and it will point to the data of src_id:
192  */
193 ASStorageID dup_data(ASStorage *storage, ASStorageID src_id);
194 
195 /* this will provide access to default storage heap that is used whenever above functions get
196  * NULL passed as ASStorage parameter :
197  */
198 void flush_default_asstorage();
199 int set_asstorage_block_size( ASStorage *storage, int new_size );
200 
201 
202 #endif
203