3

I wanted to use CreateBitmapFromMemory method, and its requires the stride as an input. and this stride confused me.

cbStride [in]

Type: UINT

The number of bytes between successive scanlines in pbBuffer.

and here it says: stride = image width + padding

  1. Why do we need these extra space(padding). why dont just image width.

This is how calculate the stride right?

    lWidthByte = (lWidth * bits + 7) / 8;

lWidth→pixel count

bits→bits per pixel

I suppuse deviding by 8 is for convert to byte. but,

  1. What is (+7) doing here?

and finally

    cbStride =((lWidthByte + 3) / 4) * 4;
  1. Whats going on here? (why not cbStride = lWidthByte)

Please help me to clear these.

Community
  • 1
  • 1
mhs
  • 1,012
  • 2
  • 14
  • 35

1 Answers1

10

The use of padding is due to various (old and current) memory layout optimizations.
Having image pixel-rows have a length (in bytes) that is an integral multiple of 4/8/16 bytes can significantly simplify and optimized many image based operations. The reason is that these sizes allow proper storing and parallel pixel processing in the CPU registers, e.g. with SSE/MMX, without mixing pixels from two consecutive rows.
Without padding, extra code has to be inserted to handle partial WORD/DWORD pixel data since two consecutive pixels in memory might refer to one pixel on the right of one row and the left pixel on the next row.

If your image is a single channel image with 8 bit depth, i.e. grayscale in the range [0,255], then the stride would be the image width rounded up to the nearest multiple of 4 or 8 bytes. Note that the stride always specified in bytes even when a pixel may have more than one byte depth.

For images with more channels and/or more than one byte per pixel/channel, the stride would be the image width in bytes rounded up to the nearest multiple of 4 or 8 bytes.

The +7 and similar arithmetic examples you gave just make sure that the numbers are correctly rounded since integer math truncates the non-integer component of the division.
Just insert some numbers and see how it works. Don't forget to truncate (floor()) the intermediate division results.

Adi Shavit
  • 16,743
  • 5
  • 67
  • 137
  • Thanks @Adi. I also tried without padding. (cbStride = lWidthByte x heght) program looks fine. If i calculate as 4 byte roundup boundary will speedup the application? – mhs Apr 30 '15 at 04:27
  • 1
    It might be slightly faster. However, speed is not really the major issue anymore. It really depends on the use of the image. If you are using it with APIs that require 4-byte image rows, then images without this might be corrupted or wrongly processed. – Adi Shavit Apr 30 '15 at 07:43
  • I used WIC and tried with both 4-byte image row and without padding. both seems ok (tested with 2 or 3 images). in that case, which is the best way to calculate and why? – mhs May 01 '15 at 01:14
  • Whether or not to actually use padding when allocating the bitmap really depends on the APIs that you plan to use the bitmap with. Many APIs do not have a problem working with no padding so you should not see any problem either way. Your question only asked what padding was and how to calculate it. – Adi Shavit May 01 '15 at 08:46
  • 1
    Having stride separate from width also lets you use subsets of a large image without copying. stride=storage layout, width = number of columns to actually look at. – Peter Cordes Oct 11 '17 at 04:54