Bank/Peek/Poke
Blitz3D Forums/Blitz3D Beginners Area/Bank/Peek/Poke
| ||
The fllowing example highlights the issue better than Ican explain it. I am uncertain how to ensure the CORRECT SIZE of the new 'compressed' bank. Local n=128 Local TestBank=CreateBank(n) ;Fill testexample For X=0 To n-1 PokeByte TestBank,x,Rand(0,7) Next ; This should resutl in a new bank 3:8 size ratio - but for some reason, the size Max*0.375 is not correct. Local Shrink=ShrinkBank(TestBank) Function ShrinkBank(BigBank) Local Max=BankSize(BigBank) Local ShrinkSize=Max*0.375 Local Bank=CreateBank(ShrinkSize);Shrink to 3 bits instead of 8 bits Local BigBytes Local BigByteBits Local IterBigByte Local Word Local WordBits Local SmallByte Local SmallShort Local SmallOffset For BigBytes =0 To Max-1 Step 7 DebugLog("Compressing bytes "+Str(BigBytes)+" - "+Str(BigBytes+7)+" of "+Str(Max-1)) Word=0 For IterBigByte=0 To 7 BigByteBits=(PeekByte(BigBank,BigBytes+IterBigByte) And 7) WordBits=BigByteBits Shl (IterBigByte*3) Word=Word+WordBits Next SmallByte=Word And 255 SmallShort=(Word Shr 8)And 65535 PokeByte Bank,SmallOffset,SmallByte PokeShort Bank,SmallOffset+1,SmallShort DebugLog("Compressed to new Bytes "+Str(SmallOffset)+" - "+Str(SmallOffset+2)+" of "+Str(ShrinkSize-1)) SmallOffset=SmallOffset+3 Next Return Bank End Function |
| ||
Ignore this. I found my mistake. Such a silly thing, too - For BigBytes =0 To Max-1 Step 7 Should read For BigBytes =0 To Max-1 Step 8 ______________________________________________________________ Whilst this is quite specific as it stands, the actual concept: Compressing A*8 bytes where only the first B bits of each byte is used into BA/8 bytes May be of benefit for others. |
| ||
[obsolete post] |
| ||
I never once suggested whatsoever this was a general case. It is, as I mentioned clearly "this is quite specific as it stands" for when A=8n and B=3 Obviously it will not work when the compressed bits overflow an 8bit byte. Perhaps I should have clarified that the values MUST be integral. This includes the BA/8 compressed size. Yes it could be modified to include appended "padding" bits as well as cases where different (but consistent per function call) numbers of relevant bits are used to be compressed to related sizes of bytes. I have neither care nor interest in doing so, but you're welcome to develop further should you wish. This was not my intention, and is of no interest nor use to me. This was code for a specific purpose in which a bank of size in which only the first 3 bits were relevant and therefore the information content could be preserved losslessly into a bank of ratio 3:8 the size. That was all. I only posted the function due to the bug mentioned and subsequently addressed in my second post. On identifying the bug, I deemed it may be interesting to some to see the function. I am puzzled as to why you would think it would work with a value of A=1.25 knowing that 3.75 is NOT an integer nor a valid size for a bank. or even why you would NOT include the fix given the very reason for posting in the first place was because without the fix mentioned, the vfunction failed. __ "[ I'll be back later to take a closer look at your project. ] " What on earth is this supposed to mean? What project, and who the helldo you think you are? Do I presume to oversee or inspect every effort of coding you make? What makes you think I have need nor desirte for your scrutiny of anything I work on? Where exactly do you hope to gain knowledge of my projects or work from? |
| ||
[obsolete post] ![]() ![]() |
| ||
relax guys, we may disagree on some things and sometimes post critics of others codes/creations, but there is no need to be angry, we are all here to learn and become better coders/developers... |
| ||
I have no issue with criticising my code, I have no real formal education in coding and so must expect significant areas in which improvements can be made and welcome constructive suggestions. This is why I frequently post here with problems. I do not, however, welcome other users self-appointing their right to consider themselves arbiters and auditors of work and employ some form of inspection scrutiny whether requested or otherwise with such ridiculous and outright rude commentary as "I'll be back later to take a closer look at your project". ___ The code above is itself a further development (albeit used for a different purpose for a separate project) along a similar notion of lossless compression from an earlier concept relating to compression specific text. Despite the specifics of text and limtiations on available characters, the original concept did allow a little more versatility and generality of use. I have reproduced a sample blow which contains an example and some information on how it can be adapated for more general usage. ; This can be changed to 16 for SHORT Int or 32 for LONG Int, if the string length is known, this may speed up the process by dealing with more characters at one time. In which case, Remember to change Read/Write Byte to Read/Write Short or Int as required below. Const BYTESIZE=8 ;Identifies the distinct characters Global CHARSET$="ABCDEFGHIJKLMNOPRSTUVWXYZ. ,'!?" ;Identifies the number of distinct characters ; (saves time to store in one var rather than call Len() each time Global POSSIBLECHARS=Len(CHARSET) ;This calculates the maximum number of BITS required to represent any of the available Chars. Essentially this is the limit of compression. Global BITS_PER_CHAR=Log(POSSIBLECHARS)/Log(2) ; Yet again, this saves time to calculate and sotr beforehand, rather than call the logarithm function each time. ;Example:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: Local FileOut=WriteFile("TestFile.dat") SetStringToBitStream(FileOut,"THIS IS A TEST! OK, YOU'RE SURE?") CloseFile FileOut Local FileIn=ReadFile("TestFile.dat") Local Name$=GetStringFromBitStream(FileIn) CloseFile FileIn WaitKey() End Function GetStringFromBitStream$(Stream) Local NAME_LENGTH=ReadByte(Stream) Local Byte Local Iter Local CharacterBit Local Bit Local ByteBit Local ByteBitValue Local CharBitValue Local CurrentChar Local Char$ Local Name$ Local MaximumByteBits=((BITS_PER_CHAR*NAME_LENGTH)-BYTESIZE) Byte=ReadByte(Stream) For Bit=0 To BITS_PER_CHAR*NAME_LENGTH ByteBit=Bit Mod BYTESIZE CharacterBit=Bit Mod BITS_PER_CHAR ByteBitValue=(2^ByteBit) Mod (2^BYTESIZE) CharBitValue=(2^CharacterBit) Mod NAME_LENGTH If (Byte And ByteBitValue) CurrentChar=CurrentChar+CharBitValue End If If (CharacterBit=BITS_PER_CHAR-1) Char=Mid(CHARSET,CurrentChar+1,1) CurrentChar=0 Name=Name+Char End If If ((ByteBit=BYTESIZE-1) And (Bit<MaximumByteBits)) Byte=ReadByte(Stream) End If Next Return Trim(Name) End Function Function SetStringToBitStream(Stream,Name$) Local NAME_LENGTH=Len(Name) WriteByte Stream,NAME_LENGTH Local Bit Local Char$ Local Byte Local Character Local CharBit Local CharBitValue Local ByteBit Local ByteBitValue Local CharCount For CharCount=1 To NAME_LENGTH Char=Mid(Name,CharCount,1) Character=Instr(CHARSET,Char)-1 If (Character<0) RuntimeError "Invalid Character "+Char End If For CharBit=0 To BITS_PER_CHAR-1 CharBitValue=(2^CharBit) Mod POSSIBLECHARS ByteBitValue=(2^ByteBit) Mod (2^BYTESIZE) If (Character And CharBitValue) Byte=Byte+ByteBitValue End If Bit=Bit+1 ByteBit=Bit Mod BYTESIZE If (Not(ByteBit)) WriteByte Stream,Byte Byte=0 End If Next Next End Function |
| ||
![]() |
| ||
I don't really understand the reason of the clash either, but apparently some steam had to go out and you were the one to take it ;) |
| ||
""[ I'll be back later to take a closer look at your project. ] "" This irks me. My project is nobody else's business. I'm not even sure HOW virtlands intends to gain access to look at such work. It's patently rude to assume he can simply stroll along and scrutinise someone else's work and that's not even a consideration of WHY. BHy what authority does he seek to appoint himself the one to "look closely" at my projects? He's acting like some nosey schoolteacher hovering over a students' desk - and for what reason? _ Again, I have no problem with criticism and constructive comments of code I post here, but that line quoted is neither. |
| ||
... ![]() ![]() |
| ||
... Visual output ? ![]() |
| ||
... ... Please put some visual output into your program, so that we have some clue what it is doing: There's an example included which provides visual output. That being the file written to the relative location. Local FileOut=WriteFile("TestFile.dat") SetStringToBitStream(FileOut,"THIS IS A TEST! OK, YOU'RE SURE?") CloseFile FileOut Local FileIn=ReadFile("TestFile.dat") Local Name$=GetStringFromBitStream(FileIn) CloseFile FileIn WaitKey() End It's not at all complex. It's actually very very basic. Consider a bank of code (or a string) as a sequence of bytes: ABYTE|BBYTE|CBYTE|DBYTE|EBYTE... etc. These bytes can be themselves considered as built up from bits. ABCDEFGH|ABCDEFHG|ABCDEFGH|ABCDEFGH|ABCDEFGH However, if the RELEVANT INFORMATION of each byte may be represented in terms of just 5 bits, then the INFORMATION CONTENT is equivalent with: ABCDE000|ABCDE000|ABCDE000|ABCDE000|ABCDE000... the 000 representing "junk" or "padding" bits which are really just wasted space. Therefore, it is possible to compress the space by removing the junk bits and pulling the bits along from the next bytes in sequence to fill the gaps. ABCDEABC|DEABCDEA|BCDEABCD|E... So what did take up 5 bytes now takes up just over 3. Naturally, there are some pitfalls and an amount of care must be taken to customise the routines SPECIFICALLY FOR THE CASE IN WHICH THEY ARE TO BE USED - once again, this is NOT A GENERAL SOLUTION. The only remotely complex aspect is how to identify the individual 'nibblets' of information and their position relative to the actual bytes. (i.e. in the example here, in the SECOND byte, from the 3rd BIT of that byte: "ABCDE") --- or that there may be a mismatch at the end (i.e. single bit E with a requirement for at least 7 padding bits. It can be thought of as temporarily considering a different BIT-DEPTH for the memory, where that BIT DEPTH is not restricted to multiples of 4 or 8. __ I have included comments and used descriptive variable/method names to identify the key areas of the code. Were I intending this to be something I offer to the Blitzcommunity as solution and include support thereof, I would post in the ocde archives. As it happens, this thread was due to requesting help with the bug in the code which is now fixed and therefore the thread may be disregarded. _______________________________________________________________________ At heart, this was all for the purposes of compressing data sizes for load/save to disk or more critically, network communication (with a view to packet sizes obviously necessitating the offset against time taken to process), so there's very little that has any impact or relevance in visual display terms. |
| ||
Then here. This shows visually that as the bytes are processed from the big bank, the compressed bank is formed much smaller. Really do not see what benefit this brings whatseover, but since you asked for it, hope it helps... ;EXAMPLE WITH VISUAL OUTPUT FOR VIRTLANDS - NOT SURE WHAT PURPOSE IT SERVES SINCE THIS IS NOT SUPPOSED TO BE A VISUAL PROCESS WHATSOEVER Graphics 1024,768,32,2 Const VO_BIG_X=32 Const VO_BIG_Y=32 Const VO_SMALL_X=32 Const VO_SMALL_Y=64 Const VO_BYTE_GRAPHIC_BLOCK=4 Local n=128 Local TestBank=CreateBank(n) ;Fill testexample For X=0 To n-1 PokeByte TestBank,x,Rand(0,7) Next Local Shrink=ShrinkBank(TestBank) WaitKey() End Function ShrinkBank(BigBank) Local Max=BankSize(BigBank) Local ShrinkSize=Max*0.375 Local Bank=CreateBank(ShrinkSize);Shrink to 3 bits instead of 8 bits Local BigBytes Local BigByteBits Local IterBigByte Local Word Local WordBits Local SmallByte Local SmallShort Local SmallOffset For BigBytes =0 To Max-1 Step 8 Word=0 For IterBigByte=0 To 7 BigByteBits=(PeekByte(BigBank,BigBytes+IterBigByte) And 7) WordBits=BigByteBits Shl (IterBigByte*3) Word=Word+WordBits DrawOutput(BigBytes+IterBigByte,SmallOffset,Max-1,ShrinkSize) Next SmallByte=Word And 255 SmallShort=(Word Shr 8)And 65535 PokeByte Bank,SmallOffset,SmallByte PokeShort Bank,SmallOffset+1,SmallShort SmallOffset=SmallOffset+3 DrawOutput(BigBytes+IterBigByte,SmallOffset,Max-1,ShrinkSize) Next DrawOutput(BigBytes+IterBigByte,SmallOffset,Max-1,ShrinkSize) Return Bank End Function Function DrawOutput(Offset,SmallOffset,BB,SB) Cls Local X ;Labels Color 255,255,255 Text VO_BIG_X,VO_BIG_Y-12,"Padded data progress: %"+Str(Int(Float(Offset*100)/BB)) Text VO_SMALL_X,VO_SMALL_Y-12,"Compressed bank size: "+Str(SmallOffset+3)+" bytes" ;BuildGrids Color 255,0,0 For X=0 To BB-1 Rect VO_BIG_X+(X*VO_BYTE_GRAPHIC_BLOCK),VO_BIG_Y,VO_BYTE_GRAPHIC_BLOCK,VO_BYTE_GRAPHIC_BLOCK,False Next ; For X=0 To SB ; Rect VO_SMALL_X+(X*VO_BYTE_GRAPHIC_BLOCK),VO_SMALL_Y,VO_BYTE_GRAPHIC_BLOCK,VO_BYTE_GRAPHIC_BLOCK,False ; Next ;ShowProgress Color 0,255,0 ;Normal Rect VO_BIG_X,VO_BIG_Y,Offset*VO_BYTE_GRAPHIC_BLOCK,VO_BYTE_GRAPHIC_BLOCK,True ;Compressed Rect VO_SMALL_X,VO_SMALL_Y,SmallOffset*VO_BYTE_GRAPHIC_BLOCK,VO_BYTE_GRAPHIC_BLOCK,True Flip True End Function |