News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Code to align to 32 bits

Started by NoCforMe, November 09, 2024, 06:53:17 PM

Previous topic - Next topic

jj2007

Quote from: NoCforMe on November 09, 2024, 06:53:17 PMI came up with the following code:
Code Select Expand
      MOV    EAX, <line length>
      NEG    EAX                       ;Flip bits arithmetically
      AND    EAX, 11B                  ;Isolate 2 low bits
      MOV    padding, EAX              ;and Bob's your uncle
Does the 11B actually assemble without the "h"?

sinsi

🍺🍺🍺

NoCforMe

That code works like a charm for aligning both 256-color BMP data (1 byte/pixel) and 16-color data (2 pixels/byte), but it doesn't work at all on 2-color data, with 8 pixels/byte. Here's the scheme for determining padding in that case:

# bits AND 1111B    padding
-----------------------------
      1 - 8           3
      8 - 16          2
     17 - 24          1
     25 - 32          0
(the last case includes # bits AND 11111B = 0)

So I ended up getting the padding by brute force:

; Get padding for 2 colors:
MOV EAX, BMPwidth ;Width in pixels
AND EAX, 11111B
JZ pad0 ;If 0, no padding needed.
CMP EAX, 8
JBE pad3
CMP EAX, 16
JBE pad2
CMP EAX, 24
JBE pad1
pad0: XOR EAX, EAX
JMP SHORT setpad
pad1: MOV EAX, 1
JMP SHORT setpad
pad2: MOV EAX, 2
JMP SHORT setpad
pad3: MOV EAX, 3

setpad: MOV Padding, EAX

Not very elegant but it works.

Can anyone think of a wickedly clever scheme that does this computationally, without conditional tests? I couldn't come up with anything. Guess I'm just not that clever.
Assembly language programming should be fun. That's why I do it.

TimoVJL

#18
DELETED as had a bug for OP's example
May the source be with you

NoCforMe

Timo, do you even bother reading articles before posting links to them?
That article had nothing--nothing at all--that addressed, let alone answered, my question. It was a complete waste of time, both on my part and on yours.

Sheesh. I'm starting to lose confidence in other humans having enough common sense to know when to post something they think is "helpful" and when to simply STFU.
Assembly language programming should be fun. That's why I do it.

_japheth

Quote from: NoCforMe on November 13, 2024, 01:07:02 PMTimo, do you even bother reading articles before posting links to them?
That article had nothing--nothing at all--that addressed, let alone answered, my question. It was a complete waste of time, both on my part and on yours.

Hmmmm - the article at least clears the terminology (answer 1): the number of bytes between 2 rows of a .bmp file, called the stride and, OTOH, the number of bits per pixel . If I understand correctly, it's only the stride that needs alignment ( to a dword, meaning that the address of the first pixel of a row must have its lowest 2 bits cleared ). The bits per pixel value shouldn't matter at all.
Dummheit, gepaart mit Dreistigkeit - eine furchtbare Macht.

NoCforMe

I understand the layout of BMP bitmap data very well; that's not the issue. The article didn't tell me anything I didn't already know.

Yes, the "stride" is the important thing here. And it is totally dependent on bits per pixel.

Let's take a 24- or 32-BPP bitmap: there's no alignment adjustment needed here, because each pixel falls on a 32-bit boundary.

With lower BPP bitmaps, alignment becomes an issue: the next step down from 24 BPP is 8 BPP, a 256-color bitmap with a palette. Here the pixels are bytes, so obviously we might need to do some adjustment to land on a DWORD boundary. Same with 4 BPP, a 16-color bitmap (2 pixels per byte).

My question, if anyone remembers it, has to do with the lowest form of BMP, 1 BPP, AKA black and white. Here each bit is a pixel. So obviously alignment is an issue. Let's say your bitmap is 12 pixels wide (a bit small, but whatever): that means we need to pad each row with 2 bytes (12 bits fits in a 16-bit word). The stride then becomes 4 (the shortest actual row for a 1 BPP bitmap). The stride is simply the actual length of a row of pixels, including padding: it's what you have to add to the address of a row to get to the next row.

I gave my method how to figure the padding (and from that the stride) for a 1 BPP bitmap. What I was asking for was a more elegant solution, not a primer in BMP structure.
Assembly language programming should be fun. That's why I do it.

sinsi

Quote from: NoCforMe on November 13, 2024, 05:23:48 PMLet's take a 24- or 32-BPP bitmap: there's no alignment adjustment needed here, because each pixel falls on a 32-bit boundary.
No, a 24-bit pixel is 3 bytes but in a BMP tle line is aligned to 32-bits.

You need to calculate how many bits are in one line and align the end to the next DWORD.
🍺🍺🍺


NoCforMe

Quote from: sinsi on November 13, 2024, 05:43:39 PM
Quote from: NoCforMe on November 13, 2024, 05:23:48 PMLet's take a 24- or 32-BPP bitmap: there's no alignment adjustment needed here, because each pixel falls on a 32-bit boundary.
No, a 24-bit pixel is 3 bytes but in a BMP tle line is aligned to 32-bits.

You need to calculate how many bits are in one line and align the end to the next DWORD.

Sorry, right: 24 BPP would require padding under some circumstances.

There's also a 16 BPP format that I've never seen nor dealt with. That would be, what? 65K colors. Non-indexed (no palette). I think. Never dealt with that format either.
Assembly language programming should be fun. That's why I do it.

_japheth

Quote from: NoCforMe on November 13, 2024, 05:23:48 PMI gave my method how to figure the padding (and from that the stride) for a 1 BPP bitmap. What I was asking for was a more elegant solution, not a primer in BMP structure.

According to MS in https://learn.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-bitmapinfoheader the formula is:

stride = ((((biWidth * biBitCount) + 31) & ~31) >> 3);
biSizeImage = abs(biHeight) * stride;
Dummheit, gepaart mit Dreistigkeit - eine furchtbare Macht.

NoCforMe

I guess that's the universal formula (works for all BPPs). Maybe I should just use that ...

Still need to calculate padding for my app, but that's easily done.
Assembly language programming should be fun. That's why I do it.