Чтение C++ кода функции CreateFrame (с точки зрения C#)

// Create test video frame
void CreateFrame(char * buffer, int w, int h, int bytespan)
{
  int wxh = w * h;
  static float seed = 1.0;
  for (int i = 0; i < h; i ++)
  {
    char* line = buffer + i * bytespan;
    for (int j = 0; j < w; j ++)
    {
      // RGB
      line[0] = 255 * sin(((float)i / wxh * seed) * 3.14);
      line[1] = 255 * cos(((float)j / wxh * seed) * 3.14);
      line[2] = 255 * sin(((float)(i + j) / wxh * seed) * 3.14);
      line += 3;
    }
  }
  seed = seed + 2.2;
}

Может ли кто-нибудь, пожалуйста, высокий мне line += 3; за?

а как создать такой аналог функции в C#?

5 ответов

Решение

В C/C++ значение line в строке на самом деле адрес памяти массива, и line[1] фактически представляет значение по адресу переменной line плюс 1 пункт смещения. (Если тип предметов в line является intто это значит адрес line плюс четыре байта; так как это char, это означает адрес line плюс один байт.)

Так, line += 3 Значит это line[1] теперь эквивалентно [old "line" value][4], Кодировщик мог написать код следующим образом:

for (int j = 0; j < w; j ++)
{
  // RGB
  line[(3 * j)] = 255 * sin(((float)i / wxh * seed) * 3.14);
  line[(3 * j) + 1] = 255 * cos(((float)j / wxh * seed) * 3.14);
  line[(3 * j) + 2] = 255 * sin(((float)(i + j) / wxh * seed) * 3.14);
}

line += 3 увеличивает указатель line на 3 байта, так что он указывает на следующий пиксель. line здесь указатель на 3-байтовый пиксель, поэтому его действительно следует называть чем-то другим, например pPixel,

Линия - указатель на позицию в буфере. Увеличение строки ускоряет обработку вниз по буферу.

Аналог A C# может быть:

static float seed = 1.0f;
static void CreateFrame(byte[] buffer, int w, int h, int bytespan)
{
  int wxh = w * h;
  for (int i = 0; i < h; i ++)
  {
    int line = i * bytespan;
    for (int j = 0; j < w; j ++)
    {
      // RGB
      buffer[line + 0] = (byte)(255 * Math.Sin(((float)i / wxh * seed) * 3.14));
      buffer[line + 1] = (byte)(255 * Math.Cos(((float)j / wxh * seed) * 3.14));
      buffer[line + 2] = (byte)(255 * Math.Sin(((float)(i + j) / wxh * seed) * 3.14));
      line += 3;
    }
  }
  seed = seed + 2.2f;
}

Это указатель арифметики. Поскольку вы имеете дело с 3 элементами массива за один раз, вам нужно будет соответствующим образом обновить указатель, иначе вы будете читать одно и то же местоположение дважды и, конечно, ошибочно.

Вы должны заменить указатель байтовым массивом и индексировать его целым числом следующим образом:

// Create test video frame
void CreateFrame(byte[] buffer, int w, int h, int bytespan)
{
  int wxh = w * h;
  static float seed = 1.0;
  for (int i = 0; i < h; i ++)
  {
    int line = i * bytespan;
    for (int j = 0; j < w; j ++)
    {
      // RGB
      buffer[line + 0] = 255 * sin(((float)i / wxh * seed) * 3.14);
      buffer[line + 1] = 255 * cos(((float)j / wxh * seed) * 3.14);
      buffer[line + 2] = 255 * sin(((float)(i + j) / wxh * seed) * 3.14);
      line += 3;
    }
  }
  seed = seed + 2.2;
}

Я просто оставил имя переменной как line, даже если из того, что я понимаю, это не совсем линия.

Другие вопросы по тегам