Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

DarkBASIC Professional Discussion / Understanding Image Memblocks

Author
Message
Sph!nx
17
Years of Service
User Offline
Joined: 3rd Dec 2008
Location: The Netherlands
Posted: 19th Aug 2013 18:52 Edited at: 19th Aug 2013 18:56
Hello everybody,

I'm currently trying to understand memblocks and I have an idea of what it is; content fully loaded in memory, right? And that's where my knowledge ends.. im lost.

Let's say I have loaded an image of 100x100 pixels and would like to load it into memory, how would I do that?

Let's say I wish to extract a part of that image (10x10 px), from position x=30 and y = 20 from the image and make a new image from that smaller part. How would I do that?

I'm not asking you write my whole code, just a kick in the right direction. Here's what I've got so far:


Any help is much appreciated!

Regards Sph!nx
www.mental-image.net
Rudolpho
20
Years of Service
User Offline
Joined: 28th Dec 2005
Location: Sweden
Posted: 19th Aug 2013 19:43 Edited at: 19th Aug 2013 19:48
Yes, you are creating a memblock that will be filled out with the image data correctly there.

Image memblocks have a 12-byte header:


Assuming your image memblock is indeed 32-bits, each pixel follows thereafter as a DWORD colour. You have width x height pixels, hence the memory at byte offset 12 .. 12 + (width - 1) * 4 corresponds to the first line of pixels in your image data (12 is the size of the 3 header dwords; width, height and depth).
Functions for reading / writing individual pixels would thus look like so:



To then get a sub-image you would simply read the pixels at the desired positions and write them to another memory location (like another memblock, which you could then convert to an image).


Edit: you can not change the original memblock so that it contains only a sub-section of an image (or well, I suppose you might be able to if you set the width and height members of the header accordingly, but you will still have to store the original image intermediarily when building the "sub-image", so it would be easiest to just make a second memblock for this purpose; sample the desired pixels from the first one and write them to the second. Which you have set the header bytes of accordingly, or it won't work! Note that the second memblock here doesn't have to be created from an image but can (and should) be built from scratch).


"Why do programmers get Halloween and Christmas mixed up?"
Sph!nx
17
Years of Service
User Offline
Joined: 3rd Dec 2008
Location: The Netherlands
Posted: 19th Aug 2013 20:01
Wow, thanks a lot Rudolpho! I will study this carefully but probably have more questions later on. Like, how would I get the size of the new memblock, would this be the pixel count?

Regards Sph!nx
www.mental-image.net
Mage
Valued Member
19
Years of Service
User Offline
Joined: 3rd Feb 2007
Location:
Posted: 19th Aug 2013 21:48
Do not convert the memblock back into an image overtop of an existing image. The mipmaps will not properly update and the image if used as a texture will appear as the original image unless at an extremely close distance.

Always convert back using an unused or deleted image number.

Rudolpho
20
Years of Service
User Offline
Joined: 28th Dec 2005
Location: Sweden
Posted: 19th Aug 2013 23:16
Quote: "Like, how would I get the size of the new memblock, would this be the pixel count?"

Yes, the 12 bytes in the header plus the pixel count * byte depth (bit-depth / 8).


"Why do programmers get Halloween and Christmas mixed up?"
Sph!nx
17
Years of Service
User Offline
Joined: 3rd Dec 2008
Location: The Netherlands
Posted: 20th Aug 2013 14:04 Edited at: 20th Aug 2013 14:04
Thank Mage, that was what I intended to!

Rudolpho, thanks mate. How does this look so far?


I've added a for next loop for the process to copy the pixels. Still not sure how to copy that correctly though. I've studied the additional functions you supplied, but it still puzzles me.

Regards Sph!nx
www.mental-image.net
Rudolpho
20
Years of Service
User Offline
Joined: 28th Dec 2005
Location: Sweden
Posted: 20th Aug 2013 22:23 Edited at: 20th Aug 2013 22:24
No problem, glad to help.

Your new_mb there doesn't have enough room for 10x10 pixels; since each pixel uses 4 bytes you should multiply that part by 4 (so (4 * 10 * 10) + 12).

