Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question on Interleaved Bitmap / BytesPerRow wrong ? #252

Open
youenchene opened this issue Mar 1, 2025 · 3 comments
Open

Question on Interleaved Bitmap / BytesPerRow wrong ? #252

youenchene opened this issue Mar 1, 2025 · 3 comments

Comments

@youenchene
Copy link
Contributor

In bitmap.c :

if(ubFlags & BMF_INTERLEAVED) {
		pBitMap->Flags |= BMF_INTERLEAVED;
		UWORD uwRealWidth;
		uwRealWidth = pBitMap->BytesPerRow;
		pBitMap->BytesPerRow *= ubDepth;

		pBitMap->Planes[0] = (PLANEPTR) memAlloc(
			pBitMap->BytesPerRow*uwHeight,
			(ubFlags & BMF_FASTMEM) ? MEMF_ANY : MEMF_CHIP
		);
		if(!pBitMap->Planes[0]) {
			logWrite("ERR: Can't alloc interleaved bitplanes\n");
			goto fail;
		}
		for(i = 1; i != ubDepth; ++i) {
			pBitMap->Planes[i] = pBitMap->Planes[i-1] + uwRealWidth;
		}

		if (ubFlags & BMF_CLEAR) {
			memset(pBitMap->Planes[0], 0, pBitMap->Rows * pBitMap->BytesPerRow);
		}
	}

This line pBitMap->BytesPerRow *= ubDepth; bother me.

What I understood from interleaved bitmap is 1 bit is color and each bitmap is layer.

So a 32 width pixel image should be 4 bytes (so 32 bits) for one row.

And this on 4 bitplane for a 16 colors images.

According to this code the BytesPerRow become 16, so 16 bytes by row.

Did I completely losted my mind and misunderstanding interleaved or did I put my finger on a mistake in the code ?

(under the hood : I am trying to do a xflip method which drive me crazy)

@tehKaiN
Copy link
Member

tehKaiN commented Mar 1, 2025

This mimics how Amiga OS stores its bitmaps. It's a bit hacky but explainable, and indeed misses some comments in the code.

This comes from assumption that some parts of the code might calculate amount of data in the bitmap rectangle by doing BytesPerRow * Rows. Having BytesPerRow pre-multiplied by depth allows some code paths to work either for non-interleaved and interleaved bitmaps, e.g. in blit.c:

ULONG ulSrcOffs = pSrc->BytesPerRow * wSrcY + (wSrcX / 8);
ULONG ulDstOffs = pDst->BytesPerRow * wDstY + (wDstX / 8);

the other explanation is that otherwise you'd have to do BytesPerRow * Rows * Depth, and this gives you 2 multiplications, which are quite slow on an A500, so that gives you a nice speed boost here and there.

Even if you don't have further questions about it, let's keep the issue open so that it can be closed when a PR with some in-code/docs explanation lands.

To get the proper BytesPerRow you might want to use bitmapGetByteWidth().

When we get #9, premultiplied value could be stored separately and that could eliminate the need for bitmapGetByteWidth().

@youenchene
Copy link
Contributor Author

Ok I get it.

'pBitMap->Planes[0] = (PLANEPTR) memAlloc(
pBitMap->BytesPerRow*uwHeight,
(ubFlags & BMF_FASTMEM) ? MEMF_ANY : MEMF_CHIP
);´

Is doing the memalloc for all the bitplanes.

@tehKaiN
Copy link
Member

tehKaiN commented Mar 1, 2025

Exactly ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants