Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Optimization of unsafe code

Optimization of unsafe code

Scheduled Pinned Locked Moved C#
graphicsalgorithmsperformancequestion
4 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • R Offline
    R Offline
    Robert Rohde
    wrote on last edited by
    #1

    Hi, I have the following code in an unsafe section of code:

    //...
    int scan0 = data.Scan0.ToInt32();

    byte * colPixel;
    byte * rowPixel;

    byte innerColorB = innerColor.B;
    byte innerColorG = innerColor.G;
    byte innerColorR = innerColor.R;
    byte innerColorA = innerColor.A;

    int stride = data.Stride;

    for (int y = 0; y < height; y ++)
    {
    rowPixel = (byte *)(scan0 + y * stride);
    for (int x = 0; x < width; x++)
    {
    colPixel = rowPixel + 4 * x;
    *colPixel = innerColorB;
    *(colPixel + 1) = innerColorG;
    *(colPixel + 2) = innerColorR;
    *(colPixel + 3) = innerColorA;
    }
    }
    //...

    I'm basically setting all pixels of a bitmap to a specified color. I know I could use the FillRectangle function but I don't want to :). My question is if anyone here might have an idea how this could be performed better/faster.

    C 1 Reply Last reply
    0
    • R Robert Rohde

      Hi, I have the following code in an unsafe section of code:

      //...
      int scan0 = data.Scan0.ToInt32();

      byte * colPixel;
      byte * rowPixel;

      byte innerColorB = innerColor.B;
      byte innerColorG = innerColor.G;
      byte innerColorR = innerColor.R;
      byte innerColorA = innerColor.A;

      int stride = data.Stride;

      for (int y = 0; y < height; y ++)
      {
      rowPixel = (byte *)(scan0 + y * stride);
      for (int x = 0; x < width; x++)
      {
      colPixel = rowPixel + 4 * x;
      *colPixel = innerColorB;
      *(colPixel + 1) = innerColorG;
      *(colPixel + 2) = innerColorR;
      *(colPixel + 3) = innerColorA;
      }
      }
      //...

      I'm basically setting all pixels of a bitmap to a specified color. I know I could use the FillRectangle function but I don't want to :). My question is if anyone here might have an idea how this could be performed better/faster.

      C Offline
      C Offline
      Christian Graus
      wrote on last edited by
      #2

      Robert Rohde wrote:

      int scan0 = data.Scan0.ToInt32();

      I don't lint the look of this. I always turn it into a byte * from the get go. I'm not sure if C# will magically deal with 64 bit, where this code would be wrong. I think the way I do it is faster, which is to create a byte * out of scan0, then keep adding to it as I go, instead of calculating the position every time. You should read my image processing articles on this site, they all do it the same way. Christian Graus - Microsoft MVP - C++

      R 1 Reply Last reply
      0
      • C Christian Graus

        Robert Rohde wrote:

        int scan0 = data.Scan0.ToInt32();

        I don't lint the look of this. I always turn it into a byte * from the get go. I'm not sure if C# will magically deal with 64 bit, where this code would be wrong. I think the way I do it is faster, which is to create a byte * out of scan0, then keep adding to it as I go, instead of calculating the position every time. You should read my image processing articles on this site, they all do it the same way. Christian Graus - Microsoft MVP - C++

        R Offline
        R Offline
        Robert Rohde
        wrote on last edited by
        #3

        Thanks for your help. Now it performes a bit better (although not really significant):

        byte * p = (byte *)(void *)data.Scan0;
        int nOffset = data.Stride - bitmap.Width * 4;
        for (int y = 0; y < height; ++y)
        {
        for (int x = 0; x < width; ++x)
        {
        p[0] = innerColorB;
        p[1] = innerColorG;
        p[2] = innerColorR;
        p[3] = innerColorA;
        p += 4;
        }
        p += nOffset;
        }

        Isn't there a way to set a bunch of bytes in one step instead of having to move through each pixel? As I said the whole bitmap should be filled with one color. Is there a way to prepare a byte array or something containing all bytes for one row and than just copying it y times?

        C 1 Reply Last reply
        0
        • R Robert Rohde

          Thanks for your help. Now it performes a bit better (although not really significant):

          byte * p = (byte *)(void *)data.Scan0;
          int nOffset = data.Stride - bitmap.Width * 4;
          for (int y = 0; y < height; ++y)
          {
          for (int x = 0; x < width; ++x)
          {
          p[0] = innerColorB;
          p[1] = innerColorG;
          p[2] = innerColorR;
          p[3] = innerColorA;
          p += 4;
          }
          p += nOffset;
          }

          Isn't there a way to set a bunch of bytes in one step instead of having to move through each pixel? As I said the whole bitmap should be filled with one color. Is there a way to prepare a byte array or something containing all bytes for one row and than just copying it y times?

          C Offline
          C Offline
          Christian Graus
          wrote on last edited by
          #4

          I've not found a memcpy type function or a memset, for that matter, in the framework. However, given that the color does not change, you could turn the RGBA values into an int, and then set it in one step for each pixel. nOffset will also be a multiple of 4, so you could set the pointer to be an int * all the way through, instead of having to cast it, just make sure you divide nOffset by 4 to match. Christian Graus - Microsoft MVP - C++

          1 Reply Last reply
          0
          Reply
          • Reply as topic
          Log in to reply
          • Oldest to Newest
          • Newest to Oldest
          • Most Votes


          • Login

          • Don't have an account? Register

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • World
          • Users
          • Groups