To copy the pixels from the source memblock it would be easiest to use two for-loops and step through the x and y coordinates for the (smaller) destination image much like you're doing there. I would let the loop go from 0 .. 9 instead of 1 to 10 since you will be accessing memory using offsets, which is much easier if you're thinking of it as zero-based.
The approach I used in the functions I posted earlier should work here too; you get the colour at the source position (which it seems is (idX + posX#, idY + posY#) for you assuming the above code), and then write it to (idX, idY) of the target memblock.
There is no need to increase the posX# / posY# values. Also they should be integers, not floats (I doubt it will matter in this case though; the errors won't be large enough to make the calculations wrong when casting them back to integers).

Here is a complete demo function with comments for copying a rectangular area of an image and creating a new image from that. I hope that will make it clearer as to how it all works together



"Why do programmers get Halloween and Christmas mixed up?"
Sph!nx
17
Years of Service
User Offline
Joined: 3rd Dec 2008
Location: The Netherlands
Posted: 20th Aug 2013 22:50 Edited at: 20th Aug 2013 22:51
You sir are awesome! Thanks!

It's much clearer now but had to read up a little on dword but could not find what you meant by 4 bytes in a dword.

In the documentation it says:
Quote: "DWORD Range : 0 to 4,294,967,295"

I can use the dword from your example, but what does it actually mean?

Regards Sph!nx
www.mental-image.net
Rudolpho
20
Years of Service
User Offline
Joined: 28th Dec 2005
Location: Sweden
Posted: 20th Aug 2013 23:06
Dword stands for double word (there are qwords as well, which are 4 words). Originally a word was the used to represent the number of bits that a certain processor makes use of (and it still is I guess). Therefore chances are a dword should really mean 4x32 or 4x64 bits most of the time when addressing a modern computer. For whatever reason the Windows API decided that a word is always 2 bytes however, and thus a dword is 4 bytes. The same naming is used in DBPro.

A 32-bit colour has 4 bytes; alpha, red, green and blue components. Thus it fits nicely in a dword.
You could just as well use an integer, but dwords are unsigned, which makes sense for colours. THE DBPro compiler will happily cast integers to dwords though so you might as well use it; if you change to a different language you may end up with colours that wrap around back to 0 after reaching 128 green or similar though, so to save the headaches then you might just as well always use unsigned datatypes when the data you're using is indeed supposed to be unsigned.

And in case you were wondering, 2^32 = 4 294 967 296, thus the range of 0 .. 4 294 967 295 for dwords. 2^16 = 65536, so the range of a word is 0 .. 65535, and so on.


"Why do programmers get Halloween and Christmas mixed up?"
Sph!nx
17
Years of Service
User Offline
Joined: 3rd Dec 2008
Location: The Netherlands
Posted: 20th Aug 2013 23:43
You are fast! Still trying to process this dword, integer stuff. I don't know how I've been coding the stuff I did all these years without understanding this basic memory stuff.

So, in n00b language, an dword is a line of numbers, stored in four sections separated by the comma?

Sorry for my n00bishness

Regards Sph!nx
www.mental-image.net
Rudolpho
20
Years of Service
User Offline
Joined: 28th Dec 2005
Location: Sweden
Posted: 21st Aug 2013 00:21
Quote: "So, in n00b language, an dword is a line of numbers, stored in four sections separated by the comma?"

Well, no.

Basically a DWORD is 4 bytes.
A byte consists of 8 bits.
Therefore, using all possible permutations the byte can store values %00000000 through %11111111 (where 0 is a unset bit and 1 is a set one). Since it has the base two, this corresponds to 2^8 = 256 different values.
In a WORD (2 bytes) you have 8 + 8 = 16 bits. Thus you can combine those in 2^16 = 65536 different ways, and thence that's how many different values a word can represent. Assuming it is unsigned (meaning it is always positive; negative values cannot be represented) it can be any value between 0 through 65535 (65536 can never be reached as it will wrap around to the bit combination representing 0 again).
The same goes for DWORDs; since you now have 4 bytes, that is 2^32 unique values (or 256^4 or 65536^2 if you prefer).
When used as a colour, each byte in the DWORD represents a channel (alpha, red, green and blue as mentioned earlier, in that order).
You can think of them as individual bytes, and you can set them as that too if you like (for example only extract the green channel from the source image). It is faster to read them as dwords though, and DBPro also uses such colour values initernally (for example ink and set object diffuse use such dword values for the colour; the rgb() function returns one as well).
Thus each separate colour channel can have 256 different values, but taken together you can have ~4.295 billion colour combinations (which isn't technically true as the alpha channel yields no visible colour change (it is usually used to store transparency or whatever else you wish in an image)).


"Why do programmers get Halloween and Christmas mixed up?"
Sph!nx
17
Years of Service
User Offline
Joined: 3rd Dec 2008
Location: The Netherlands
Posted: 21st Aug 2013 00:52
Ok, read this very carefully a few times and will do so a few more times.

I hope I'm on the right track... basically they are four sets of 1's and 0's, representing values to use. In case of images, the four sets represent alpha, red, green blue. Am I correct?

The permutation to get those values are set in the header of the memblock (width, height depth, in this case), am I right?

Regards Sph!nx
www.mental-image.net
Mage
Valued Member
19
Years of Service
User Offline
Joined: 3rd Feb 2007
Location:
Posted: 21st Aug 2013 05:40
A color is broken into several channels A R G B. Alpha, Red, Green, Blue. Channel is the term used for these 4 values that make up an actual color. Each channel is 8 bits. The channels are sandwiched together into a binary number 32bits long called a DWord. The DWord can then be written to memory.

Libervurto
20
Years of Service
User Offline
Joined: 30th Jun 2006
Location: On Toast
Posted: 21st Aug 2013 21:33 Edited at: 21st Aug 2013 21:34
I wrote some memblock bitmap functions a while ago that may help you:




The gluteus-maximus mammary-gland formally known as OBese87.
Rudolpho
20
Years of Service
User Offline
Joined: 28th Dec 2005
Location: Sweden
Posted: 22nd Aug 2013 01:00
Quote: "The permutation to get those values are set in the header of the memblock (width, height depth, in this case), am I right?"

Almost but not quite. Only the depth field in the header will affect how large the pixel channels are. You could set it to 16, but then it would get rather messy to read / set the pixel colours as you'd have to extract half-bytes for each colour. (I suppose 8- and 24-bit images work as well, not sure how though since there is no way to have a colour palette in a memblock as far as I know).


"Why do programmers get Halloween and Christmas mixed up?"
Sph!nx
17
Years of Service
User Offline
Joined: 3rd Dec 2008
Location: The Netherlands
Posted: 22nd Aug 2013 02:39 Edited at: 22nd Aug 2013 02:42
Thanks guys, you are great. This is something that's been puzzling me for quite a while and I believe it's beginning to sink in.

Ok, so depth is set in header and I'm guessing I have nothing to do with the actual permutations.

I can use it now, through the use of the supplied code here but just to get a correct picture. This is a right way of seeing it?
Quote: "I hope I'm on the right track... basically they are four sets of 1's and 0's, representing values to use. In case of images, the four sets represent alpha, red, green blue. Am I correct?"

These are added and read from a memblock trough the use of the Dword, correct?

Regards Sph!nx
www.mental-image.net
Libervurto
20
Years of Service
User Offline
Joined: 30th Jun 2006
Location: On Toast
Posted: 22nd Aug 2013 05:19 Edited at: 22nd Aug 2013 05:22
Helpful:



The gluteus-maximus mammary-gland formally known as OBese87.
Rudolpho
20
Years of Service
User Offline
Joined: 28th Dec 2005
Location: Sweden
Posted: 22nd Aug 2013 13:59 Edited at: 22nd Aug 2013 13:59
The only reason I said permutations was to explain how data is stored in bits making up bytes. I don't know for you, but that is more complicated to think about than it has to be if you ask me; 8 bits is a byte, which can hold 256 different values. That's a fact that you may just as well memorize.

There are indeed four sets of ones and zeroes, these are bytes. (Unless you want to consider other depths than 32-bit, but that is the standard for everything in DBPro unless you manage to run your application in 16-bit colour depth (my graphics card doesn't even seem to allow that)).
A byte can, as said, hold 256 unique values and therefore you can set your channels to any number between 0 and 255.
So a colour of [255, 255, 0, 0] would be 255 alpha, meaning it is completely opaque, 255 red meaning the highest amount of pure red and no green or blue. Thus your final colour is bright red. [128, 0, 100, 0] would be a semi-transparent (50% see-through) dark green (100 / 255, so ~39% of full, bright green) colour.
Libervurto's image is quite helpful to illustrate the contents of the header as well.

You could also read your colours like so, but it would be less efficient due to you having to do 4 times the amount of function calls:



"Why do programmers get Halloween and Christmas mixed up?"
Libervurto
20
Years of Service
User Offline
Joined: 30th Jun 2006
Location: On Toast
Posted: 22nd Aug 2013 22:36 Edited at: 22nd Aug 2013 22:38
I made an infographic, since I remember struggling to learn this stuff.





The gluteus-maximus mammary-gland formally known as OBese87.
Sph!nx
17
Years of Service
User Offline
Joined: 3rd Dec 2008
Location: The Netherlands
Posted: 23rd Aug 2013 00:31
Guys, your help is fantastic! Can't thank you enough. This is something I'm struggling with for a long time and I'm finally starting to understand it! I know I will need to dive into memory code more and will look at it from different angles but you guys helped a lot to get a basic understanding.

Libervurto:
Thanks mate, These images are exactly what I needed for a full picture! If you got more of these things....

Regards Sph!nx
www.mental-image.net

Login to post a reply

Server time is: 2026-07-07 05:39:36
Your offset time is: 2026-07-07 05:39:36